From e7cd7c8dc30aaa87cf4a411cf1849c6424c1b2b2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 7 Mar 2021 01:35:55 +0100 Subject: [PATCH 001/230] MSVC FSFW almost compiling --- container/FixedArrayList.h | 4 +++- datapool/PoolEntry.cpp | 2 +- datapoollocal/LocalPoolDataSetBase.cpp | 10 ++++++---- osal/host/SemaphoreFactory.cpp | 4 +--- osal/windows/TcWinUdpPollingTask.cpp | 4 ++++ osal/windows/TcWinUdpPollingTask.h | 2 +- osal/windows/TmTcWinUdpBridge.cpp | 8 +++++++- power/PowerComponent.cpp | 21 +++++++++++---------- power/PowerComponent.h | 6 +++--- storagemanager/LocalPool.h | 1 + 10 files changed, 38 insertions(+), 24 deletions(-) diff --git a/container/FixedArrayList.h b/container/FixedArrayList.h index 89b76388..7af636b6 100644 --- a/container/FixedArrayList.h +++ b/container/FixedArrayList.h @@ -8,7 +8,9 @@ */ template class FixedArrayList: public ArrayList { - static_assert(MAX_SIZE <= (pow(2,sizeof(count_t)*8)-1), "count_t is not large enough to hold MAX_SIZE"); +#if !defined(_MSC_VER) + static_assert(MAX_SIZE <= (std::pow(2,sizeof(count_t)*8)-1), "count_t is not large enough to hold MAX_SIZE"); +#endif private: T data[MAX_SIZE]; public: diff --git a/datapool/PoolEntry.cpp b/datapool/PoolEntry.cpp index a5867222..6504e20c 100644 --- a/datapool/PoolEntry.cpp +++ b/datapool/PoolEntry.cpp @@ -7,7 +7,7 @@ template PoolEntry::PoolEntry(std::initializer_list initValue, bool setValid ): - length(initValue.size()), valid(setValid) { + length(static_cast(initValue.size())), valid(setValid) { this->address = new T[this->length]; if(initValue.size() == 0) { std::memset(this->address, 0, this->getByteSize()); diff --git a/datapoollocal/LocalPoolDataSetBase.cpp b/datapoollocal/LocalPoolDataSetBase.cpp index e5ea1598..2d70712b 100644 --- a/datapoollocal/LocalPoolDataSetBase.cpp +++ b/datapoollocal/LocalPoolDataSetBase.cpp @@ -95,14 +95,16 @@ ReturnValue_t LocalPoolDataSetBase::serializeWithValidityBuffer(uint8_t **buffer size_t *size, size_t maxSize, SerializeIF::Endianness streamEndianness) const { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - uint8_t validityMaskSize = std::ceil(static_cast(fillCount)/8.0); - uint8_t validityMask[validityMaskSize] = {}; + const uint8_t validityMaskSize = std::ceil(static_cast(fillCount)/8.0); + /* Use a std::vector here because MSVC will (rightly) not create a fixed size array + with a non constant size specifier */ + std::vector validityMask(validityMaskSize); uint8_t validBufferIndex = 0; uint8_t validBufferIndexBit = 0; for (uint16_t count = 0; count < fillCount; count++) { if(registeredVariables[count]->isValid()) { /* Set bit at correct position */ - bitutil::bitSet(validityMask + validBufferIndex, validBufferIndexBit); + bitutil::bitSet(validityMask.data() + validBufferIndex, validBufferIndexBit); } if(validBufferIndexBit == 7) { validBufferIndex ++; @@ -123,7 +125,7 @@ ReturnValue_t LocalPoolDataSetBase::serializeWithValidityBuffer(uint8_t **buffer return SerializeIF::BUFFER_TOO_SHORT; } // copy validity buffer to end - std::memcpy(*buffer, validityMask, validityMaskSize); + std::memcpy(*buffer, validityMask.data(), validityMaskSize); *size += validityMaskSize; return result; } diff --git a/osal/host/SemaphoreFactory.cpp b/osal/host/SemaphoreFactory.cpp index 3d3fe17f..530b3e45 100644 --- a/osal/host/SemaphoreFactory.cpp +++ b/osal/host/SemaphoreFactory.cpp @@ -1,7 +1,5 @@ #include "../../tasks/SemaphoreFactory.h" -#include "../../osal/linux/BinarySemaphore.h" -#include "../../osal/linux/CountingSemaphore.h" -#include "../../serviceinterface/ServiceInterfaceStream.h" +#include "../../serviceinterface/ServiceInterface.h" SemaphoreFactory* SemaphoreFactory::factoryInstance = nullptr; diff --git a/osal/windows/TcWinUdpPollingTask.cpp b/osal/windows/TcWinUdpPollingTask.cpp index 4fd88c93..f9b3753e 100644 --- a/osal/windows/TcWinUdpPollingTask.cpp +++ b/osal/windows/TcWinUdpPollingTask.cpp @@ -4,6 +4,10 @@ #include #include +#if defined(_MSC_VER) +#include +typedef SSIZE_T ssize_t; +#endif TcWinUdpPollingTask::TcWinUdpPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge, size_t frameSize, diff --git a/osal/windows/TcWinUdpPollingTask.h b/osal/windows/TcWinUdpPollingTask.h index 50d39d25..063a783e 100644 --- a/osal/windows/TcWinUdpPollingTask.h +++ b/osal/windows/TcWinUdpPollingTask.h @@ -23,7 +23,7 @@ class TcWinUdpPollingTask: public SystemObject, 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}; + static constexpr timeval DEFAULT_TIMEOUT = {0, 500}; TcWinUdpPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge, size_t frameSize = 0, double timeoutSeconds = -1); diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index 69a48f3e..ac890198 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -1,6 +1,12 @@ -#include #include "TmTcWinUdpBridge.h" +#include + +#if defined(_MSC_VER) +#include +typedef SSIZE_T ssize_t; +#endif + TmTcWinUdpBridge::TmTcWinUdpBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId, object_id_t tcStoreId, uint16_t serverPort, uint16_t clientPort): diff --git a/power/PowerComponent.cpp b/power/PowerComponent.cpp index 04f8658e..778d2b71 100644 --- a/power/PowerComponent.cpp +++ b/power/PowerComponent.cpp @@ -1,6 +1,7 @@ #include "PowerComponent.h" #include "../serialize/SerializeAdapter.h" + PowerComponent::PowerComponent(): switchId1(0xFF), switchId2(0xFF), doIHaveTwoSwitches(false) { } @@ -8,23 +9,23 @@ PowerComponent::PowerComponent(): switchId1(0xFF), switchId2(0xFF), PowerComponent::PowerComponent(object_id_t setId, uint8_t moduleId, float min, float max, uint8_t switchId1, bool twoSwitches, uint8_t switchId2) : deviceObjectId(setId), switchId1(switchId1), switchId2(switchId2), - doIHaveTwoSwitches(twoSwitches), min(min), max(max), + doIHaveTwoSwitches(twoSwitches), minVoltage(min), maxVoltage(max), moduleId(moduleId) { } ReturnValue_t PowerComponent::serialize(uint8_t** buffer, size_t* size, size_t maxSize, Endianness streamEndianness) const { - ReturnValue_t result = SerializeAdapter::serialize(&min, buffer, + ReturnValue_t result = SerializeAdapter::serialize(&minVoltage, buffer, size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return SerializeAdapter::serialize(&max, buffer, size, maxSize, + return SerializeAdapter::serialize(&maxVoltage, buffer, size, maxSize, streamEndianness); } size_t PowerComponent::getSerializedSize() const { - return sizeof(min) + sizeof(max); + return sizeof(minVoltage) + sizeof(maxVoltage); } object_id_t PowerComponent::getDeviceObjectId() { @@ -44,21 +45,21 @@ bool PowerComponent::hasTwoSwitches() { } float PowerComponent::getMin() { - return min; + return minVoltage; } float PowerComponent::getMax() { - return max; + return maxVoltage; } ReturnValue_t PowerComponent::deSerialize(const uint8_t** buffer, size_t* size, Endianness streamEndianness) { - ReturnValue_t result = SerializeAdapter::deSerialize(&min, buffer, + ReturnValue_t result = SerializeAdapter::deSerialize(&minVoltage, buffer, size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return SerializeAdapter::deSerialize(&max, buffer, size, streamEndianness); + return SerializeAdapter::deSerialize(&maxVoltage, buffer, size, streamEndianness); } ReturnValue_t PowerComponent::getParameter(uint8_t domainId, uint8_t uniqueId, @@ -69,10 +70,10 @@ ReturnValue_t PowerComponent::getParameter(uint8_t domainId, uint8_t uniqueId, } switch (uniqueId) { case 0: - parameterWrapper->set<>(min); + parameterWrapper->set<>(minVoltage); break; case 1: - parameterWrapper->set<>(max); + parameterWrapper->set<>(maxVoltage); break; default: return INVALID_IDENTIFIER_ID; diff --git a/power/PowerComponent.h b/power/PowerComponent.h index 659b6853..68b07c32 100644 --- a/power/PowerComponent.h +++ b/power/PowerComponent.h @@ -9,7 +9,7 @@ class PowerComponent: public PowerComponentIF { public: - PowerComponent(object_id_t setId, uint8_t moduleId, float min, float max, + PowerComponent(object_id_t setId, uint8_t moduleId, float minVoltage, float maxVoltage, uint8_t switchId1, bool twoSwitches = false, uint8_t switchId2 = 0xFF); @@ -41,8 +41,8 @@ private: const bool doIHaveTwoSwitches; - float min = 0.0; - float max = 0.0; + float minVoltage = 0.0; + float maxVoltage = 0.0; uint8_t moduleId = 0; diff --git a/storagemanager/LocalPool.h b/storagemanager/LocalPool.h index 6a666485..55d49254 100644 --- a/storagemanager/LocalPool.h +++ b/storagemanager/LocalPool.h @@ -169,6 +169,7 @@ private: * Indicates that this element is free. * This value limits the maximum size of a pool. * Change to larger data type if increase is required. + * Brackets required for MSVC (nameclashes with min and max) */ static const size_type STORAGE_FREE = std::numeric_limits::max(); /** From 331bbd14e7cb842e3113ca55ef25a91f6f5f587c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 8 Mar 2021 12:57:21 +0100 Subject: [PATCH 002/230] implemented explicit virt abstract propagation --- controller/ExtendedControllerBase.cpp | 16 ---------------- controller/ExtendedControllerBase.h | 8 ++++---- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/controller/ExtendedControllerBase.cpp b/controller/ExtendedControllerBase.cpp index 95ba012e..b5b8c660 100644 --- a/controller/ExtendedControllerBase.cpp +++ b/controller/ExtendedControllerBase.cpp @@ -17,14 +17,6 @@ ReturnValue_t ExtendedControllerBase::executeAction(ActionId_t actionId, return HasReturnvaluesIF::RETURN_OK; } - - -ReturnValue_t ExtendedControllerBase::initializeLocalDataPool( - localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) { - /* Needs to be overriden and implemented by child class. */ - return HasReturnvaluesIF::RETURN_OK; -} - object_id_t ExtendedControllerBase::getObjectId() const { return SystemObject::getObjectId(); } @@ -107,14 +99,6 @@ MessageQueueId_t ExtendedControllerBase::getCommandQueue() const { return commandQueue->getId(); } -LocalPoolDataSetBase* ExtendedControllerBase::getDataSetHandle(sid_t sid) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "ExtendedControllerBase::getDataSetHandle: No child " - << " implementation provided, returning nullptr!" << std::endl; -#endif - return nullptr; -} - LocalDataPoolManager* ExtendedControllerBase::getHkManagerHandle() { return &poolManager; } diff --git a/controller/ExtendedControllerBase.h b/controller/ExtendedControllerBase.h index f069819b..d5d43933 100644 --- a/controller/ExtendedControllerBase.h +++ b/controller/ExtendedControllerBase.h @@ -61,11 +61,11 @@ protected: /* HasLocalDatapoolIF overrides */ virtual LocalDataPoolManager* getHkManagerHandle() override; virtual object_id_t getObjectId() const override; - virtual ReturnValue_t initializeLocalDataPool( - localpool::DataPool& localDataPoolMap, - LocalDataPoolManager& poolManager) override; virtual uint32_t getPeriodicOperationFrequency() const override; - virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; + + virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, + LocalDataPoolManager& poolManager) override = 0; + virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override = 0; }; From 1966b336134b877e93ea6885478607bc3791b0ee Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 8 Mar 2021 14:08:31 +0100 Subject: [PATCH 003/230] typo --- pus/Service3Housekeeping.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pus/Service3Housekeeping.cpp b/pus/Service3Housekeeping.cpp index 5456764d..c4f80c2a 100644 --- a/pus/Service3Housekeeping.cpp +++ b/pus/Service3Housekeeping.cpp @@ -159,7 +159,7 @@ ReturnValue_t Service3Housekeeping::prepareCollectionIntervalModificationCommand CommandMessage *command, object_id_t objectId, bool isDiagnostics, const uint8_t *tcData, size_t tcDataLen) { if(tcDataLen < sizeof(sid_t) + sizeof(float)) { - // SID plus the size of the new collection intervL. + /* SID plus the size of the new collection interval. */ return CommandingServiceBase::INVALID_TC; } From bdd66072d120354ffe6f7cf8280d76eb3e36078d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 8 Mar 2021 14:21:20 +0100 Subject: [PATCH 004/230] removed obsolete comment --- storagemanager/LocalPool.h | 1 - 1 file changed, 1 deletion(-) diff --git a/storagemanager/LocalPool.h b/storagemanager/LocalPool.h index 55d49254..6a666485 100644 --- a/storagemanager/LocalPool.h +++ b/storagemanager/LocalPool.h @@ -169,7 +169,6 @@ private: * Indicates that this element is free. * This value limits the maximum size of a pool. * Change to larger data type if increase is required. - * Brackets required for MSVC (nameclashes with min and max) */ static const size_type STORAGE_FREE = std::numeric_limits::max(); /** From e67ff6a937c155659ee49118bf80ad238093cc3b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 8 Mar 2021 23:00:53 +0100 Subject: [PATCH 005/230] cleaner wiretapping handling --- osal/windows/CMakeLists.txt | 15 +++++---- osal/windows/TcWinTcpServer.cpp | 46 ++++++++++++++++++++++++++++ osal/windows/TcWinTcpServer.h | 30 ++++++++++++++++++ osal/windows/TcWinUdpPollingTask.cpp | 33 ++++++++++---------- osal/windows/TcWinUdpPollingTask.h | 6 ++-- osal/windows/TmTcWinUdpBridge.cpp | 40 ++++++++++++------------ osal/windows/TmTcWinUdpBridge.h | 5 ++- 7 files changed, 127 insertions(+), 48 deletions(-) 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 b6e76d6a..889ea339 100644 --- a/osal/windows/CMakeLists.txt +++ b/osal/windows/CMakeLists.txt @@ -1,11 +1,10 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - TcWinUdpPollingTask.cpp - TmTcWinUdpBridge.cpp +target_sources(${LIB_FSFW_NAME} PRIVATE + TcWinUdpPollingTask.cpp + TmTcWinUdpBridge.cpp + TcWinTcpServer.cpp ) -target_link_libraries(${LIB_FSFW_NAME} - PRIVATE - wsock32 - ws2_32 +target_link_libraries(${LIB_FSFW_NAME} PRIVATE + wsock32 + ws2_32 ) \ No newline at end of file diff --git a/osal/windows/TcWinTcpServer.cpp b/osal/windows/TcWinTcpServer.cpp new file mode 100644 index 00000000..aebc0bee --- /dev/null +++ b/osal/windows/TcWinTcpServer.cpp @@ -0,0 +1,46 @@ +#include "TcWinTcpServer.h" +#include "../../serviceinterface/ServiceInterface.h" +#include + +TcWinTcpServer::TcWinTcpServer(object_id_t objectId, object_id_t tmtcUnixUdpBridge): + SystemObject(objectId) { + /* Open TCP socket */ + serverTcpSocket = socket(AF_INET, SOCK_STREAM, 0); + if(serverTcpSocket == 0) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "TcWinTcpServer::TcWinTcpServer: Socket creation failed!" << std::endl; + handleSocketError(); +#endif + } + + setsockopt(serverTcpSocket, SOL_SOCKET, SO_REUSEADDR | SO_BROADCAST, + &tcpSockOpt, sizeof(tcpSockOpt)); +} + +TcWinTcpServer::~TcWinTcpServer() { +} + +void TcWinTcpServer::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; + } + } +} + + diff --git a/osal/windows/TcWinTcpServer.h b/osal/windows/TcWinTcpServer.h new file mode 100644 index 00000000..3a17336a --- /dev/null +++ b/osal/windows/TcWinTcpServer.h @@ -0,0 +1,30 @@ +#ifndef FSFW_OSAL_WINDOWS_TCWINTCPSERVER_H_ +#define FSFW_OSAL_WINDOWS_TCWINTCPSERVER_H_ + +#include "../../objectmanager/SystemObject.h" +#include "../../tasks/ExecutableObjectIF.h" + +#include + +class TcWinTcpServer: + public SystemObject, + public ExecutableObjectIF { +public: + /* The ports chosen here should not be used by any other process. */ + static constexpr uint16_t DEFAULT_TCP_SERVER_PORT = 7301; + static constexpr uint16_t DEFAULT_TCP_CLIENT_PORT = 7302; + + TcWinTcpServer(object_id_t objectId, object_id_t tmtcUnixUdpBridge); + virtual~ TcWinTcpServer(); + +private: + + SOCKET serverTcpSocket = 0; + + std::vector receptionBuffer; + int tcpSockOpt = 0; + + void handleSocketError(); +}; + +#endif /* FSFW_OSAL_WINDOWS_TCWINTCPSERVER_H_ */ diff --git a/osal/windows/TcWinUdpPollingTask.cpp b/osal/windows/TcWinUdpPollingTask.cpp index f9b3753e..32c21700 100644 --- a/osal/windows/TcWinUdpPollingTask.cpp +++ b/osal/windows/TcWinUdpPollingTask.cpp @@ -20,8 +20,8 @@ TcWinUdpPollingTask::TcWinUdpPollingTask(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); @@ -36,7 +36,7 @@ TcWinUdpPollingTask::TcWinUdpPollingTask(object_id_t objectId, TcWinUdpPollingTask::~TcWinUdpPollingTask() {} ReturnValue_t TcWinUdpPollingTask::performOperation(uint8_t opCode) { - // Poll for new UDP datagrams in permanent loop. + /* Poll for new UDP datagrams in permanent loop. */ while(true) { //! Sender Address is cached here. struct sockaddr_in senderAddress; @@ -46,7 +46,7 @@ ReturnValue_t TcWinUdpPollingTask::performOperation(uint8_t opCode) { receptionFlags, reinterpret_cast(&senderAddress), &senderAddressSize); if(bytesReceived == SOCKET_ERROR) { - // handle error + /* Handle error */ #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "TcWinUdpPollingTask::performOperation: Reception" " error." << std::endl; @@ -54,9 +54,9 @@ ReturnValue_t TcWinUdpPollingTask::performOperation(uint8_t opCode) { handleReadError(); continue; } -#if FSFW_CPP_OSTREAM_ENABLED == 1 - //sif::debug << "TcWinUdpPollingTask::performOperation: " << bytesReceived - // << " bytes received" << std::endl; +#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_WIRETAPPING_ENABLED == 1 + sif::debug << "TcWinUdpPollingTask::performOperation: " << bytesReceived << + " bytes received" << std::endl; #endif ReturnValue_t result = handleSuccessfullTcRead(bytesReceived); @@ -74,12 +74,14 @@ ReturnValue_t TcWinUdpPollingTask::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_WIRETAPPING_ENABLED == 1 + arrayprinter::print(receptionBuffer.data(), bytesRead);# +#endif if (result != HasReturnvaluesIF::RETURN_OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TcSerialPollingTask::transferPusToSoftwareBus: Data " - "storage failed" << std::endl; - sif::error << "Packet size: " << bytesRead << std::endl; + sif::warning<< "TcSerialPollingTask::transferPusToSoftwareBus: Data " + "storage failed" << std::endl; + sif::warning << "Packet size: " << bytesRead << std::endl; #endif return HasReturnvaluesIF::RETURN_FAILED; } @@ -89,8 +91,7 @@ ReturnValue_t TcWinUdpPollingTask::handleSuccessfullTcRead(size_t bytesRead) { result = MessageQueueSenderIF::sendMessage(targetTcDestination, &message); if (result != HasReturnvaluesIF::RETURN_OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "Serial Polling: Sending message to queue failed" - << std::endl; + sif::warning << "Serial Polling: Sending message to queue failed" << std::endl; #endif tcStore->deleteData(storeId); } @@ -117,9 +118,9 @@ ReturnValue_t TcWinUdpPollingTask::initialize() { } serverUdpSocket = tmtcBridge->serverSocket; -#if FSFW_CPP_OSTREAM_ENABLED == 1 - //sif::info << "TcWinUdpPollingTask::initialize: Server UDP socket " - // << serverUdpSocket << std::endl; +#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_WIRETAPPING_ENABLED == 1 + sif::info << "TcWinUdpPollingTask::initialize: Server UDP socket " << serverUdpSocket << + std::endl; #endif return HasReturnvaluesIF::RETURN_OK; diff --git a/osal/windows/TcWinUdpPollingTask.h b/osal/windows/TcWinUdpPollingTask.h index 063a783e..8a9cf51f 100644 --- a/osal/windows/TcWinUdpPollingTask.h +++ b/osal/windows/TcWinUdpPollingTask.h @@ -8,6 +8,9 @@ #include +//! Debugging preprocessor define. +#define FSFW_UDP_RCV_WIRETAPPING_ENABLED 0 + /** * @brief This class can be used to implement the polling of a Unix socket, * using UDP for now. @@ -51,8 +54,7 @@ private: //! 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 + //! Server socket, which is member of TMTC bridge and is assigned in constructor SOCKET serverUdpSocket = 0; std::vector receptionBuffer; diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index ac890198..dce88bb2 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -85,13 +85,12 @@ TmTcWinUdpBridge::~TmTcWinUdpBridge() { ReturnValue_t TmTcWinUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { int flags = 0; - //clientAddress.sin_addr.s_addr = htons(INADDR_ANY); - //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 + clientAddress.sin_addr.s_addr = htons(INADDR_ANY); + clientAddressLen = sizeof(serverAddress); + 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, @@ -104,9 +103,9 @@ ReturnValue_t TmTcWinUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { #endif handleSendError(); } -#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; } @@ -114,16 +113,16 @@ ReturnValue_t TmTcWinUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { void TmTcWinUdpBridge::checkAndSetClientAddress(sockaddr_in newAddress) { MutexHelper 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_SEND_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; clientAddressLen = sizeof(clientAddress); @@ -135,8 +134,8 @@ void TmTcWinUdpBridge::handleSocketError() { switch(errCode) { case(WSANOTINITIALISED): { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << "TmTcWinUdpBridge::handleSocketError: WSANOTINITIALISED: " - << "WSAStartup(...) call necessary" << std::endl; + sif::warning << "TmTcWinUdpBridge::handleSocketError: WSANOTINITIALISED: WSAStartup" + " call necessary" << std::endl; #endif break; } @@ -146,8 +145,7 @@ void TmTcWinUdpBridge::handleSocketError() { windows-sockets-error-codes-2 */ #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << "TmTcWinUdpBridge::handleSocketError: Error code: " - << errCode << std::endl; + sif::warning << "TmTcWinUdpBridge::handleSocketError: Error code: " << errCode << std::endl; #endif break; } diff --git a/osal/windows/TmTcWinUdpBridge.h b/osal/windows/TmTcWinUdpBridge.h index 8188039c..b51c8c7a 100644 --- a/osal/windows/TmTcWinUdpBridge.h +++ b/osal/windows/TmTcWinUdpBridge.h @@ -6,10 +6,13 @@ #include #include +//! Debugging preprocessor define. +#define FSFW_UDP_SEND_WIRETAPPING_ENABLED 0 + class TmTcWinUdpBridge: public TmTcBridge { friend class TcWinUdpPollingTask; public: - // The ports chosen here should not be used by any other process. + /* The ports chosen here should not be used by any other process. */ static constexpr uint16_t DEFAULT_UDP_SERVER_PORT = 7301; static constexpr uint16_t DEFAULT_UDP_CLIENT_PORT = 7302; From 4e5e6e145ecfe866b34a2ed1ef94de1e192a1053 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 8 Mar 2021 23:02:06 +0100 Subject: [PATCH 006/230] added win sock --- osal/windows/TmTcWinUdpBridge.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index dce88bb2..07fedd02 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -38,8 +38,9 @@ TmTcWinUdpBridge::TmTcWinUdpBridge(object_id_t objectId, setClientPort = clientPort; } - // Set up UDP socket: https://man7.org/linux/man-pages/man7/ip.7.html - //clientSocket = socket(AF_INET, SOCK_DGRAM, 0); + /* Set up UDP socket: + https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-socket + */ serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if(serverSocket == INVALID_SOCKET) { #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -52,7 +53,7 @@ TmTcWinUdpBridge::TmTcWinUdpBridge(object_id_t objectId, serverAddress.sin_family = AF_INET; - // Accept packets from any interface. (potentially insecure). + /* Accept packets from any interface. (potentially insecure). */ serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); serverAddress.sin_port = htons(setServerPort); serverAddressLen = sizeof(serverAddress); From 8be4f45969ea46b73f10973dde548af84d9a3621 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 8 Mar 2021 23:14:10 +0100 Subject: [PATCH 007/230] added generic error handler --- osal/windows/TcWinTcpServer.cpp | 35 ++++++++++++++++++++----------- osal/windows/TcWinTcpServer.h | 7 ++++++- osal/windows/TmTcWinUdpBridge.cpp | 19 +++++++++++------ osal/windows/TmTcWinUdpBridge.h | 5 +++++ 4 files changed, 47 insertions(+), 19 deletions(-) diff --git a/osal/windows/TcWinTcpServer.cpp b/osal/windows/TcWinTcpServer.cpp index aebc0bee..756e7776 100644 --- a/osal/windows/TcWinTcpServer.cpp +++ b/osal/windows/TcWinTcpServer.cpp @@ -9,25 +9,39 @@ TcWinTcpServer::TcWinTcpServer(object_id_t objectId, object_id_t tmtcUnixUdpBrid if(serverTcpSocket == 0) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "TcWinTcpServer::TcWinTcpServer: Socket creation failed!" << std::endl; - handleSocketError(); + handleError(ErrorSources::SOCKET_CALL); #endif } - setsockopt(serverTcpSocket, SOL_SOCKET, SO_REUSEADDR | SO_BROADCAST, - &tcpSockOpt, sizeof(tcpSockOpt)); + int retval = setsockopt(serverTcpSocket, SOL_SOCKET, SO_REUSEADDR | SO_BROADCAST, + reinterpret_cast(&tcpSockOpt), sizeof(tcpSockOpt)); + if(retval != 0) { + + } } TcWinTcpServer::~TcWinTcpServer() { } -void TcWinTcpServer::handleSocketError() { +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"; + } switch(errCode) { case(WSANOTINITIALISED): { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "TmTcWinUdpBridge::handleSocketError: WSANOTINITIALISED: WSAStartup" - " call necessary" << std::endl; -#endif + 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: { @@ -35,12 +49,9 @@ void TcWinTcpServer::handleSocketError() { 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; } } +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ } - - diff --git a/osal/windows/TcWinTcpServer.h b/osal/windows/TcWinTcpServer.h index 3a17336a..4f53dda4 100644 --- a/osal/windows/TcWinTcpServer.h +++ b/osal/windows/TcWinTcpServer.h @@ -24,7 +24,12 @@ private: std::vector receptionBuffer; int tcpSockOpt = 0; - void handleSocketError(); + enum class ErrorSources { + SOCKET_CALL, + SETSOCKOPT_CALL + }; + + void handleError(ErrorSources errorSrc); }; #endif /* FSFW_OSAL_WINDOWS_TCWINTCPSERVER_H_ */ diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index 07fedd02..375e45e7 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -44,8 +44,8 @@ TmTcWinUdpBridge::TmTcWinUdpBridge(object_id_t objectId, 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; + sif::warning << "TmTcWinUdpBridge::TmTcWinUdpBridge: Could not open UDP socket!" << + std::endl; #endif handleSocketError(); return; @@ -57,16 +57,23 @@ TmTcWinUdpBridge::TmTcWinUdpBridge(object_id_t objectId, serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); serverAddress.sin_port = htons(setServerPort); serverAddressLen = sizeof(serverAddress); - setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, + 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); clientAddressLen = sizeof(clientAddress); - int result = bind(serverSocket, + result = bind(serverSocket, reinterpret_cast(&serverAddress), serverAddressLen); if(result != 0) { @@ -159,14 +166,14 @@ void TmTcWinUdpBridge::handleBindError() { case(WSANOTINITIALISED): { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::info << "TmTcWinUdpBridge::handleBindError: WSANOTINITIALISED: " - << "WSAStartup(...) call " << "necessary" << std::endl; + << "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; + "Port is already in use!" << std::endl; #endif break; } diff --git a/osal/windows/TmTcWinUdpBridge.h b/osal/windows/TmTcWinUdpBridge.h index b51c8c7a..14354139 100644 --- a/osal/windows/TmTcWinUdpBridge.h +++ b/osal/windows/TmTcWinUdpBridge.h @@ -41,6 +41,11 @@ private: //! by another task. MutexIF* mutex; + enum class ErrorSources { + SOCKET_CALL, + SETSOCKOPT_CALL + }; + void handleSocketError(); void handleBindError(); void handleSendError(); From 494dd0db324af343e1596a295506bc1748ed584f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 8 Mar 2021 23:55:58 +0100 Subject: [PATCH 008/230] continued tcp server --- osal/windows/TcWinTcpServer.cpp | 76 +++++++++++++++++++++++++++++-- osal/windows/TcWinTcpServer.h | 14 +++++- osal/windows/TmTcWinUdpBridge.cpp | 3 +- 3 files changed, 87 insertions(+), 6 deletions(-) diff --git a/osal/windows/TcWinTcpServer.cpp b/osal/windows/TcWinTcpServer.cpp index 756e7776..d090df45 100644 --- a/osal/windows/TcWinTcpServer.cpp +++ b/osal/windows/TcWinTcpServer.cpp @@ -2,10 +2,32 @@ #include "../../serviceinterface/ServiceInterface.h" #include -TcWinTcpServer::TcWinTcpServer(object_id_t objectId, object_id_t tmtcUnixUdpBridge): + +TcWinTcpServer::TcWinTcpServer(object_id_t objectId, object_id_t tmtcUnixUdpBridge, + uint16_t customTcpServerPort): SystemObject(objectId) { - /* Open TCP socket */ + /* 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; + } + + /* Open TCP (stream) socket */ serverTcpSocket = socket(AF_INET, SOCK_STREAM, 0); + uint16_t tcpPort = customTcpServerPort; + + if(customTcpServerPort == 0xffff) { + tcpPort = DEFAULT_TCP_SERVER_PORT; + } + if(serverTcpSocket == 0) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "TcWinTcpServer::TcWinTcpServer: Socket creation failed!" << std::endl; @@ -16,11 +38,52 @@ TcWinTcpServer::TcWinTcpServer(object_id_t objectId, object_id_t tmtcUnixUdpBrid int retval = setsockopt(serverTcpSocket, 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); } + tcpAddress.sin_family = AF_INET; + tcpAddress.sin_addr.s_addr = htonl(INADDR_ANY); + tcpAddress.sin_port = htons(tcpPort); + + retval = bind(serverTcpSocket, reinterpret_cast(&tcpAddress), + tcpAddrLen); + if(retval != 0) { + sif::warning << "TcWinTcpServer::TcWinTcpServer: Binding socket failed!" << + std::endl; + handleError(ErrorSources::BIND_CALL); + } + } TcWinTcpServer::~TcWinTcpServer() { + closesocket(serverTcpSocket); + WSACleanup(); +} + +ReturnValue_t TcWinTcpServer::initialize() { + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t TcWinTcpServer::performOperation(uint8_t opCode) { + /* If a connection is accepted, the corresponding scoket will be assigned to the new socket */ + SOCKET connectorSocket; + sockaddr_in connectorSockAddr; + int connectorSockAddrLen = 0; + /* Listen for connection requests permanently for lifetime of program */ + while(true) { + int retval = listen(serverTcpSocket, backlog); + if(retval != 0) { + handleError(ErrorSources::LISTEN_CALL); + } + + connectorSocket = accept(serverTcpSocket, reinterpret_cast(&connectorSockAddr), + &connectorSockAddrLen); + + if(connectorSocket) {}; + + } + return HasReturnvaluesIF::RETURN_OK; } void TcWinTcpServer::handleError(ErrorSources errorSrc) { @@ -33,6 +96,13 @@ void TcWinTcpServer::handleError(ErrorSources errorSrc) { 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"; + } + switch(errCode) { case(WSANOTINITIALISED): { sif::warning << "TmTcWinUdpBridge::handleError: " << errorSrcString << " | " diff --git a/osal/windows/TcWinTcpServer.h b/osal/windows/TcWinTcpServer.h index 4f53dda4..45d92ff8 100644 --- a/osal/windows/TcWinTcpServer.h +++ b/osal/windows/TcWinTcpServer.h @@ -14,19 +14,29 @@ public: static constexpr uint16_t DEFAULT_TCP_SERVER_PORT = 7301; static constexpr uint16_t DEFAULT_TCP_CLIENT_PORT = 7302; - TcWinTcpServer(object_id_t objectId, object_id_t tmtcUnixUdpBridge); + TcWinTcpServer(object_id_t objectId, object_id_t tmtcUnixUdpBridge, + uint16_t customTcpServerPort = 0xffff); virtual~ TcWinTcpServer(); + ReturnValue_t initialize() override; + ReturnValue_t performOperation(uint8_t opCode) override; + private: SOCKET serverTcpSocket = 0; + struct sockaddr_in tcpAddress; + int tcpAddrLen = sizeof(tcpAddress); + int backlog = 3; std::vector receptionBuffer; int tcpSockOpt = 0; enum class ErrorSources { SOCKET_CALL, - SETSOCKOPT_CALL + SETSOCKOPT_CALL, + BIND_CALL, + LISTEN_CALL, + ACCEPT_CALL }; void handleError(ErrorSources errorSrc); diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index 375e45e7..d4467e44 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -14,7 +14,7 @@ TmTcWinUdpBridge::TmTcWinUdpBridge(object_id_t objectId, mutex = MutexFactory::instance()->createMutex(); communicationLinkUp = false; - // Initiates Winsock DLL. + /* Initiates Winsock DLL. */ WSAData wsaData; WORD wVersionRequested = MAKEWORD(2, 2); int err = WSAStartup(wVersionRequested, &wsaData); @@ -87,6 +87,7 @@ TmTcWinUdpBridge::TmTcWinUdpBridge(object_id_t objectId, } TmTcWinUdpBridge::~TmTcWinUdpBridge() { + closesocket(serverSocket); WSACleanup(); } From b6952424205a5a656294450ae365c54d7c5079a0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 9 Mar 2021 00:37:42 +0100 Subject: [PATCH 009/230] contiued tcp and improved udp task --- osal/windows/TcWinTcpServer.cpp | 115 ++++++++++++++++++--------- osal/windows/TcWinTcpServer.h | 16 ++-- osal/windows/TcWinUdpPollingTask.cpp | 7 +- 3 files changed, 88 insertions(+), 50 deletions(-) diff --git a/osal/windows/TcWinTcpServer.cpp b/osal/windows/TcWinTcpServer.cpp index d090df45..1cf7ed1d 100644 --- a/osal/windows/TcWinTcpServer.cpp +++ b/osal/windows/TcWinTcpServer.cpp @@ -1,86 +1,120 @@ #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, - uint16_t customTcpServerPort): - SystemObject(objectId) { + 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. */ + /* 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; #endif - return; + return HasReturnvaluesIF::RETURN_FAILED; + } + + ZeroMemory(&hints, sizeof (hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_flags = AI_PASSIVE; + + retval = getaddrinfo(nullptr, tcpPort.c_str(), &hints, &addrResult); + if (retval != 0) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "TcWinTcpServer::TcWinTcpServer: Retrieving address info failed!" << + std::endl; +#endif + handleError(ErrorSources::GETADDRINFO_CALL); + return HasReturnvaluesIF::RETURN_FAILED; } /* Open TCP (stream) socket */ - serverTcpSocket = socket(AF_INET, SOCK_STREAM, 0); - uint16_t tcpPort = customTcpServerPort; - - if(customTcpServerPort == 0xffff) { - tcpPort = DEFAULT_TCP_SERVER_PORT; - } - - if(serverTcpSocket == 0) { + 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; - handleError(ErrorSources::SOCKET_CALL); #endif + freeaddrinfo(addrResult); + handleError(ErrorSources::SOCKET_CALL); + return HasReturnvaluesIF::RETURN_FAILED; } - int retval = setsockopt(serverTcpSocket, 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); - } - tcpAddress.sin_family = AF_INET; - tcpAddress.sin_addr.s_addr = htonl(INADDR_ANY); - tcpAddress.sin_port = htons(tcpPort); +// 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(serverTcpSocket, reinterpret_cast(&tcpAddress), + retval = bind(listenerTcpSocket, reinterpret_cast(&tcpAddress), tcpAddrLen); - if(retval != 0) { + 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(serverTcpSocket); + closesocket(listenerTcpSocket); WSACleanup(); } -ReturnValue_t TcWinTcpServer::initialize() { - return HasReturnvaluesIF::RETURN_OK; -} - ReturnValue_t TcWinTcpServer::performOperation(uint8_t opCode) { /* If a connection is accepted, the corresponding scoket will be assigned to the new socket */ - SOCKET connectorSocket; - sockaddr_in connectorSockAddr; + SOCKET clientSocket; + sockaddr_in clientSockAddr; int connectorSockAddrLen = 0; + int retval = 0; /* Listen for connection requests permanently for lifetime of program */ while(true) { - int retval = listen(serverTcpSocket, backlog); - if(retval != 0) { + retval = listen(listenerTcpSocket, currentBacklog); + if(retval == SOCKET_ERROR) { handleError(ErrorSources::LISTEN_CALL); + continue; } - connectorSocket = accept(serverTcpSocket, reinterpret_cast(&connectorSockAddr), + clientSocket = accept(listenerTcpSocket, reinterpret_cast(&clientSockAddr), &connectorSockAddrLen); - if(connectorSocket) {}; + if(clientSocket == INVALID_SOCKET) { + handleError(ErrorSources::ACCEPT_CALL); + continue; + }; + + retval = recv(clientSocket, reinterpret_cast(receptionBuffer.data()), + receptionBuffer.size(), 0); +#if FSFW_TCP_SERVER_WIRETAPPING_ENABLED == 1 +#endif } return HasReturnvaluesIF::RETURN_OK; @@ -102,6 +136,9 @@ void TcWinTcpServer::handleError(ErrorSources errorSrc) { else if(errorSrc == ErrorSources::ACCEPT_CALL) { errorSrcString = "accept call"; } + else if(errorSrc == ErrorSources::GETADDRINFO_CALL) { + errorSrcString = "getaddrinfo call"; + } switch(errCode) { case(WSANOTINITIALISED): { diff --git a/osal/windows/TcWinTcpServer.h b/osal/windows/TcWinTcpServer.h index 45d92ff8..7b679106 100644 --- a/osal/windows/TcWinTcpServer.h +++ b/osal/windows/TcWinTcpServer.h @@ -4,18 +4,22 @@ #include "../../objectmanager/SystemObject.h" #include "../../tasks/ExecutableObjectIF.h" +#include #include +//! Debugging preprocessor define. +#define FSFW_TCP_SERVER_WIRETAPPING_ENABLED 0 + class TcWinTcpServer: public SystemObject, public ExecutableObjectIF { public: /* The ports chosen here should not be used by any other process. */ - static constexpr uint16_t DEFAULT_TCP_SERVER_PORT = 7301; - static constexpr uint16_t DEFAULT_TCP_CLIENT_PORT = 7302; + 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, - uint16_t customTcpServerPort = 0xffff); + std::string customTcpServerPort = ""); virtual~ TcWinTcpServer(); ReturnValue_t initialize() override; @@ -23,15 +27,17 @@ public: private: - SOCKET serverTcpSocket = 0; + std::string tcpPort; + SOCKET listenerTcpSocket = 0; struct sockaddr_in tcpAddress; int tcpAddrLen = sizeof(tcpAddress); - int backlog = 3; + int currentBacklog = 3; std::vector receptionBuffer; int tcpSockOpt = 0; enum class ErrorSources { + GETADDRINFO_CALL, SOCKET_CALL, SETSOCKOPT_CALL, BIND_CALL, diff --git a/osal/windows/TcWinUdpPollingTask.cpp b/osal/windows/TcWinUdpPollingTask.cpp index 32c21700..06e75bd5 100644 --- a/osal/windows/TcWinUdpPollingTask.cpp +++ b/osal/windows/TcWinUdpPollingTask.cpp @@ -3,11 +3,6 @@ #include "../../serviceinterface/ServiceInterfaceStream.h" #include -#include -#if defined(_MSC_VER) -#include -typedef SSIZE_T ssize_t; -#endif TcWinUdpPollingTask::TcWinUdpPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge, size_t frameSize, @@ -41,7 +36,7 @@ ReturnValue_t TcWinUdpPollingTask::performOperation(uint8_t opCode) { //! Sender Address is cached here. struct sockaddr_in senderAddress; int senderAddressSize = sizeof(senderAddress); - ssize_t bytesReceived = recvfrom(serverUdpSocket, + int bytesReceived = recvfrom(serverUdpSocket, reinterpret_cast(receptionBuffer.data()), frameSize, receptionFlags, reinterpret_cast(&senderAddress), &senderAddressSize); From d5a065eaa8c5e5e9472201c9914c8c932bcfdf36 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 9 Mar 2021 00:42:50 +0100 Subject: [PATCH 010/230] continued tcp server --- osal/windows/TcWinTcpServer.cpp | 15 ++++++++++++++- osal/windows/TcWinTcpServer.h | 5 +++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/osal/windows/TcWinTcpServer.cpp b/osal/windows/TcWinTcpServer.cpp index 1cf7ed1d..f85147f0 100644 --- a/osal/windows/TcWinTcpServer.cpp +++ b/osal/windows/TcWinTcpServer.cpp @@ -1,5 +1,6 @@ #include "TcWinTcpServer.h" #include "../../serviceinterface/ServiceInterface.h" + #include #include @@ -90,7 +91,7 @@ TcWinTcpServer::~TcWinTcpServer() { } ReturnValue_t TcWinTcpServer::performOperation(uint8_t opCode) { - /* If a connection is accepted, the corresponding scoket will be assigned to the new socket */ + /* If a connection is accepted, the corresponding socket will be assigned to the new socket */ SOCKET clientSocket; sockaddr_in clientSockAddr; int connectorSockAddrLen = 0; @@ -113,9 +114,21 @@ ReturnValue_t TcWinTcpServer::performOperation(uint8_t opCode) { 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; } diff --git a/osal/windows/TcWinTcpServer.h b/osal/windows/TcWinTcpServer.h index 7b679106..f8aebc53 100644 --- a/osal/windows/TcWinTcpServer.h +++ b/osal/windows/TcWinTcpServer.h @@ -10,6 +10,11 @@ //! 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 { From da2f594a00f945f3c5dffa96d5539425cd4c5362 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 9 Mar 2021 11:25:13 +0100 Subject: [PATCH 011/230] renamed mutex helper to mutex guard --- health/HealthTable.cpp | 12 ++++++------ ipc/{MutexHelper.h => MutexGuard.h} | 19 ++++++++++++------- osal/windows/TmTcWinUdpBridge.cpp | 2 +- storagemanager/PoolManager.cpp | 6 +++--- 4 files changed, 22 insertions(+), 17 deletions(-) rename ipc/{MutexHelper.h => MutexGuard.h} (79%) diff --git a/health/HealthTable.cpp b/health/HealthTable.cpp index 2b8b6712..98af5fb8 100644 --- a/health/HealthTable.cpp +++ b/health/HealthTable.cpp @@ -31,7 +31,7 @@ ReturnValue_t HealthTable::registerObject(object_id_t object, void HealthTable::setHealth(object_id_t object, HasHealthIF::HealthState newState) { - MutexHelper(mutex, timeoutType, mutexTimeoutMs); + MutexGuard(mutex, timeoutType, mutexTimeoutMs); HealthMap::iterator iter = healthMap.find(object); if (iter != healthMap.end()) { iter->second = newState; @@ -40,7 +40,7 @@ void HealthTable::setHealth(object_id_t object, HasHealthIF::HealthState HealthTable::getHealth(object_id_t object) { HasHealthIF::HealthState state = HasHealthIF::HEALTHY; - MutexHelper(mutex, timeoutType, mutexTimeoutMs); + MutexGuard(mutex, timeoutType, mutexTimeoutMs); HealthMap::iterator iter = healthMap.find(object); if (iter != healthMap.end()) { state = iter->second; @@ -49,7 +49,7 @@ HasHealthIF::HealthState HealthTable::getHealth(object_id_t object) { } bool HealthTable::hasHealth(object_id_t object) { - MutexHelper(mutex, timeoutType, mutexTimeoutMs); + MutexGuard(mutex, timeoutType, mutexTimeoutMs); HealthMap::iterator iter = healthMap.find(object); if (iter != healthMap.end()) { return true; @@ -58,14 +58,14 @@ bool HealthTable::hasHealth(object_id_t object) { } size_t HealthTable::getPrintSize() { - MutexHelper(mutex, timeoutType, mutexTimeoutMs); + MutexGuard(mutex, timeoutType, mutexTimeoutMs); uint32_t size = healthMap.size() * sizeof(object_id_t) + sizeof(HasHealthIF::HealthState) + sizeof(uint16_t); return size; } void HealthTable::printAll(uint8_t* pointer, size_t maxSize) { - MutexHelper(mutex, timeoutType, mutexTimeoutMs); + MutexGuard(mutex, timeoutType, mutexTimeoutMs); size_t size = 0; uint16_t count = healthMap.size(); SerializeAdapter::serialize(&count, @@ -81,7 +81,7 @@ void HealthTable::printAll(uint8_t* pointer, size_t maxSize) { ReturnValue_t HealthTable::iterate(HealthEntry *value, bool reset) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - MutexHelper(mutex, timeoutType, mutexTimeoutMs); + MutexGuard(mutex, timeoutType, mutexTimeoutMs); if (reset) { mapIterator = healthMap.begin(); } diff --git a/ipc/MutexHelper.h b/ipc/MutexGuard.h similarity index 79% rename from ipc/MutexHelper.h rename to ipc/MutexGuard.h index bc744d3f..f0c95509 100644 --- a/ipc/MutexHelper.h +++ b/ipc/MutexGuard.h @@ -4,9 +4,9 @@ #include "MutexFactory.h" #include "../serviceinterface/ServiceInterface.h" -class MutexHelper { +class MutexGuard { public: - MutexHelper(MutexIF* mutex, MutexIF::TimeoutType timeoutType = + MutexGuard(MutexIF* mutex, MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::BLOCKING, uint32_t timeoutMs = 0): internalMutex(mutex) { if(mutex == nullptr) { @@ -19,10 +19,10 @@ public: #endif /* FSFW_VERBOSE_LEVEL >= 1 */ return; } - ReturnValue_t status = mutex->lockMutex(timeoutType, + result = mutex->lockMutex(timeoutType, timeoutMs); #if FSFW_VERBOSE_LEVEL >= 1 - if(status == MutexIF::MUTEX_TIMEOUT) { + if(result == MutexIF::MUTEX_TIMEOUT) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "MutexHelper: Lock of mutex failed with timeout of " << timeoutMs << " milliseconds!" << std::endl; @@ -32,9 +32,9 @@ public: #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ } - else if(status != HasReturnvaluesIF::RETURN_OK) { + else if(result != HasReturnvaluesIF::RETURN_OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "MutexHelper: Lock of Mutex failed with code " << status << std::endl; + sif::error << "MutexHelper: Lock of Mutex failed with code " << result << std::endl; #else sif::printError("MutexHelper: Lock of Mutex failed with code %d\n", status); #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ @@ -45,13 +45,18 @@ public: #endif /* FSFW_VERBOSE_LEVEL >= 1 */ } - ~MutexHelper() { + ReturnValue_t getLockResult() const { + return result; + } + + ~MutexGuard() { if(internalMutex != nullptr) { internalMutex->unlockMutex(); } } private: MutexIF* internalMutex; + ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; }; #endif /* FRAMEWORK_IPC_MUTEXHELPER_H_ */ diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index 69a48f3e..94805cdc 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -106,7 +106,7 @@ ReturnValue_t TmTcWinUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { } void TmTcWinUdpBridge::checkAndSetClientAddress(sockaddr_in newAddress) { - MutexHelper lock(mutex, MutexIF::TimeoutType::WAITING, 10); + MutexGuard lock(mutex, MutexIF::TimeoutType::WAITING, 10); // char ipAddress [15]; #if FSFW_CPP_OSTREAM_ENABLED == 1 diff --git a/storagemanager/PoolManager.cpp b/storagemanager/PoolManager.cpp index 4e8014fd..eec84907 100644 --- a/storagemanager/PoolManager.cpp +++ b/storagemanager/PoolManager.cpp @@ -15,7 +15,7 @@ PoolManager::~PoolManager(void) { ReturnValue_t PoolManager::reserveSpace(const size_t size, store_address_t* address, bool ignoreFault) { - MutexHelper mutexHelper(mutex, MutexIF::TimeoutType::WAITING, + MutexGuard mutexHelper(mutex, MutexIF::TimeoutType::WAITING, mutexTimeoutMs); ReturnValue_t status = LocalPool::reserveSpace(size, address,ignoreFault); @@ -32,7 +32,7 @@ ReturnValue_t PoolManager::deleteData( ". id is "<< storeId.packetIndex << std::endl; #endif #endif - MutexHelper mutexHelper(mutex, MutexIF::TimeoutType::WAITING, + MutexGuard mutexHelper(mutex, MutexIF::TimeoutType::WAITING, mutexTimeoutMs); return LocalPool::deleteData(storeId); } @@ -40,7 +40,7 @@ ReturnValue_t PoolManager::deleteData( ReturnValue_t PoolManager::deleteData(uint8_t* buffer, size_t size, store_address_t* storeId) { - MutexHelper mutexHelper(mutex, MutexIF::TimeoutType::WAITING, 20); + MutexGuard mutexHelper(mutex, MutexIF::TimeoutType::WAITING, 20); ReturnValue_t status = LocalPool::deleteData(buffer, size, storeId); return status; From cad302730ef129c0d4509ae7d0fa3185a15294ff Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 9 Mar 2021 11:30:00 +0100 Subject: [PATCH 012/230] mutex guard instead of helpe --- container/SharedRingBuffer.cpp | 2 +- container/SharedRingBuffer.h | 2 +- datapoollocal/LocalDataPoolManager.cpp | 2 +- datapoollocal/LocalDataPoolManager.h | 2 +- datapoollocal/LocalPoolVector.tpp | 4 ++-- health/HealthTable.cpp | 2 +- ipc/MutexGuard.h | 2 +- storagemanager/PoolManager.h | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/container/SharedRingBuffer.cpp b/container/SharedRingBuffer.cpp index 1681325d..5e20bb6f 100644 --- a/container/SharedRingBuffer.cpp +++ b/container/SharedRingBuffer.cpp @@ -1,6 +1,6 @@ #include "SharedRingBuffer.h" #include "../ipc/MutexFactory.h" -#include "../ipc/MutexHelper.h" +#include "../ipc/MutexGuard.h" SharedRingBuffer::SharedRingBuffer(object_id_t objectId, const size_t size, bool overwriteOld, size_t maxExcessBytes): diff --git a/container/SharedRingBuffer.h b/container/SharedRingBuffer.h index 43ab6e8f..66a119ab 100644 --- a/container/SharedRingBuffer.h +++ b/container/SharedRingBuffer.h @@ -66,7 +66,7 @@ public: /** * The mutex handle can be accessed directly, for example to perform - * the lock with the #MutexHelper for a RAII compliant lock operation. + * the lock with the #MutexGuard for a RAII compliant lock operation. * @return */ MutexIF* getMutexHandle() const; diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index 72873d99..0c44ab7e 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -10,7 +10,7 @@ #include "../housekeeping/AcceptsHkPacketsIF.h" #include "../timemanager/CCSDSTime.h" #include "../ipc/MutexFactory.h" -#include "../ipc/MutexHelper.h" +#include "../ipc/MutexGuard.h" #include "../ipc/QueueFactory.h" #include diff --git a/datapoollocal/LocalDataPoolManager.h b/datapoollocal/LocalDataPoolManager.h index ff6edb95..d06cf2c6 100644 --- a/datapoollocal/LocalDataPoolManager.h +++ b/datapoollocal/LocalDataPoolManager.h @@ -14,7 +14,7 @@ #include "../ipc/MutexIF.h" #include "../ipc/CommandMessage.h" #include "../ipc/MessageQueueIF.h" -#include "../ipc/MutexHelper.h" +#include "../ipc/MutexGuard.h" #include #include diff --git a/datapoollocal/LocalPoolVector.tpp b/datapoollocal/LocalPoolVector.tpp index 5b2089b3..044b8fa7 100644 --- a/datapoollocal/LocalPoolVector.tpp +++ b/datapoollocal/LocalPoolVector.tpp @@ -25,7 +25,7 @@ inline LocalPoolVector::LocalPoolVector(gp_id_t globalPoolId, template inline ReturnValue_t LocalPoolVector::read( MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) { - MutexHelper(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs); + MutexGuard(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs); return readWithoutLock(); } template @@ -64,7 +64,7 @@ inline ReturnValue_t LocalPoolVector::commit(bool valid, template inline ReturnValue_t LocalPoolVector::commit( MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) { - MutexHelper(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs); + MutexGuard(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs); return commitWithoutLock(); } diff --git a/health/HealthTable.cpp b/health/HealthTable.cpp index 98af5fb8..5d720b19 100644 --- a/health/HealthTable.cpp +++ b/health/HealthTable.cpp @@ -1,5 +1,5 @@ #include "HealthTable.h" -#include "../ipc/MutexHelper.h" +#include "../ipc/MutexGuard.h" #include "../ipc/MutexFactory.h" #include "../serialize/SerializeAdapter.h" diff --git a/ipc/MutexGuard.h b/ipc/MutexGuard.h index f0c95509..7eee47b5 100644 --- a/ipc/MutexGuard.h +++ b/ipc/MutexGuard.h @@ -36,7 +36,7 @@ public: #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "MutexHelper: Lock of Mutex failed with code " << result << std::endl; #else - sif::printError("MutexHelper: Lock of Mutex failed with code %d\n", status); + sif::printError("MutexHelper: Lock of Mutex failed with code %d\n", result); #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ } #else diff --git a/storagemanager/PoolManager.h b/storagemanager/PoolManager.h index 5786a225..4dde3a23 100644 --- a/storagemanager/PoolManager.h +++ b/storagemanager/PoolManager.h @@ -3,7 +3,7 @@ #include "LocalPool.h" #include "StorageAccessor.h" -#include "../ipc/MutexHelper.h" +#include "../ipc/MutexGuard.h" /** From 59028ccc3ff0421d5e35a1431e21897ebe5dc403 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 9 Mar 2021 14:48:41 +0100 Subject: [PATCH 013/230] updated power component --- power/PowerComponent.cpp | 20 ++++++++++---------- power/PowerComponent.h | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/power/PowerComponent.cpp b/power/PowerComponent.cpp index 778d2b71..9ea84dad 100644 --- a/power/PowerComponent.cpp +++ b/power/PowerComponent.cpp @@ -9,23 +9,23 @@ PowerComponent::PowerComponent(): switchId1(0xFF), switchId2(0xFF), PowerComponent::PowerComponent(object_id_t setId, uint8_t moduleId, float min, float max, uint8_t switchId1, bool twoSwitches, uint8_t switchId2) : deviceObjectId(setId), switchId1(switchId1), switchId2(switchId2), - doIHaveTwoSwitches(twoSwitches), minVoltage(min), maxVoltage(max), + doIHaveTwoSwitches(twoSwitches), minPower(min), maxPower(max), moduleId(moduleId) { } ReturnValue_t PowerComponent::serialize(uint8_t** buffer, size_t* size, size_t maxSize, Endianness streamEndianness) const { - ReturnValue_t result = SerializeAdapter::serialize(&minVoltage, buffer, + ReturnValue_t result = SerializeAdapter::serialize(&minPower, buffer, size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return SerializeAdapter::serialize(&maxVoltage, buffer, size, maxSize, + return SerializeAdapter::serialize(&maxPower, buffer, size, maxSize, streamEndianness); } size_t PowerComponent::getSerializedSize() const { - return sizeof(minVoltage) + sizeof(maxVoltage); + return sizeof(minPower) + sizeof(maxPower); } object_id_t PowerComponent::getDeviceObjectId() { @@ -45,21 +45,21 @@ bool PowerComponent::hasTwoSwitches() { } float PowerComponent::getMin() { - return minVoltage; + return minPower; } float PowerComponent::getMax() { - return maxVoltage; + return maxPower; } ReturnValue_t PowerComponent::deSerialize(const uint8_t** buffer, size_t* size, Endianness streamEndianness) { - ReturnValue_t result = SerializeAdapter::deSerialize(&minVoltage, buffer, + ReturnValue_t result = SerializeAdapter::deSerialize(&minPower, buffer, size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return SerializeAdapter::deSerialize(&maxVoltage, buffer, size, streamEndianness); + return SerializeAdapter::deSerialize(&maxPower, buffer, size, streamEndianness); } ReturnValue_t PowerComponent::getParameter(uint8_t domainId, uint8_t uniqueId, @@ -70,10 +70,10 @@ ReturnValue_t PowerComponent::getParameter(uint8_t domainId, uint8_t uniqueId, } switch (uniqueId) { case 0: - parameterWrapper->set<>(minVoltage); + parameterWrapper->set<>(minPower); break; case 1: - parameterWrapper->set<>(maxVoltage); + parameterWrapper->set<>(maxPower); break; default: return INVALID_IDENTIFIER_ID; diff --git a/power/PowerComponent.h b/power/PowerComponent.h index 68b07c32..ce45f142 100644 --- a/power/PowerComponent.h +++ b/power/PowerComponent.h @@ -41,8 +41,8 @@ private: const bool doIHaveTwoSwitches; - float minVoltage = 0.0; - float maxVoltage = 0.0; + float minPower = 0.0; + float maxPower = 0.0; uint8_t moduleId = 0; From 7b3616c41f9912d91b2ffcc959db84f99f38b4ba Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 9 Mar 2021 21:09:01 +0100 Subject: [PATCH 014/230] corrections --- power/PowerComponent.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/power/PowerComponent.h b/power/PowerComponent.h index ce45f142..6b9778a5 100644 --- a/power/PowerComponent.h +++ b/power/PowerComponent.h @@ -9,7 +9,7 @@ class PowerComponent: public PowerComponentIF { public: - PowerComponent(object_id_t setId, uint8_t moduleId, float minVoltage, float maxVoltage, + PowerComponent(object_id_t setId, uint8_t moduleId, float minPower, float maxPower, uint8_t switchId1, bool twoSwitches = false, uint8_t switchId2 = 0xFF); From 82d7b7ed6f62d0f3ca64b7bdc89781a6c242fd3c Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 9 Mar 2021 21:21:01 +0100 Subject: [PATCH 015/230] renamed mutex helper --- ipc/MutexGuard.h | 2 -- osal/linux/TmTcUnixUdpBridge.cpp | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/ipc/MutexGuard.h b/ipc/MutexGuard.h index 7eee47b5..4ad23012 100644 --- a/ipc/MutexGuard.h +++ b/ipc/MutexGuard.h @@ -40,8 +40,6 @@ public: #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ } #else - /* To avoid unused variable warning */ - static_cast(status); #endif /* FSFW_VERBOSE_LEVEL >= 1 */ } diff --git a/osal/linux/TmTcUnixUdpBridge.cpp b/osal/linux/TmTcUnixUdpBridge.cpp index 0af1fc68..7f110114 100644 --- a/osal/linux/TmTcUnixUdpBridge.cpp +++ b/osal/linux/TmTcUnixUdpBridge.cpp @@ -1,6 +1,6 @@ #include "TmTcUnixUdpBridge.h" #include "../../serviceinterface/ServiceInterface.h" -#include "../../ipc/MutexHelper.h" +#include "../../ipc/MutexGuard.h" #include #include @@ -69,7 +69,7 @@ TmTcUnixUdpBridge::~TmTcUnixUdpBridge() { ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { int flags = 0; - MutexHelper lock(mutex, MutexIF::TimeoutType::WAITING, 10); + MutexGuard lock(mutex, MutexIF::TimeoutType::WAITING, 10); if(ipAddrAnySet){ clientAddress.sin_addr.s_addr = htons(INADDR_ANY); @@ -100,7 +100,7 @@ ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { } void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in& newAddress) { - MutexHelper lock(mutex, MutexIF::TimeoutType::WAITING, 10); + MutexGuard lock(mutex, MutexIF::TimeoutType::WAITING, 10); // char ipAddress [15]; #if FSFW_CPP_OSTREAM_ENABLED == 1 From a7bf9a6734d29f59a74024934886969c6572e9c6 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 9 Mar 2021 21:25:22 +0100 Subject: [PATCH 016/230] important replacements --- ipc/MutexGuard.h | 18 +++++++++--------- osal/host/MessageQueue.cpp | 6 +++--- osal/host/QueueMapManager.cpp | 4 ++-- osal/rtems/Clock.cpp | 6 +++--- osal/windows/TmTcWinUdpBridge.cpp | 2 +- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/ipc/MutexGuard.h b/ipc/MutexGuard.h index 4ad23012..9ee68c81 100644 --- a/ipc/MutexGuard.h +++ b/ipc/MutexGuard.h @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_IPC_MUTEXHELPER_H_ -#define FRAMEWORK_IPC_MUTEXHELPER_H_ +#ifndef FRAMEWORK_IPC_MUTEXGUARD_H_ +#define FRAMEWORK_IPC_MUTEXGUARD_H_ #include "MutexFactory.h" #include "../serviceinterface/ServiceInterface.h" @@ -12,9 +12,9 @@ public: if(mutex == nullptr) { #if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "MutexHelper: Passed mutex is invalid!" << std::endl; + sif::error << "MutexGuard: Passed mutex is invalid!" << std::endl; #else - sif::printError("MutexHelper: Passed mutex is invalid!\n"); + sif::printError("MutexGuard: Passed mutex is invalid!\n"); #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ #endif /* FSFW_VERBOSE_LEVEL >= 1 */ return; @@ -24,19 +24,19 @@ public: #if FSFW_VERBOSE_LEVEL >= 1 if(result == MutexIF::MUTEX_TIMEOUT) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "MutexHelper: Lock of mutex failed with timeout of " + sif::error << "MutexGuard: Lock of mutex failed with timeout of " << timeoutMs << " milliseconds!" << std::endl; #else - sif::printError("MutexHelper: Lock of mutex failed with timeout of %lu milliseconds\n", + sif::printError("MutexGuard: Lock of mutex failed with timeout of %lu milliseconds\n", timeoutMs); #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ } else if(result != HasReturnvaluesIF::RETURN_OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "MutexHelper: Lock of Mutex failed with code " << result << std::endl; + sif::error << "MutexGuard: Lock of Mutex failed with code " << result << std::endl; #else - sif::printError("MutexHelper: Lock of Mutex failed with code %d\n", result); + sif::printError("MutexGuard: Lock of Mutex failed with code %d\n", result); #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ } #else @@ -57,4 +57,4 @@ private: ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; }; -#endif /* FRAMEWORK_IPC_MUTEXHELPER_H_ */ +#endif /* FRAMEWORK_IPC_MUTEXGUARD_H_ */ diff --git a/osal/host/MessageQueue.cpp b/osal/host/MessageQueue.cpp index dfc045e8..fe7b8c08 100644 --- a/osal/host/MessageQueue.cpp +++ b/osal/host/MessageQueue.cpp @@ -3,7 +3,7 @@ #include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../ipc/MutexFactory.h" -#include "../../ipc/MutexHelper.h" +#include "../../ipc/MutexGuard.h" MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize): messageSize(maxMessageSize), messageDepth(messageDepth) { @@ -65,7 +65,7 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { } // not sure this will work.. //*message = std::move(messageQueue.front()); - MutexHelper mutexLock(queueLock, MutexIF::TimeoutType::WAITING, 20); + MutexGuard mutexLock(queueLock, MutexIF::TimeoutType::WAITING, 20); MessageQueueMessage* currentMessage = &messageQueue.front(); std::copy(currentMessage->getBuffer(), currentMessage->getBuffer() + messageSize, message->getBuffer()); @@ -130,7 +130,7 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, return HasReturnvaluesIF::RETURN_FAILED; } if(targetQueue->messageQueue.size() < targetQueue->messageDepth) { - MutexHelper mutexLock(targetQueue->queueLock, + MutexGuard mutexLock(targetQueue->queueLock, MutexIF::TimeoutType::WAITING, 20); // not ideal, works for now though. MessageQueueMessage* mqmMessage = diff --git a/osal/host/QueueMapManager.cpp b/osal/host/QueueMapManager.cpp index 2a54f813..b50d62dc 100644 --- a/osal/host/QueueMapManager.cpp +++ b/osal/host/QueueMapManager.cpp @@ -2,7 +2,7 @@ #include "../../serviceinterface/ServiceInterface.h" #include "../../ipc/MutexFactory.h" -#include "../../ipc/MutexHelper.h" +#include "../../ipc/MutexGuard.h" QueueMapManager* QueueMapManager::mqManagerInstance = nullptr; @@ -43,7 +43,7 @@ ReturnValue_t QueueMapManager::addMessageQueue( MessageQueueIF* QueueMapManager::getMessageQueue( MessageQueueId_t messageQueueId) const { - MutexHelper(mapLock, MutexIF::TimeoutType::WAITING, 50); + MutexGuard(mapLock, MutexIF::TimeoutType::WAITING, 50); auto queueIter = queueMap.find(messageQueueId); if(queueIter != queueMap.end()) { return queueIter->second; diff --git a/osal/rtems/Clock.cpp b/osal/rtems/Clock.cpp index aef71fe1..b80786f7 100644 --- a/osal/rtems/Clock.cpp +++ b/osal/rtems/Clock.cpp @@ -1,7 +1,7 @@ #include "RtemsBasic.h" #include "../../timemanager/Clock.h" -#include "../../ipc/MutexHelper.h" +#include "../../ipc/MutexGuard.h" #include #include @@ -183,7 +183,7 @@ ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) { if(checkOrCreateClockMutex()!=HasReturnvaluesIF::RETURN_OK){ return HasReturnvaluesIF::RETURN_FAILED; } - MutexHelper helper(timeMutex); + MutexGuard helper(timeMutex); leapSeconds = leapSeconds_; @@ -196,7 +196,7 @@ ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) { if(timeMutex==nullptr){ return HasReturnvaluesIF::RETURN_FAILED; } - MutexHelper helper(timeMutex); + MutexGuard helper(timeMutex); *leapSeconds_ = leapSeconds; diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index 36bb9ad3..d0de33d3 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -1,6 +1,6 @@ #include "TmTcWinUdpBridge.h" -#include +#include #if defined(_MSC_VER) #include From 3e9c19ee11950e73a5d67276697add9f07521097 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 9 Mar 2021 21:25:22 +0100 Subject: [PATCH 017/230] important replacements --- ipc/MutexGuard.h | 18 +++++++++--------- osal/host/MessageQueue.cpp | 6 +++--- osal/host/QueueMapManager.cpp | 4 ++-- osal/rtems/Clock.cpp | 6 +++--- osal/windows/TmTcWinUdpBridge.cpp | 8 +++++++- 5 files changed, 24 insertions(+), 18 deletions(-) diff --git a/ipc/MutexGuard.h b/ipc/MutexGuard.h index 7eee47b5..00baa2da 100644 --- a/ipc/MutexGuard.h +++ b/ipc/MutexGuard.h @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_IPC_MUTEXHELPER_H_ -#define FRAMEWORK_IPC_MUTEXHELPER_H_ +#ifndef FRAMEWORK_IPC_MUTEXGUARD_H_ +#define FRAMEWORK_IPC_MUTEXGUARD_H_ #include "MutexFactory.h" #include "../serviceinterface/ServiceInterface.h" @@ -12,9 +12,9 @@ public: if(mutex == nullptr) { #if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "MutexHelper: Passed mutex is invalid!" << std::endl; + sif::error << "MutexGuard: Passed mutex is invalid!" << std::endl; #else - sif::printError("MutexHelper: Passed mutex is invalid!\n"); + sif::printError("MutexGuard: Passed mutex is invalid!\n"); #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ #endif /* FSFW_VERBOSE_LEVEL >= 1 */ return; @@ -24,19 +24,19 @@ public: #if FSFW_VERBOSE_LEVEL >= 1 if(result == MutexIF::MUTEX_TIMEOUT) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "MutexHelper: Lock of mutex failed with timeout of " + sif::error << "MutexGuard: Lock of mutex failed with timeout of " << timeoutMs << " milliseconds!" << std::endl; #else - sif::printError("MutexHelper: Lock of mutex failed with timeout of %lu milliseconds\n", + sif::printError("MutexGuard: Lock of mutex failed with timeout of %lu milliseconds\n", timeoutMs); #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ } else if(result != HasReturnvaluesIF::RETURN_OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "MutexHelper: Lock of Mutex failed with code " << result << std::endl; + sif::error << "MutexGuard: Lock of Mutex failed with code " << result << std::endl; #else - sif::printError("MutexHelper: Lock of Mutex failed with code %d\n", result); + sif::printError("MutexGuard: Lock of Mutex failed with code %d\n", result); #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ } #else @@ -59,4 +59,4 @@ private: ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; }; -#endif /* FRAMEWORK_IPC_MUTEXHELPER_H_ */ +#endif /* FRAMEWORK_IPC_MUTEXGUARD_H_ */ diff --git a/osal/host/MessageQueue.cpp b/osal/host/MessageQueue.cpp index dfc045e8..fe7b8c08 100644 --- a/osal/host/MessageQueue.cpp +++ b/osal/host/MessageQueue.cpp @@ -3,7 +3,7 @@ #include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../ipc/MutexFactory.h" -#include "../../ipc/MutexHelper.h" +#include "../../ipc/MutexGuard.h" MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize): messageSize(maxMessageSize), messageDepth(messageDepth) { @@ -65,7 +65,7 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { } // not sure this will work.. //*message = std::move(messageQueue.front()); - MutexHelper mutexLock(queueLock, MutexIF::TimeoutType::WAITING, 20); + MutexGuard mutexLock(queueLock, MutexIF::TimeoutType::WAITING, 20); MessageQueueMessage* currentMessage = &messageQueue.front(); std::copy(currentMessage->getBuffer(), currentMessage->getBuffer() + messageSize, message->getBuffer()); @@ -130,7 +130,7 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, return HasReturnvaluesIF::RETURN_FAILED; } if(targetQueue->messageQueue.size() < targetQueue->messageDepth) { - MutexHelper mutexLock(targetQueue->queueLock, + MutexGuard mutexLock(targetQueue->queueLock, MutexIF::TimeoutType::WAITING, 20); // not ideal, works for now though. MessageQueueMessage* mqmMessage = diff --git a/osal/host/QueueMapManager.cpp b/osal/host/QueueMapManager.cpp index 2a54f813..b50d62dc 100644 --- a/osal/host/QueueMapManager.cpp +++ b/osal/host/QueueMapManager.cpp @@ -2,7 +2,7 @@ #include "../../serviceinterface/ServiceInterface.h" #include "../../ipc/MutexFactory.h" -#include "../../ipc/MutexHelper.h" +#include "../../ipc/MutexGuard.h" QueueMapManager* QueueMapManager::mqManagerInstance = nullptr; @@ -43,7 +43,7 @@ ReturnValue_t QueueMapManager::addMessageQueue( MessageQueueIF* QueueMapManager::getMessageQueue( MessageQueueId_t messageQueueId) const { - MutexHelper(mapLock, MutexIF::TimeoutType::WAITING, 50); + MutexGuard(mapLock, MutexIF::TimeoutType::WAITING, 50); auto queueIter = queueMap.find(messageQueueId); if(queueIter != queueMap.end()) { return queueIter->second; diff --git a/osal/rtems/Clock.cpp b/osal/rtems/Clock.cpp index aef71fe1..b80786f7 100644 --- a/osal/rtems/Clock.cpp +++ b/osal/rtems/Clock.cpp @@ -1,7 +1,7 @@ #include "RtemsBasic.h" #include "../../timemanager/Clock.h" -#include "../../ipc/MutexHelper.h" +#include "../../ipc/MutexGuard.h" #include #include @@ -183,7 +183,7 @@ ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) { if(checkOrCreateClockMutex()!=HasReturnvaluesIF::RETURN_OK){ return HasReturnvaluesIF::RETURN_FAILED; } - MutexHelper helper(timeMutex); + MutexGuard helper(timeMutex); leapSeconds = leapSeconds_; @@ -196,7 +196,7 @@ ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) { if(timeMutex==nullptr){ return HasReturnvaluesIF::RETURN_FAILED; } - MutexHelper helper(timeMutex); + MutexGuard helper(timeMutex); *leapSeconds_ = leapSeconds; diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index 94805cdc..d0de33d3 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -1,6 +1,12 @@ -#include #include "TmTcWinUdpBridge.h" +#include + +#if defined(_MSC_VER) +#include +typedef SSIZE_T ssize_t; +#endif + TmTcWinUdpBridge::TmTcWinUdpBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId, object_id_t tcStoreId, uint16_t serverPort, uint16_t clientPort): From 7525c883925a2e0e9eae6932337eab459b061cfe Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 9 Mar 2021 21:21:01 +0100 Subject: [PATCH 018/230] renamed mutex helper --- ipc/MutexGuard.h | 2 -- osal/linux/TmTcUnixUdpBridge.cpp | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/ipc/MutexGuard.h b/ipc/MutexGuard.h index 00baa2da..9ee68c81 100644 --- a/ipc/MutexGuard.h +++ b/ipc/MutexGuard.h @@ -40,8 +40,6 @@ public: #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ } #else - /* To avoid unused variable warning */ - static_cast(status); #endif /* FSFW_VERBOSE_LEVEL >= 1 */ } diff --git a/osal/linux/TmTcUnixUdpBridge.cpp b/osal/linux/TmTcUnixUdpBridge.cpp index 0af1fc68..7f110114 100644 --- a/osal/linux/TmTcUnixUdpBridge.cpp +++ b/osal/linux/TmTcUnixUdpBridge.cpp @@ -1,6 +1,6 @@ #include "TmTcUnixUdpBridge.h" #include "../../serviceinterface/ServiceInterface.h" -#include "../../ipc/MutexHelper.h" +#include "../../ipc/MutexGuard.h" #include #include @@ -69,7 +69,7 @@ TmTcUnixUdpBridge::~TmTcUnixUdpBridge() { ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { int flags = 0; - MutexHelper lock(mutex, MutexIF::TimeoutType::WAITING, 10); + MutexGuard lock(mutex, MutexIF::TimeoutType::WAITING, 10); if(ipAddrAnySet){ clientAddress.sin_addr.s_addr = htons(INADDR_ANY); @@ -100,7 +100,7 @@ ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { } void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in& newAddress) { - MutexHelper lock(mutex, MutexIF::TimeoutType::WAITING, 10); + MutexGuard lock(mutex, MutexIF::TimeoutType::WAITING, 10); // char ipAddress [15]; #if FSFW_CPP_OSTREAM_ENABLED == 1 From 61affafecdd4777b84cd46c711e97aa696e951dc Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 9 Mar 2021 21:58:29 +0100 Subject: [PATCH 019/230] and now some test broke.. --- osal/linux/TaskFactory.cpp | 1 + unittest/tests/datapoollocal/DataSetTest.cpp | 6 +++--- unittest/tests/datapoollocal/LocalPoolManagerTest.cpp | 4 ++-- unittest/tests/datapoollocal/LocalPoolOwnerBase.h | 5 +++-- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/osal/linux/TaskFactory.cpp b/osal/linux/TaskFactory.cpp index 93564647..80bf47b7 100644 --- a/osal/linux/TaskFactory.cpp +++ b/osal/linux/TaskFactory.cpp @@ -2,6 +2,7 @@ #include "PeriodicPosixTask.h" #include "../../tasks/TaskFactory.h" +#include "../../serviceinterface/ServiceInterface.h" #include "../../returnvalues/HasReturnvaluesIF.h" //TODO: Different variant than the lazy loading in QueueFactory. What's better and why? diff --git a/unittest/tests/datapoollocal/DataSetTest.cpp b/unittest/tests/datapoollocal/DataSetTest.cpp index 56134595..920bbda2 100644 --- a/unittest/tests/datapoollocal/DataSetTest.cpp +++ b/unittest/tests/datapoollocal/DataSetTest.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include @@ -54,7 +54,7 @@ TEST_CASE("LocalDataSet" , "[LocDataSetTest]") { { /* Test read operation. Values should be all zeros */ - PoolReadHelper readHelper(&localSet); + PoolReadGuard readHelper(&localSet); REQUIRE(readHelper.getReadResult() == retval::CATCH_OK); CHECK(not localSet.isValid()); CHECK(localSet.localPoolVarUint8.value == 0); @@ -82,7 +82,7 @@ TEST_CASE("LocalDataSet" , "[LocDataSetTest]") { { /* Now we read again and check whether our zeroed values were overwritten with the values in the pool */ - PoolReadHelper readHelper(&localSet); + PoolReadGuard readHelper(&localSet); REQUIRE(readHelper.getReadResult() == retval::CATCH_OK); CHECK(localSet.isValid()); CHECK(localSet.localPoolVarUint8.value == 232); diff --git a/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp b/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp index a10b4499..cd3be942 100644 --- a/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp +++ b/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include #include @@ -75,7 +75,7 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { SECTION("SnapshotUpdateTests") { /* Set the variables in the set to certain values. These are checked later. */ { - PoolReadHelper readHelper(&poolOwner->dataset); + PoolReadGuard readHelper(&poolOwner->dataset); REQUIRE(readHelper.getReadResult() == retval::CATCH_OK); poolOwner->dataset.localPoolVarUint8.value = 5; poolOwner->dataset.localPoolVarFloat.value = -12.242; diff --git a/unittest/tests/datapoollocal/LocalPoolOwnerBase.h b/unittest/tests/datapoollocal/LocalPoolOwnerBase.h index 5c277850..8e6b07b0 100644 --- a/unittest/tests/datapoollocal/LocalPoolOwnerBase.h +++ b/unittest/tests/datapoollocal/LocalPoolOwnerBase.h @@ -1,16 +1,17 @@ #ifndef FSFW_UNITTEST_TESTS_DATAPOOLLOCAL_LOCALPOOLOWNERBASE_H_ #define FSFW_UNITTEST_TESTS_DATAPOOLLOCAL_LOCALPOOLOWNERBASE_H_ +#include + #include #include #include #include #include #include -#include #include #include -#include "../../../datapool/PoolReadHelper.h" +#include namespace lpool { static constexpr lp_id_t uint8VarId = 0; From e5b3b6d75eaaa424f21aaf0120768ba0f94b18d3 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 9 Mar 2021 22:21:27 +0100 Subject: [PATCH 020/230] fixed unit test --- unittest/tests/action/TestActionHelper.cpp | 2 +- unittest/tests/datapoollocal/LocalPoolVectorTest.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/unittest/tests/action/TestActionHelper.cpp b/unittest/tests/action/TestActionHelper.cpp index a7adfc82..d8bd58c9 100644 --- a/unittest/tests/action/TestActionHelper.cpp +++ b/unittest/tests/action/TestActionHelper.cpp @@ -70,7 +70,7 @@ TEST_CASE( "Action Helper" , "[ActionHelper]") { SECTION("Handle finish"){ CHECK(not testMqMock.wasMessageSent()); ReturnValue_t status = 0x9876; - actionHelper.finish(true, testMqMock.getId(), testActionId, status); + actionHelper.finish(false, testMqMock.getId(), testActionId, status); CHECK(testMqMock.wasMessageSent()); CommandMessage testMessage; REQUIRE(testMqMock.receiveMessage(&testMessage) == static_cast(HasReturnvaluesIF::RETURN_OK)); diff --git a/unittest/tests/datapoollocal/LocalPoolVectorTest.cpp b/unittest/tests/datapoollocal/LocalPoolVectorTest.cpp index 2bc47568..db76fc00 100644 --- a/unittest/tests/datapoollocal/LocalPoolVectorTest.cpp +++ b/unittest/tests/datapoollocal/LocalPoolVectorTest.cpp @@ -115,6 +115,7 @@ TEST_CASE("LocalPoolVector" , "[LocPoolVecTest]") { REQUIRE(readOnlyVec.commit() == static_cast(PoolVariableIF::INVALID_READ_WRITE_MODE)); } + poolOwner->reset(); } From bb5b7bed40eaf86293ebc9f631dc39ee2b844469 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 9 Mar 2021 23:18:53 +0100 Subject: [PATCH 021/230] made getter public --- datapoollocal/LocalPoolDataSetBase.h | 3 ++- unittest/tests/datapoollocal/DataSetTest.cpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/datapoollocal/LocalPoolDataSetBase.h b/datapoollocal/LocalPoolDataSetBase.h index 404509ae..b9946aaf 100644 --- a/datapoollocal/LocalPoolDataSetBase.h +++ b/datapoollocal/LocalPoolDataSetBase.h @@ -166,6 +166,8 @@ public: object_id_t getCreatorObjectId(); + bool getReportingEnabled() const; + protected: sid_t sid; //! This mutex is used if the data is created by one object only. @@ -180,7 +182,6 @@ protected: */ bool reportingEnabled = false; void setReportingEnabled(bool enabled); - bool getReportingEnabled() const; void initializePeriodicHelper(float collectionInterval, dur_millis_t minimumPeriodicInterval, diff --git a/unittest/tests/datapoollocal/DataSetTest.cpp b/unittest/tests/datapoollocal/DataSetTest.cpp index 920bbda2..101116cb 100644 --- a/unittest/tests/datapoollocal/DataSetTest.cpp +++ b/unittest/tests/datapoollocal/DataSetTest.cpp @@ -21,6 +21,7 @@ TEST_CASE("LocalDataSet" , "[LocDataSetTest]") { SECTION("BasicTest") { /* Test some basic functions */ + CHECK(localSet.getReportingEnabled() == false); CHECK(localSet.getLocalPoolIdsSerializedSize(false) == 3 * sizeof(lp_id_t)); CHECK(localSet.getLocalPoolIdsSerializedSize(true) == 3 * sizeof(lp_id_t) + sizeof(uint8_t)); From 676c9ffcf39c648be8c5cb7fc7f630b585088365 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 10 Mar 2021 16:32:24 +0100 Subject: [PATCH 022/230] added header amalagation --- datapoollocal/datapoollocal.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 datapoollocal/datapoollocal.h diff --git a/datapoollocal/datapoollocal.h b/datapoollocal/datapoollocal.h new file mode 100644 index 00000000..c5c47078 --- /dev/null +++ b/datapoollocal/datapoollocal.h @@ -0,0 +1,12 @@ +#ifndef FSFW_DATAPOOLLOCAL_DATAPOOLLOCAL_H_ +#define FSFW_DATAPOOLLOCAL_DATAPOOLLOCAL_H_ + +/* Collected related headers */ +#include "LocalPoolVariable.h" +#include "LocalPoolVector.h" +#include "StaticLocalDataSet.h" +#include "LocalDataSet.h" +#include "SharedLocalDataSet.h" + + +#endif /* FSFW_DATAPOOLLOCAL_DATAPOOLLOCAL_H_ */ From 9ba7fabdeab72b71f325a8cf57d11ea089455656 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 10 Mar 2021 16:38:54 +0100 Subject: [PATCH 023/230] removed commented out code --- unittest/tests/mocks/MessageQueueMockBase.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/unittest/tests/mocks/MessageQueueMockBase.h b/unittest/tests/mocks/MessageQueueMockBase.h index 7b810b41..31146d34 100644 --- a/unittest/tests/mocks/MessageQueueMockBase.h +++ b/unittest/tests/mocks/MessageQueueMockBase.h @@ -30,10 +30,7 @@ public: } virtual ReturnValue_t reply( MessageQueueMessageIF* message ) { - //messageSent = true; - //lastMessage = *(dynamic_cast(message)); return sendMessage(myQueueId, message); - return HasReturnvaluesIF::RETURN_OK; }; virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message, MessageQueueId_t *receivedFrom) { @@ -61,21 +58,13 @@ public: virtual ReturnValue_t sendMessageFrom( MessageQueueId_t sendTo, MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault = false ) { - //messageSent = true; - //lastMessage = *(dynamic_cast(message)); - //return HasReturnvaluesIF::RETURN_OK; return sendMessage(sendTo, message); } virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault = false ) { - //messageSent = true; - //lastMessage = *(dynamic_cast(message)); - //return HasReturnvaluesIF::RETURN_OK; return sendMessage(myQueueId, message); } virtual ReturnValue_t sendToDefault( MessageQueueMessageIF* message ) { - //messageSent = true; - //lastMessage = *(dynamic_cast(message)); return sendMessage(myQueueId, message); } virtual ReturnValue_t sendMessage( MessageQueueId_t sendTo, @@ -114,7 +103,6 @@ public: private: std::queue messagesSentQueue; - //MessageQueueMessage lastMessage; }; From 1e73302ba27f4a9beb1a5084cd3c495b48481c7c Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 10 Mar 2021 17:45:22 +0100 Subject: [PATCH 024/230] corrected include --- unittest/tests/datapoollocal/LocalPoolOwnerBase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unittest/tests/datapoollocal/LocalPoolOwnerBase.h b/unittest/tests/datapoollocal/LocalPoolOwnerBase.h index 5c277850..03b0d190 100644 --- a/unittest/tests/datapoollocal/LocalPoolOwnerBase.h +++ b/unittest/tests/datapoollocal/LocalPoolOwnerBase.h @@ -10,7 +10,7 @@ #include #include #include -#include "../../../datapool/PoolReadHelper.h" +#include namespace lpool { static constexpr lp_id_t uint8VarId = 0; From 30910034f0af710d49f5f5d3746c4b41ef948137 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 10 Mar 2021 17:46:36 +0100 Subject: [PATCH 025/230] tiny improvementst --- unittest/tests/datapoollocal/DataSetTest.cpp | 2 +- unittest/tests/datapoollocal/LocalPoolVariableTest.cpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/unittest/tests/datapoollocal/DataSetTest.cpp b/unittest/tests/datapoollocal/DataSetTest.cpp index 101116cb..eb587e3f 100644 --- a/unittest/tests/datapoollocal/DataSetTest.cpp +++ b/unittest/tests/datapoollocal/DataSetTest.cpp @@ -10,7 +10,7 @@ #include -TEST_CASE("LocalDataSet" , "[LocDataSetTest]") { +TEST_CASE("DataSetTest" , "[DataSetTest]") { LocalPoolOwnerBase* poolOwner = objectManager-> get(objects::TEST_LOCAL_POOL_OWNER_BASE); REQUIRE(poolOwner != nullptr); diff --git a/unittest/tests/datapoollocal/LocalPoolVariableTest.cpp b/unittest/tests/datapoollocal/LocalPoolVariableTest.cpp index e5a5d364..980ffda1 100644 --- a/unittest/tests/datapoollocal/LocalPoolVariableTest.cpp +++ b/unittest/tests/datapoollocal/LocalPoolVariableTest.cpp @@ -10,8 +10,7 @@ TEST_CASE("LocalPoolVariable" , "[LocPoolVarTest]") { get(objects::TEST_LOCAL_POOL_OWNER_BASE); REQUIRE(poolOwner != nullptr); REQUIRE(poolOwner->initializeHkManager() == retval::CATCH_OK); - REQUIRE(poolOwner->initializeHkManagerAfterTaskCreation() - == retval::CATCH_OK); + REQUIRE(poolOwner->initializeHkManagerAfterTaskCreation() == retval::CATCH_OK); SECTION("Basic Tests") { /* very basic test. */ From 943495117b416d357fd7afa02fc02608b655f4af Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 10 Mar 2021 17:50:10 +0100 Subject: [PATCH 026/230] moved preproc block --- datapoollocal/LocalDataPoolManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index 0c44ab7e..f572dc02 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -843,6 +843,7 @@ object_id_t LocalDataPoolManager::getCreatorObjectId() const { void LocalDataPoolManager::printWarningOrError(sif::OutputTypes outputType, const char* functionName, ReturnValue_t error, const char* errorPrint) { +#if FSFW_VERBOSE_LEVEL >= 1 if(errorPrint == nullptr) { if(error == DATASET_NOT_FOUND) { errorPrint = "Dataset not found"; @@ -873,7 +874,6 @@ void LocalDataPoolManager::printWarningOrError(sif::OutputTypes outputType, } if(outputType == sif::OutputTypes::OUT_WARNING) { -#if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "LocalDataPoolManager::" << functionName << ": Object ID 0x" << std::setw(8) << std::setfill('0') From 6501c16fd796e9fd2bb2d67dae60319603ca3b53 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 10 Mar 2021 17:51:53 +0100 Subject: [PATCH 027/230] fixed preproc block --- datapoollocal/LocalDataPoolManager.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index f572dc02..5c702f1b 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -883,10 +883,8 @@ void LocalDataPoolManager::printWarningOrError(sif::OutputTypes outputType, sif::printWarning("LocalDataPoolManager::%s: Object ID 0x%08x | %s\n", functionName, owner->getObjectId(), errorPrint); #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ -#endif /* FSFW_VERBOSE_LEVEL >= 1 */ } else if(outputType == sif::OutputTypes::OUT_ERROR) { -#if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "LocalDataPoolManager::" << functionName << ": Object ID 0x" << std::setw(8) << std::setfill('0') @@ -896,8 +894,8 @@ void LocalDataPoolManager::printWarningOrError(sif::OutputTypes outputType, sif::printError("LocalDataPoolManager::%s: Object ID 0x%08x | %s\n", functionName, owner->getObjectId(), errorPrint); #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ -#endif /* FSFW_VERBOSE_LEVEL >= 1 */ } +#endif /* #if FSFW_VERBOSE_LEVEL >= 1 */ } LocalDataPoolManager* LocalDataPoolManager::getPoolManagerHandle() { From b2e4438811f19c72aa34cbead972bd8d33282ffa Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 10 Mar 2021 18:03:39 +0100 Subject: [PATCH 028/230] added some test, initial tick counter higher now --- housekeeping/PeriodicHousekeepingHelper.cpp | 3 +++ unittest/tests/datapoollocal/DataSetTest.cpp | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/housekeeping/PeriodicHousekeepingHelper.cpp b/housekeeping/PeriodicHousekeepingHelper.cpp index 365f0004..e7345677 100644 --- a/housekeeping/PeriodicHousekeepingHelper.cpp +++ b/housekeeping/PeriodicHousekeepingHelper.cpp @@ -16,6 +16,9 @@ void PeriodicHousekeepingHelper::initialize(float collectionInterval, nonDiagIntervalFactor; } collectionIntervalTicks = intervalSecondsToInterval(collectionInterval); + /* This will cause a checkOpNecessary call to be true immediately. I think it's okay + if a HK packet is generated immediately instead of waiting one generation cycle. */ + internalTickCounter = collectionIntervalTicks; } float PeriodicHousekeepingHelper::getCollectionIntervalInSeconds() { diff --git a/unittest/tests/datapoollocal/DataSetTest.cpp b/unittest/tests/datapoollocal/DataSetTest.cpp index eb587e3f..9b4509e9 100644 --- a/unittest/tests/datapoollocal/DataSetTest.cpp +++ b/unittest/tests/datapoollocal/DataSetTest.cpp @@ -80,6 +80,13 @@ TEST_CASE("DataSetTest" , "[DataSetTest]") { localSet.localPoolVarUint8 = 0; localSet.localPoolVarFloat = 0; + localSet.setAllVariablesReadOnly(); + CHECK(localSet.localPoolUint16Vec.getReadWriteMode() == pool_rwm_t::VAR_READ); + CHECK(localSet.localPoolVarUint8.getReadWriteMode() == pool_rwm_t::VAR_READ); + CHECK(localSet.localPoolVarFloat.getReadWriteMode() == pool_rwm_t::VAR_READ); + /* For code coverage */ + localSet.initializePeriodicHelper(0.0, 0.4, false); + { /* Now we read again and check whether our zeroed values were overwritten with the values in the pool */ From 3789663db7dac886393b2ad50437f63a86fba56e Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 10 Mar 2021 18:26:07 +0100 Subject: [PATCH 029/230] added some tests --- unittest/tests/datapoollocal/DataSetTest.cpp | 2 -- .../tests/datapoollocal/LocalPoolManagerTest.cpp | 16 ++++++++++++++++ .../tests/datapoollocal/LocalPoolOwnerBase.h | 6 +++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/unittest/tests/datapoollocal/DataSetTest.cpp b/unittest/tests/datapoollocal/DataSetTest.cpp index 9b4509e9..4def46be 100644 --- a/unittest/tests/datapoollocal/DataSetTest.cpp +++ b/unittest/tests/datapoollocal/DataSetTest.cpp @@ -84,8 +84,6 @@ TEST_CASE("DataSetTest" , "[DataSetTest]") { CHECK(localSet.localPoolUint16Vec.getReadWriteMode() == pool_rwm_t::VAR_READ); CHECK(localSet.localPoolVarUint8.getReadWriteMode() == pool_rwm_t::VAR_READ); CHECK(localSet.localPoolVarFloat.getReadWriteMode() == pool_rwm_t::VAR_READ); - /* For code coverage */ - localSet.initializePeriodicHelper(0.0, 0.4, false); { /* Now we read again and check whether our zeroed values were overwritten with diff --git a/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp b/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp index cd3be942..fd2c78d7 100644 --- a/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp +++ b/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp @@ -28,6 +28,10 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { SECTION("BasicTest") { + auto owner = poolOwner->poolManager.getOwner(); + REQUIRE(owner != nullptr); + CHECK(owner->getObjectId() == objects::TEST_LOCAL_POOL_OWNER_BASE); + /* Subscribe for message generation on update. */ REQUIRE(poolOwner->subscribeWrapperSetUpdate() == retval::CATCH_OK); /* Subscribe for an update message. */ @@ -190,6 +194,18 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { REQUIRE(mqMock->receiveMessage(&messageSent) == static_cast(MessageQueueIF::EMPTY)); } + SECTION("Periodic HK") { + /* Now we subcribe for a HK periodic generation. Even when it's difficult to simulate + the temporal behaviour correctly the HK manager should generate a HK packet + immediately and the periodic helper depends on HK op function calls anyway instead of + using the clock, so we could also just call performHkOperation multiple times */ + REQUIRE(poolOwner->subscribePeriodicHk() == retval::CATCH_OK); + REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK); + /* Now HK packet should be sent as message. */ + REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + CHECK(messagesSent == 1); + } + /* we need to reset the subscription list because the pool owner is a global object. */ CHECK(poolOwner->reset() == retval::CATCH_OK); diff --git a/unittest/tests/datapoollocal/LocalPoolOwnerBase.h b/unittest/tests/datapoollocal/LocalPoolOwnerBase.h index 8e6b07b0..58ca445c 100644 --- a/unittest/tests/datapoollocal/LocalPoolOwnerBase.h +++ b/unittest/tests/datapoollocal/LocalPoolOwnerBase.h @@ -130,7 +130,7 @@ public: } uint32_t getPeriodicOperationFrequency() const override { - return 0; + return 0.2; } /** @@ -169,6 +169,10 @@ public: return dynamic_cast(messageQueue); } + ReturnValue_t subscribePeriodicHk() { + return poolManager.subscribeForPeriodicPacket(lpool::testSid, true, 0.2, false); + } + ReturnValue_t subscribeWrapperSetUpdate() { return poolManager.subscribeForSetUpdateMessage(lpool::testSetId, objects::NO_OBJECT, objects::HK_RECEIVER_MOCK, false); From 03936fc5c1929dfc152fecb5d06949e1b84a7564 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 10 Mar 2021 19:15:05 +0100 Subject: [PATCH 030/230] snapshot test added, bugfix --- datapoollocal/LocalDataPoolManager.cpp | 21 +++++---- .../datapoollocal/LocalPoolManagerTest.cpp | 45 ++++++++++++++++++- .../tests/datapoollocal/LocalPoolOwnerBase.h | 5 +++ 3 files changed, 61 insertions(+), 10 deletions(-) diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index 5c702f1b..a9668a32 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -132,13 +132,16 @@ ReturnValue_t LocalDataPoolManager::performHkOperation() { ReturnValue_t LocalDataPoolManager::handleHkUpdate(HkReceiver& receiver, ReturnValue_t& status) { if(receiver.dataType == DataType::LOCAL_POOL_VARIABLE) { - // Update packets shall only be generated from datasets. + /* Update packets shall only be generated from datasets. */ return HasReturnvaluesIF::RETURN_FAILED; } LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, receiver.dataId.sid); + if(dataSet == nullptr) { + return DATASET_NOT_FOUND; + } if(dataSet->hasChanged()) { - // prepare and send update notification + /* Prepare and send update notification */ ReturnValue_t result = generateHousekeepingPacket( receiver.dataId.sid, dataSet, true); if(result != HasReturnvaluesIF::RETURN_OK) { @@ -328,7 +331,7 @@ void LocalDataPoolManager::handleChangeResetLogic( toReset->setChanged(false); } /* All recipients have been notified, reset the changed flag */ - if(changeInfo.currentUpdateCounter <= 1) { + else if(changeInfo.currentUpdateCounter <= 1) { toReset->setChanged(false); changeInfo.currentUpdateCounter = 0; } @@ -398,7 +401,6 @@ ReturnValue_t LocalDataPoolManager::subscribeForUpdatePacket(sid_t sid, hkReceiver.destinationQueue = hkReceiverObject->getHkQueue(); LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid); - //LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid); if(dataSet != nullptr) { LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, true); LocalPoolDataSetAttorney::setDiagnostic(*dataSet, isDiagnostics); @@ -616,7 +618,7 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid, LocalPoolDataSetBase* dataSet, bool forDownlink, MessageQueueId_t destination) { if(dataSet == nullptr) { - // Configuration error. + /* Configuration error. */ printWarningOrError(sif::OutputTypes::OUT_WARNING, "generateHousekeepingPacket", DATASET_NOT_FOUND); @@ -632,7 +634,7 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid, return result; } - // and now we set a HK message and send it the HK packet destination. + /* Now we set a HK message and send it the HK packet destination. */ CommandMessage hkMessage; if(LocalPoolDataSetAttorney::isDiagnostics(*dataSet)) { HousekeepingMessage::setHkDiagnosticsReply(&hkMessage, sid, storeId); @@ -642,7 +644,7 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid, } if(hkQueue == nullptr) { - // error, no queue available to send packet with. + /* Error, no queue available to send packet with. */ printWarningOrError(sif::OutputTypes::OUT_WARNING, "generateHousekeepingPacket", QUEUE_OR_DESTINATION_INVALID); @@ -650,7 +652,7 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid, } if(destination == MessageQueueIF::NO_QUEUE) { if(hkDestinationId == MessageQueueIF::NO_QUEUE) { - // error, all destinations invalid + /* Error, all destinations invalid */ printWarningOrError(sif::OutputTypes::OUT_WARNING, "generateHousekeepingPacket", QUEUE_OR_DESTINATION_INVALID); @@ -831,6 +833,9 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, void LocalDataPoolManager::clearReceiversList() { /* Clear the vector completely and releases allocated memory. */ HkReceivers().swap(hkReceivers); + if(hkUpdateResetList != nullptr) { + HkUpdateResetList().swap(*hkUpdateResetList); + } } MutexIF* LocalDataPoolManager::getLocalPoolMutex() { diff --git a/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp b/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp index fd2c78d7..685016ed 100644 --- a/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp +++ b/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp @@ -76,7 +76,7 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { } - SECTION("SnapshotUpdateTests") { + SECTION("SetSnapshotUpdateTest") { /* Set the variables in the set to certain values. These are checked later. */ { PoolReadGuard readHelper(&poolOwner->dataset); @@ -141,7 +141,31 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { CHECK(cdsShort.msDay_ll == Catch::Approx(timeCdsNow.msDay_ll).margin(1)); } - SECTION("AdvancedTests") { + SECTION("VariableSnapshotTest") { + /* Acquire subscription interface */ + ProvidesDataPoolSubscriptionIF* subscriptionIF = poolOwner->getSubscriptionInterface(); + REQUIRE(subscriptionIF != nullptr); + + /* Subscribe for variable snapshot */ + REQUIRE(poolOwner->subscribeWrapperVariableSnapshot(lpool::uint8VarId) == retval::CATCH_OK); + auto poolVar = dynamic_cast*>( + poolOwner->getPoolObjectHandle(lpool::uint8VarId)); + REQUIRE(poolVar != nullptr); + poolVar->setChanged(true); + REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK); + + /* Check update snapshot was sent. */ + REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + CHECK(messagesSent == 1); + + /* Should have been reset. */ + CHECK(poolVar->hasChanged() == false); + REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK); + CHECK(messageSent.getCommand() == static_cast( + HousekeepingMessage::UPDATE_SNAPSHOT_VARIABLE)); + } + + SECTION("VariableUpdateTest") { /* Acquire subscription interface */ ProvidesDataPoolSubscriptionIF* subscriptionIF = poolOwner->getSubscriptionInterface(); REQUIRE(subscriptionIF != nullptr); @@ -153,6 +177,7 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { poolOwner->getPoolObjectHandle(lpool::uint8VarId)); REQUIRE(poolVar != nullptr); poolVar->setChanged(true); + REQUIRE(poolVar->hasChanged() == true); REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK); /* Check update notification was sent. */ @@ -204,6 +229,22 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { /* Now HK packet should be sent as message. */ REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); + + LocalPoolDataSetBase* setHandle = poolOwner->getDataSetHandle(lpool::testSid); + REQUIRE(setHandle != nullptr); + CHECK(poolOwner->poolManager.generateHousekeepingPacket(lpool::testSid, + setHandle, false) == retval::CATCH_OK); + REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + CHECK(messagesSent == 1); + + CHECK(setHandle->getReportingEnabled() == true); + CommandMessage hkCmd; + HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, false); + CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); + CHECK(setHandle->getReportingEnabled() == false); + HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, true, false); + CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); + CHECK(setHandle->getReportingEnabled() == true); } /* we need to reset the subscription list because the pool owner diff --git a/unittest/tests/datapoollocal/LocalPoolOwnerBase.h b/unittest/tests/datapoollocal/LocalPoolOwnerBase.h index 58ca445c..f74c47b5 100644 --- a/unittest/tests/datapoollocal/LocalPoolOwnerBase.h +++ b/unittest/tests/datapoollocal/LocalPoolOwnerBase.h @@ -193,6 +193,11 @@ public: MessageQueueIF::NO_QUEUE, objects::HK_RECEIVER_MOCK, false); } + ReturnValue_t subscribeWrapperVariableSnapshot(lp_id_t localPoolId) { + return poolManager.subscribeForVariableUpdateMessage(localPoolId, + MessageQueueIF::NO_QUEUE, objects::HK_RECEIVER_MOCK, true); + } + ReturnValue_t reset() { resetSubscriptionList(); ReturnValue_t status = HasReturnvaluesIF::RETURN_OK; From 7ad8763b14f200768438d6118de85b7a7de38882 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 10 Mar 2021 19:18:52 +0100 Subject: [PATCH 031/230] added more nullptr checks --- datapoollocal/LocalDataPoolManager.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index a9668a32..9f0eb779 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -731,6 +731,12 @@ void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver& receiver) { ReturnValue_t LocalDataPoolManager::togglePeriodicGeneration(sid_t sid, bool enable, bool isDiagnostics) { LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid); + if(dataSet == nullptr) { + printWarningOrError(sif::OutputTypes::OUT_WARNING, "togglePeriodicGeneration", + DATASET_NOT_FOUND); + return DATASET_NOT_FOUND; + } + if((LocalPoolDataSetAttorney::isDiagnostics(*dataSet) and not isDiagnostics) or (not LocalPoolDataSetAttorney::isDiagnostics(*dataSet) and isDiagnostics)) { return WRONG_HK_PACKET_TYPE; @@ -748,6 +754,12 @@ ReturnValue_t LocalDataPoolManager::togglePeriodicGeneration(sid_t sid, ReturnValue_t LocalDataPoolManager::changeCollectionInterval(sid_t sid, float newCollectionInterval, bool isDiagnostics) { LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid); + if(dataSet == nullptr) { + printWarningOrError(sif::OutputTypes::OUT_WARNING, "changeCollectionInterval", + DATASET_NOT_FOUND); + return DATASET_NOT_FOUND; + } + bool targetIsDiagnostics = LocalPoolDataSetAttorney::isDiagnostics(*dataSet); if((targetIsDiagnostics and not isDiagnostics) or (not targetIsDiagnostics and isDiagnostics)) { @@ -768,13 +780,11 @@ ReturnValue_t LocalDataPoolManager::changeCollectionInterval(sid_t sid, ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, bool isDiagnostics) { - // Get and check dataset first. - //LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid); + /* Get and check dataset first. */ LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid); if(dataSet == nullptr) { printWarningOrError(sif::OutputTypes::OUT_WARNING, - "performPeriodicHkGeneration", - DATASET_NOT_FOUND); + "performPeriodicHkGeneration", DATASET_NOT_FOUND); return DATASET_NOT_FOUND; } @@ -833,6 +843,7 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, void LocalDataPoolManager::clearReceiversList() { /* Clear the vector completely and releases allocated memory. */ HkReceivers().swap(hkReceivers); + /* Also clear the reset helper if it exists */ if(hkUpdateResetList != nullptr) { HkUpdateResetList().swap(*hkUpdateResetList); } From 6c0972b2d5770d066f2b0666ad40a33caed364a8 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 10 Mar 2021 21:17:08 +0100 Subject: [PATCH 032/230] several bugfixes --- datapoollocal/HasLocalDataPoolIF.h | 2 +- datapoollocal/LocalDataPoolManager.cpp | 2 +- datapoollocal/LocalPoolDataSetBase.cpp | 9 ++ datapoollocal/LocalPoolDataSetBase.h | 8 ++ housekeeping/HousekeepingMessage.cpp | 10 +- housekeeping/PeriodicHousekeepingHelper.cpp | 94 +++++++++++++------ housekeeping/PeriodicHousekeepingHelper.h | 8 +- .../datapoollocal/LocalPoolManagerTest.cpp | 7 ++ .../tests/datapoollocal/LocalPoolOwnerBase.h | 4 +- 9 files changed, 106 insertions(+), 38 deletions(-) diff --git a/datapoollocal/HasLocalDataPoolIF.h b/datapoollocal/HasLocalDataPoolIF.h index d52c72b6..ec25f082 100644 --- a/datapoollocal/HasLocalDataPoolIF.h +++ b/datapoollocal/HasLocalDataPoolIF.h @@ -65,7 +65,7 @@ public: * usually be the period the pool owner performs its periodic operation. * @return */ - virtual uint32_t getPeriodicOperationFrequency() const = 0; + virtual dur_millis_t getPeriodicOperationFrequency() const = 0; /** * @brief This function will be called by the manager if an update diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index 9f0eb779..83e30e82 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -770,7 +770,7 @@ ReturnValue_t LocalDataPoolManager::changeCollectionInterval(sid_t sid, LocalPoolDataSetAttorney::getPeriodicHelper(*dataSet); if(periodicHelper == nullptr) { - // config error + /* Configuration error, set might not have a corresponding pool manager */ return PERIODIC_HELPER_INVALID; } diff --git a/datapoollocal/LocalPoolDataSetBase.cpp b/datapoollocal/LocalPoolDataSetBase.cpp index 2d70712b..3abbf0dd 100644 --- a/datapoollocal/LocalPoolDataSetBase.cpp +++ b/datapoollocal/LocalPoolDataSetBase.cpp @@ -308,3 +308,12 @@ void LocalPoolDataSetBase::setAllVariablesReadOnly() { registeredVariables[idx]->setReadWriteMode(pool_rwm_t::VAR_READ); } } + +float LocalPoolDataSetBase::getCollectionInterval() const { + if(periodicHelper != nullptr) { + return periodicHelper->getCollectionIntervalInSeconds(); + } + else { + return 0.0; + } +} diff --git a/datapoollocal/LocalPoolDataSetBase.h b/datapoollocal/LocalPoolDataSetBase.h index b9946aaf..39ea9f1a 100644 --- a/datapoollocal/LocalPoolDataSetBase.h +++ b/datapoollocal/LocalPoolDataSetBase.h @@ -168,6 +168,14 @@ public: bool getReportingEnabled() const; + /** + * Returns the current periodic HK generation interval this set + * belongs to a HK manager and the interval is not 0. Otherwise, + * returns 0.0 + * @return + */ + float getCollectionInterval() const; + protected: sid_t sid; //! This mutex is used if the data is created by one object only. diff --git a/housekeeping/HousekeepingMessage.cpp b/housekeeping/HousekeepingMessage.cpp index d9803ef6..58f8551d 100644 --- a/housekeeping/HousekeepingMessage.cpp +++ b/housekeeping/HousekeepingMessage.cpp @@ -84,15 +84,21 @@ void HousekeepingMessage::setCollectionIntervalModificationCommand( else { command->setCommand(MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL); } - command->setParameter3(collectionInterval); + + /* Raw storage of the float in the message. Do not use setParameter3, does + implicit conversion to integer type! */ + std::memcpy(command->getData() + 2 * sizeof(uint32_t), &collectionInterval, + sizeof(collectionInterval)); setSid(command, sid); } sid_t HousekeepingMessage::getCollectionIntervalModificationCommand( const CommandMessage* command, float* newCollectionInterval) { + if(newCollectionInterval != nullptr) { - *newCollectionInterval = command->getParameter3(); + std::memcpy(newCollectionInterval, command->getData() + 2 * sizeof(uint32_t), + sizeof(*newCollectionInterval)); } return getSid(command); diff --git a/housekeeping/PeriodicHousekeepingHelper.cpp b/housekeeping/PeriodicHousekeepingHelper.cpp index e7345677..b0dd8522 100644 --- a/housekeeping/PeriodicHousekeepingHelper.cpp +++ b/housekeeping/PeriodicHousekeepingHelper.cpp @@ -4,49 +4,85 @@ #include PeriodicHousekeepingHelper::PeriodicHousekeepingHelper( - LocalPoolDataSetBase* owner): owner(owner) {} + LocalPoolDataSetBase* owner): owner(owner) {} void PeriodicHousekeepingHelper::initialize(float collectionInterval, - dur_millis_t minimumPeriodicInterval, bool isDiagnostics, - uint8_t nonDiagIntervalFactor) { - this->minimumPeriodicInterval = minimumPeriodicInterval; - if(not isDiagnostics) { - this->minimumPeriodicInterval = this->minimumPeriodicInterval * - nonDiagIntervalFactor; - } - collectionIntervalTicks = intervalSecondsToInterval(collectionInterval); - /* This will cause a checkOpNecessary call to be true immediately. I think it's okay + dur_millis_t minimumPeriodicInterval, bool isDiagnostics, + uint8_t nonDiagIntervalFactor) { + this->isDiagnostics = isDiagnostics; + this->minimumPeriodicInterval = minimumPeriodicInterval; + this->nonDiagIntervalFactor = nonDiagIntervalFactor; + collectionIntervalTicks = intervalSecondsToIntervalTicks(collectionInterval); + /* This will cause a checkOpNecessary call to be true immediately. I think it's okay if a HK packet is generated immediately instead of waiting one generation cycle. */ - internalTickCounter = collectionIntervalTicks; + internalTickCounter = collectionIntervalTicks; } -float PeriodicHousekeepingHelper::getCollectionIntervalInSeconds() { - return intervalToIntervalSeconds(collectionIntervalTicks); +float PeriodicHousekeepingHelper::getCollectionIntervalInSeconds() const { + return intervalTicksToSeconds(collectionIntervalTicks); } bool PeriodicHousekeepingHelper::checkOpNecessary() { - if(internalTickCounter >= collectionIntervalTicks) { - internalTickCounter = 1; - return true; - } - internalTickCounter++; - return false; + if(internalTickCounter >= collectionIntervalTicks) { + internalTickCounter = 1; + return true; + } + internalTickCounter++; + return false; } -uint32_t PeriodicHousekeepingHelper::intervalSecondsToInterval( - float collectionIntervalSeconds) { - return std::ceil(collectionIntervalSeconds * 1000 - / minimumPeriodicInterval); +uint32_t PeriodicHousekeepingHelper::intervalSecondsToIntervalTicks( + float collectionIntervalSeconds) { + /* Avoid division by zero */ + if(minimumPeriodicInterval == 0) { + if(isDiagnostics) { + /* Perform operation each cycle */ + return 1; + } + else { + return nonDiagIntervalFactor; + } + } + else { + dur_millis_t intervalInMs = collectionIntervalSeconds * 1000; + uint32_t divisor = minimumPeriodicInterval; + if(not isDiagnostics) { + /* We need to multiply the divisor because non-diagnostics only + allow a multiple of the minimum periodic interval */ + divisor *= nonDiagIntervalFactor; + } + uint32_t ticks = std::ceil(static_cast(intervalInMs) / divisor); + if(not isDiagnostics) { + /* Now we need to multiply the calculated ticks with the factor as as well + because the minimum tick count to generate a non-diagnostic is + the factor. + + Example calculation for non-diagnostic with + 0.4 second interval and 0.2 second task interval. + Resultant tick count of 5 is equal to operation each second. + + Examle calculation for non-diagnostic with 2.0 second interval and 0.2 second + task interval. + Resultant tick count of 10 is equal to operatin every 2 seconds. + + Example calculation for diagnostic with 0.4 second interval and 0.3 + second task interval. Resulting tick count of 2 is equal to operation + every 0.6 seconds. */ + ticks *= nonDiagIntervalFactor; + } + return ticks; + } } -float PeriodicHousekeepingHelper::intervalToIntervalSeconds( - uint32_t collectionInterval) { - return static_cast(collectionInterval * - minimumPeriodicInterval); +float PeriodicHousekeepingHelper::intervalTicksToSeconds( + uint32_t collectionInterval) const { + /* Number of ticks times the minimum interval is in milliseconds, so we divide by 1000 to get + the value in seconds */ + return static_cast(collectionInterval * minimumPeriodicInterval / 1000.0); } void PeriodicHousekeepingHelper::changeCollectionInterval( - float newIntervalSeconds) { - collectionIntervalTicks = intervalSecondsToInterval(newIntervalSeconds); + float newIntervalSeconds) { + collectionIntervalTicks = intervalSecondsToIntervalTicks(newIntervalSeconds); } diff --git a/housekeeping/PeriodicHousekeepingHelper.h b/housekeeping/PeriodicHousekeepingHelper.h index d96eae1d..3e8d030e 100644 --- a/housekeeping/PeriodicHousekeepingHelper.h +++ b/housekeeping/PeriodicHousekeepingHelper.h @@ -15,13 +15,15 @@ public: uint8_t nonDiagIntervalFactor); void changeCollectionInterval(float newInterval); - float getCollectionIntervalInSeconds(); + float getCollectionIntervalInSeconds() const; bool checkOpNecessary(); private: LocalPoolDataSetBase* owner = nullptr; + bool isDiagnostics = true; + uint8_t nonDiagIntervalFactor = 0; - uint32_t intervalSecondsToInterval(float collectionIntervalSeconds); - float intervalToIntervalSeconds(uint32_t collectionInterval); + uint32_t intervalSecondsToIntervalTicks(float collectionIntervalSeconds); + float intervalTicksToSeconds(uint32_t collectionInterval) const; dur_millis_t minimumPeriodicInterval = 0; uint32_t internalTickCounter = 1; diff --git a/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp b/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp index 685016ed..1ab87151 100644 --- a/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp +++ b/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp @@ -245,6 +245,13 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, true, false); CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); CHECK(setHandle->getReportingEnabled() == true); + + HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, + lpool::testSid, 0.4, false); + CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); + /* For non-diagnostics and a specified minimum frequency of 0.2 seconds, the + resulting collection interval should be 1.0 second */ + CHECK(poolOwner->dataset.getCollectionInterval() == 1.0); } /* we need to reset the subscription list because the pool owner diff --git a/unittest/tests/datapoollocal/LocalPoolOwnerBase.h b/unittest/tests/datapoollocal/LocalPoolOwnerBase.h index f74c47b5..20c565ff 100644 --- a/unittest/tests/datapoollocal/LocalPoolOwnerBase.h +++ b/unittest/tests/datapoollocal/LocalPoolOwnerBase.h @@ -129,8 +129,8 @@ public: return &poolManager; } - uint32_t getPeriodicOperationFrequency() const override { - return 0.2; + dur_millis_t getPeriodicOperationFrequency() const override { + return 200; } /** From c59fa578c7aa7aabaf5aa58782c4bf425a226cdf Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 10 Mar 2021 21:18:47 +0100 Subject: [PATCH 033/230] format improvements --- housekeeping/PeriodicHousekeepingHelper.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/housekeeping/PeriodicHousekeepingHelper.cpp b/housekeeping/PeriodicHousekeepingHelper.cpp index b0dd8522..5152706f 100644 --- a/housekeeping/PeriodicHousekeepingHelper.cpp +++ b/housekeeping/PeriodicHousekeepingHelper.cpp @@ -55,8 +55,7 @@ uint32_t PeriodicHousekeepingHelper::intervalSecondsToIntervalTicks( uint32_t ticks = std::ceil(static_cast(intervalInMs) / divisor); if(not isDiagnostics) { /* Now we need to multiply the calculated ticks with the factor as as well - because the minimum tick count to generate a non-diagnostic is - the factor. + because the minimum tick count to generate a non-diagnostic is the factor itself. Example calculation for non-diagnostic with 0.4 second interval and 0.2 second task interval. From 4f89fc62abfc5587dd84ebde3e2d040f5cbd0ecf Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 10 Mar 2021 21:38:13 +0100 Subject: [PATCH 034/230] continued tests --- .../datapoollocal/LocalPoolManagerTest.cpp | 30 +++++++++++++++++-- .../tests/datapoollocal/LocalPoolOwnerBase.h | 4 +-- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp b/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp index 1ab87151..4457e85b 100644 --- a/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp +++ b/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp @@ -219,14 +219,14 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { REQUIRE(mqMock->receiveMessage(&messageSent) == static_cast(MessageQueueIF::EMPTY)); } - SECTION("Periodic HK") { + SECTION("PeriodicHKAndMessaging") { /* Now we subcribe for a HK periodic generation. Even when it's difficult to simulate the temporal behaviour correctly the HK manager should generate a HK packet immediately and the periodic helper depends on HK op function calls anyway instead of using the clock, so we could also just call performHkOperation multiple times */ - REQUIRE(poolOwner->subscribePeriodicHk() == retval::CATCH_OK); + REQUIRE(poolOwner->subscribePeriodicHk(true) == retval::CATCH_OK); REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK); - /* Now HK packet should be sent as message. */ + /* Now HK packet should be sent as message immediately. */ REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); @@ -242,9 +242,19 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, false); CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); CHECK(setHandle->getReportingEnabled() == false); + REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + CHECK(messagesSent == 1); HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, true, false); CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); CHECK(setHandle->getReportingEnabled() == true); + REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + CHECK(messagesSent == 1); + + HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, false); + CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); + CHECK(setHandle->getReportingEnabled() == false); + REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + CHECK(messagesSent == 1); HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid, 0.4, false); @@ -252,6 +262,20 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { /* For non-diagnostics and a specified minimum frequency of 0.2 seconds, the resulting collection interval should be 1.0 second */ CHECK(poolOwner->dataset.getCollectionInterval() == 1.0); + REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + CHECK(messagesSent == 1); + + HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, false); + REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK); + CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); + /* Now HK packet should be sent as message. */ + REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + CHECK(messagesSent == 1); + + HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, false); + CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); + REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + CHECK(messagesSent == 1); } /* we need to reset the subscription list because the pool owner diff --git a/unittest/tests/datapoollocal/LocalPoolOwnerBase.h b/unittest/tests/datapoollocal/LocalPoolOwnerBase.h index 20c565ff..eb6d8a5d 100644 --- a/unittest/tests/datapoollocal/LocalPoolOwnerBase.h +++ b/unittest/tests/datapoollocal/LocalPoolOwnerBase.h @@ -169,8 +169,8 @@ public: return dynamic_cast(messageQueue); } - ReturnValue_t subscribePeriodicHk() { - return poolManager.subscribeForPeriodicPacket(lpool::testSid, true, 0.2, false); + ReturnValue_t subscribePeriodicHk(bool enableReporting) { + return poolManager.subscribeForPeriodicPacket(lpool::testSid, enableReporting, 0.2, false); } ReturnValue_t subscribeWrapperSetUpdate() { From dcde177fe38fc29ea6d02cf6024f31b7f8dcf7ba Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 10 Mar 2021 22:08:05 +0100 Subject: [PATCH 035/230] added additional tests for more than 8 variables --- unittest/tests/datapoollocal/DataSetTest.cpp | 45 ++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/unittest/tests/datapoollocal/DataSetTest.cpp b/unittest/tests/datapoollocal/DataSetTest.cpp index 4def46be..c11c66c2 100644 --- a/unittest/tests/datapoollocal/DataSetTest.cpp +++ b/unittest/tests/datapoollocal/DataSetTest.cpp @@ -207,6 +207,51 @@ TEST_CASE("DataSetTest" , "[DataSetTest]") { } + SECTION("MorePoolVariables") { + LocalDataSet set(poolOwner, 2, 10); + + /* Register same variables again to get more than 8 registered variables */ + for(uint8_t idx = 0; idx < 8; idx ++) { + REQUIRE(set.registerVariable(&localSet.localPoolVarUint8) == retval::CATCH_OK); + } + REQUIRE(set.registerVariable(&localSet.localPoolVarUint8) == retval::CATCH_OK); + REQUIRE(set.registerVariable(&localSet.localPoolUint16Vec) == retval::CATCH_OK); + + set.setValidityBufferGeneration(true); + { + PoolReadGuard readHelper(&localSet); + localSet.localPoolVarUint8.value = 42; + localSet.localPoolVarUint8.setValid(true); + localSet.localPoolUint16Vec.setValid(false); + } + + size_t maxSize = set.getSerializedSize(); + CHECK(maxSize == 9 + sizeof(uint16_t) * 3 + 2); + size_t serSize = 0; + /* Already reserve additional space for validity buffer, will be needed later */ + uint8_t buffer[maxSize + 1]; + uint8_t* buffPtr = buffer; + CHECK(set.serialize(&buffPtr, &serSize, maxSize, + SerializeIF::Endianness::MACHINE) == retval::CATCH_OK); + std::array validityBuffer; + std::memcpy(validityBuffer.data(), buffer + 9 + sizeof(uint16_t) * 3, 2); + /* The first 9 variables should be valid */ + CHECK(validityBuffer[0] == 0xff); + CHECK(bitutil::bitGet(validityBuffer.data() + 1, 0) == true); + CHECK(bitutil::bitGet(validityBuffer.data() + 1, 1) == false); + + /* Now we invert the validity */ + validityBuffer[0] = 0; + validityBuffer[1] = 0b0100'0000; + std::memcpy(buffer + 9 + sizeof(uint16_t) * 3, validityBuffer.data(), 2); + const uint8_t* constBuffPtr = buffer; + size_t sizeToDeSerialize = serSize; + CHECK(set.deSerialize(&constBuffPtr, &sizeToDeSerialize, SerializeIF::Endianness::MACHINE) + == retval::CATCH_OK); + CHECK(localSet.localPoolVarUint8.isValid() == false); + CHECK(localSet.localPoolUint16Vec.isValid() == true); + } + /* we need to reset the subscription list because the pool owner is a global object. */ CHECK(poolOwner->reset() == retval::CATCH_OK); From 8d28bc4b6addfb9d48279ad5cf1e44d56fe1cab2 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 10 Mar 2021 22:19:55 +0100 Subject: [PATCH 036/230] added source file --- unittest/tests/datapoollocal/CMakeLists.txt | 1 + .../datapoollocal/LocalPoolManagerTest.cpp | 2 + .../datapoollocal/LocalPoolOwnerBase.cpp | 91 ++++++++++++++++ .../tests/datapoollocal/LocalPoolOwnerBase.h | 101 +++--------------- 4 files changed, 108 insertions(+), 87 deletions(-) create mode 100644 unittest/tests/datapoollocal/LocalPoolOwnerBase.cpp diff --git a/unittest/tests/datapoollocal/CMakeLists.txt b/unittest/tests/datapoollocal/CMakeLists.txt index f196a080..1c98e7dc 100644 --- a/unittest/tests/datapoollocal/CMakeLists.txt +++ b/unittest/tests/datapoollocal/CMakeLists.txt @@ -3,4 +3,5 @@ target_sources(${TARGET_NAME} PRIVATE LocalPoolVectorTest.cpp DataSetTest.cpp LocalPoolManagerTest.cpp + LocalPoolOwnerBase.cpp ) diff --git a/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp b/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp index 4457e85b..cce55e1a 100644 --- a/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp +++ b/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp @@ -276,6 +276,8 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); + + HousekeepingMessage::setUpdateNotificationSetCommand(&hkCmd, lpool::testSid); } /* we need to reset the subscription list because the pool owner diff --git a/unittest/tests/datapoollocal/LocalPoolOwnerBase.cpp b/unittest/tests/datapoollocal/LocalPoolOwnerBase.cpp new file mode 100644 index 00000000..7abbd454 --- /dev/null +++ b/unittest/tests/datapoollocal/LocalPoolOwnerBase.cpp @@ -0,0 +1,91 @@ +#include "LocalPoolOwnerBase.h" + +LocalPoolOwnerBase::LocalPoolOwnerBase(object_id_t objectId): + SystemObject(objectId), poolManager(this, messageQueue), + dataset(this, lpool::testSetId) { + messageQueue = new MessageQueueMockBase(); +} + +ReturnValue_t LocalPoolOwnerBase::initializeHkManager() { + if(not initialized) { + initialized = true; + return poolManager.initialize(messageQueue); + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t LocalPoolOwnerBase::initializeLocalDataPool(localpool::DataPool &localDataPoolMap, + LocalDataPoolManager &poolManager) { + + // Default initialization empty for now. + localDataPoolMap.emplace(lpool::uint8VarId, + new PoolEntry({0})); + localDataPoolMap.emplace(lpool::floatVarId, + new PoolEntry({0})); + localDataPoolMap.emplace(lpool::uint32VarId, + new PoolEntry({0})); + + localDataPoolMap.emplace(lpool::uint16Vec3Id, + new PoolEntry({0, 0, 0})); + localDataPoolMap.emplace(lpool::int64Vec2Id, + new PoolEntry({0, 0})); + return HasReturnvaluesIF::RETURN_OK; +} + +LocalPoolObjectBase* LocalPoolOwnerBase::getPoolObjectHandle(lp_id_t localPoolId) { + if(localPoolId == lpool::uint8VarId) { + return &testUint8; + } + else if(localPoolId == lpool::uint16Vec3Id) { + return &testUint16Vec; + } + else if(localPoolId == lpool::floatVarId) { + return &testFloat; + } + else if(localPoolId == lpool::int64Vec2Id) { + return &testInt64Vec; + } + else if(localPoolId == lpool::uint32VarId) { + return &testUint32; + } + else { + return &testUint8; + } +} + +ReturnValue_t LocalPoolOwnerBase::reset() { + resetSubscriptionList(); + ReturnValue_t status = HasReturnvaluesIF::RETURN_OK; + { + PoolReadGuard readHelper(&dataset); + if(readHelper.getReadResult() != HasReturnvaluesIF::RETURN_OK) { + status = readHelper.getReadResult(); + } + dataset.localPoolVarUint8.value = 0; + dataset.localPoolVarFloat.value = 0.0; + dataset.localPoolUint16Vec.value[0] = 0; + dataset.localPoolUint16Vec.value[1] = 0; + dataset.localPoolUint16Vec.value[2] = 0; + dataset.setValidity(false, true); + } + + { + PoolReadGuard readHelper(&testUint32); + if(readHelper.getReadResult() != HasReturnvaluesIF::RETURN_OK) { + status = readHelper.getReadResult(); + } + testUint32.value = 0; + testUint32.setValid(false); + } + + { + PoolReadGuard readHelper(&testInt64Vec); + if(readHelper.getReadResult() != HasReturnvaluesIF::RETURN_OK) { + status = readHelper.getReadResult(); + } + testInt64Vec.value[0] = 0; + testInt64Vec.value[1] = 0; + testInt64Vec.setValid(false); + } + return status; +} diff --git a/unittest/tests/datapoollocal/LocalPoolOwnerBase.h b/unittest/tests/datapoollocal/LocalPoolOwnerBase.h index eb6d8a5d..fc009544 100644 --- a/unittest/tests/datapoollocal/LocalPoolOwnerBase.h +++ b/unittest/tests/datapoollocal/LocalPoolOwnerBase.h @@ -70,12 +70,7 @@ private: class LocalPoolOwnerBase: public SystemObject, public HasLocalDataPoolIF { public: - LocalPoolOwnerBase( - object_id_t objectId = objects::TEST_LOCAL_POOL_OWNER_BASE): - SystemObject(objectId), poolManager(this, messageQueue), - dataset(this, lpool::testSetId) { - messageQueue = new MessageQueueMockBase(); - } + LocalPoolOwnerBase(object_id_t objectId = objects::TEST_LOCAL_POOL_OWNER_BASE); ~LocalPoolOwnerBase() { QueueFactory::instance()->deleteMessageQueue(messageQueue); @@ -85,13 +80,7 @@ public: return SystemObject::getObjectId(); } - ReturnValue_t initializeHkManager() { - if(not initialized) { - initialized = true; - return poolManager.initialize(messageQueue); - } - return HasReturnvaluesIF::RETURN_OK; - } + ReturnValue_t initializeHkManager(); ReturnValue_t initializeHkManagerAfterTaskCreation() { if(not initializedAfterTaskCreation) { @@ -107,23 +96,8 @@ public: } // This is called by initializeAfterTaskCreation of the HK manager. - virtual ReturnValue_t initializeLocalDataPool( - localpool::DataPool& localDataPoolMap, - LocalDataPoolManager& poolManager) { - // Default initialization empty for now. - localDataPoolMap.emplace(lpool::uint8VarId, - new PoolEntry({0})); - localDataPoolMap.emplace(lpool::floatVarId, - new PoolEntry({0})); - localDataPoolMap.emplace(lpool::uint32VarId, - new PoolEntry({0})); - - localDataPoolMap.emplace(lpool::uint16Vec3Id, - new PoolEntry({0, 0, 0})); - localDataPoolMap.emplace(lpool::int64Vec2Id, - new PoolEntry({0, 0})); - return HasReturnvaluesIF::RETURN_OK; - } + virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, + LocalDataPoolManager& poolManager) override; LocalDataPoolManager* getHkManagerHandle() override { return &poolManager; @@ -143,27 +117,7 @@ public: return &dataset; } - virtual LocalPoolObjectBase* getPoolObjectHandle( - lp_id_t localPoolId) override { - if(localPoolId == lpool::uint8VarId) { - return &testUint8; - } - else if(localPoolId == lpool::uint16Vec3Id) { - return &testUint16Vec; - } - else if(localPoolId == lpool::floatVarId) { - return &testFloat; - } - else if(localPoolId == lpool::int64Vec2Id) { - return &testInt64Vec; - } - else if(localPoolId == lpool::uint32VarId) { - return &testUint32; - } - else { - return &testUint8; - } - } + virtual LocalPoolObjectBase* getPoolObjectHandle(lp_id_t localPoolId) override; MessageQueueMockBase* getMockQueueHandle() const { return dynamic_cast(messageQueue); @@ -198,51 +152,24 @@ public: MessageQueueIF::NO_QUEUE, objects::HK_RECEIVER_MOCK, true); } - ReturnValue_t reset() { - resetSubscriptionList(); - ReturnValue_t status = HasReturnvaluesIF::RETURN_OK; - { - PoolReadGuard readHelper(&dataset); - if(readHelper.getReadResult() != HasReturnvaluesIF::RETURN_OK) { - status = readHelper.getReadResult(); - } - dataset.localPoolVarUint8.value = 0; - dataset.localPoolVarFloat.value = 0.0; - dataset.localPoolUint16Vec.value[0] = 0; - dataset.localPoolUint16Vec.value[1] = 0; - dataset.localPoolUint16Vec.value[2] = 0; - dataset.setValidity(false, true); - } - - { - PoolReadGuard readHelper(&testUint32); - if(readHelper.getReadResult() != HasReturnvaluesIF::RETURN_OK) { - status = readHelper.getReadResult(); - } - testUint32.value = 0; - testUint32.setValid(false); - } - - { - PoolReadGuard readHelper(&testInt64Vec); - if(readHelper.getReadResult() != HasReturnvaluesIF::RETURN_OK) { - status = readHelper.getReadResult(); - } - testInt64Vec.value[0] = 0; - testInt64Vec.value[1] = 0; - testInt64Vec.setValid(false); - } - return status; - } + ReturnValue_t reset(); void resetSubscriptionList() { poolManager.clearReceiversList(); } + void handleChangedDataset(sid_t sid, store_address_t storeId) { + this->thisSidHasChanged = sid; + this->storeIdForChangedSid = storeId; + } + LocalDataPoolManager poolManager; LocalPoolTestDataSet dataset; private: + sid_t thisSidHasChanged; + store_address_t storeIdForChangedSid; + lp_var_t testUint8 = lp_var_t(this, lpool::uint8VarId); lp_var_t testFloat = lp_var_t(this, lpool::floatVarId); lp_var_t testUint32 = lp_var_t(this, lpool::uint32VarId); From 620b2ae79e551b110e37f45f8e9123100b326a89 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 10 Mar 2021 23:16:47 +0100 Subject: [PATCH 037/230] weird bug --- datapoollocal/SharedLocalDataSet.cpp | 13 ++++++ datapoollocal/SharedLocalDataSet.h | 9 +++- unittest/tests/datapoollocal/DataSetTest.cpp | 6 +++ .../datapoollocal/LocalPoolManagerTest.cpp | 5 +++ .../datapoollocal/LocalPoolOwnerBase.cpp | 43 +++++++++++++++++++ .../tests/datapoollocal/LocalPoolOwnerBase.h | 23 +++++----- 6 files changed, 84 insertions(+), 15 deletions(-) diff --git a/datapoollocal/SharedLocalDataSet.cpp b/datapoollocal/SharedLocalDataSet.cpp index dd1bdcc4..9915628e 100644 --- a/datapoollocal/SharedLocalDataSet.cpp +++ b/datapoollocal/SharedLocalDataSet.cpp @@ -1,5 +1,6 @@ #include "SharedLocalDataSet.h" + SharedLocalDataSet::SharedLocalDataSet(object_id_t objectId, sid_t sid, const size_t maxSize): SystemObject(objectId), LocalPoolDataSetBase(sid, nullptr, maxSize) { @@ -11,6 +12,18 @@ ReturnValue_t SharedLocalDataSet::lockDataset(dur_millis_t mutexTimeout) { return datasetLock->lockMutex(MutexIF::TimeoutType::WAITING, mutexTimeout); } +SharedLocalDataSet::SharedLocalDataSet(object_id_t objectId, + HasLocalDataPoolIF *owner, uint32_t setId, + const size_t maxSize): SystemObject(objectId), + LocalPoolDataSetBase(owner, setId, nullptr, maxSize) { + this->setContainer(poolVarVector.data()); + datasetLock = MutexFactory::instance()->createMutex(); +} + +SharedLocalDataSet::~SharedLocalDataSet() { + MutexFactory::instance()->deleteMutex(datasetLock); +} + ReturnValue_t SharedLocalDataSet::unlockDataset() { return datasetLock->unlockMutex(); } diff --git a/datapoollocal/SharedLocalDataSet.h b/datapoollocal/SharedLocalDataSet.h index 83f2a72f..bbb47da4 100644 --- a/datapoollocal/SharedLocalDataSet.h +++ b/datapoollocal/SharedLocalDataSet.h @@ -11,15 +11,20 @@ * multiple threads. It provides a lock in addition to all other functionalities provided * by the LocalPoolDataSetBase class. * - * TODO: override and protect read, commit and some other calls used by pool manager. + * The user is completely responsible for lockingand unlocking the dataset when using the + * shared dataset. */ class SharedLocalDataSet: public SystemObject, public LocalPoolDataSetBase, public SharedDataSetIF { public: - SharedLocalDataSet(object_id_t objectId, sid_t sid, + SharedLocalDataSet(object_id_t objectId, HasLocalDataPoolIF* owner, uint32_t setId, const size_t maxSize); + SharedLocalDataSet(object_id_t objectId, sid_t sid, const size_t maxSize); + + virtual~ SharedLocalDataSet(); + ReturnValue_t lockDataset(dur_millis_t mutexTimeout) override; ReturnValue_t unlockDataset() override; private: diff --git a/unittest/tests/datapoollocal/DataSetTest.cpp b/unittest/tests/datapoollocal/DataSetTest.cpp index c11c66c2..30b5bb05 100644 --- a/unittest/tests/datapoollocal/DataSetTest.cpp +++ b/unittest/tests/datapoollocal/DataSetTest.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -252,6 +253,11 @@ TEST_CASE("DataSetTest" , "[DataSetTest]") { CHECK(localSet.localPoolUint16Vec.isValid() == true); } + SECTION("SharedDataSet") { + object_id_t sharedSetId = objects::SHARED_SET_ID; + SharedLocalDataSet sharedSet(sharedSetId, poolOwner, 2, 5); + } + /* we need to reset the subscription list because the pool owner is a global object. */ CHECK(poolOwner->reset() == retval::CATCH_OK); diff --git a/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp b/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp index cce55e1a..2d7294ef 100644 --- a/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp +++ b/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp @@ -278,6 +278,11 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { CHECK(messagesSent == 1); HousekeepingMessage::setUpdateNotificationSetCommand(&hkCmd, lpool::testSid); + sid_t sidToCheck; + store_address_t storeId; + CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); + CHECK(poolOwner->changedDataSetCallbackWasCalled(sidToCheck, storeId) == true); + CHECK(sidToCheck == lpool::testSid); } /* we need to reset the subscription list because the pool owner diff --git a/unittest/tests/datapoollocal/LocalPoolOwnerBase.cpp b/unittest/tests/datapoollocal/LocalPoolOwnerBase.cpp index 7abbd454..0e2703a7 100644 --- a/unittest/tests/datapoollocal/LocalPoolOwnerBase.cpp +++ b/unittest/tests/datapoollocal/LocalPoolOwnerBase.cpp @@ -89,3 +89,46 @@ ReturnValue_t LocalPoolOwnerBase::reset() { } return status; } + +bool LocalPoolOwnerBase::changedDataSetCallbackWasCalled(sid_t &sid, store_address_t &storeId) { + bool condition = false; + if(not this->changedDatasetSid.notSet()) { + condition = true; + } + sid = changedDatasetSid; + storeId = storeIdForChangedSet; + this->changedDatasetSid.raw = sid_t::INVALID_SID; + this->storeIdForChangedSet = storeId::INVALID_STORE_ADDRESS; + return condition; +} + +void LocalPoolOwnerBase::handleChangedDataset(sid_t sid, store_address_t storeId) { + this->changedDatasetSid = sid; + this->storeIdForChangedSet = storeId; +} + +bool LocalPoolOwnerBase::changedVariableCallbackWasCalled(gp_id_t &gpid, store_address_t &storeId) { + bool condition = false; + if(not this->changedPoolVariableGpid.notSet()) { + condition = true; + } + gpid = changedPoolVariableGpid; + storeId = storeIdForChangedVariable; + this->changedPoolVariableGpid.raw = gp_id_t::INVALID_GPID; + this->storeIdForChangedVariable = storeId::INVALID_STORE_ADDRESS; + return condition; +} + +ReturnValue_t LocalPoolOwnerBase::initializeHkManagerAfterTaskCreation() { + if(not initializedAfterTaskCreation) { + initializedAfterTaskCreation = true; + return poolManager.initializeAfterTaskCreation(); + } + return HasReturnvaluesIF::RETURN_OK; + +} + +void LocalPoolOwnerBase::handleChangedPoolVariable(gp_id_t globPoolId, store_address_t storeId) { + this->changedPoolVariableGpid = globPoolId; + this->storeIdForChangedVariable = storeId; +} diff --git a/unittest/tests/datapoollocal/LocalPoolOwnerBase.h b/unittest/tests/datapoollocal/LocalPoolOwnerBase.h index fc009544..7915eeb4 100644 --- a/unittest/tests/datapoollocal/LocalPoolOwnerBase.h +++ b/unittest/tests/datapoollocal/LocalPoolOwnerBase.h @@ -82,13 +82,7 @@ public: ReturnValue_t initializeHkManager(); - ReturnValue_t initializeHkManagerAfterTaskCreation() { - if(not initializedAfterTaskCreation) { - initializedAfterTaskCreation = true; - return poolManager.initializeAfterTaskCreation(); - } - return HasReturnvaluesIF::RETURN_OK; - } + ReturnValue_t initializeHkManagerAfterTaskCreation(); /** Command queue for housekeeping messages. */ MessageQueueId_t getCommandQueue() const override { @@ -158,17 +152,20 @@ public: poolManager.clearReceiversList(); } - void handleChangedDataset(sid_t sid, store_address_t storeId) { - this->thisSidHasChanged = sid; - this->storeIdForChangedSid = storeId; - } + bool changedDataSetCallbackWasCalled(sid_t& sid, store_address_t& storeId); + bool changedVariableCallbackWasCalled(gp_id_t& gpid, store_address_t& storeId); LocalDataPoolManager poolManager; LocalPoolTestDataSet dataset; private: - sid_t thisSidHasChanged; - store_address_t storeIdForChangedSid; + void handleChangedDataset(sid_t sid, store_address_t storeId) override; + sid_t changedDatasetSid; + store_address_t storeIdForChangedSet; + + void handleChangedPoolVariable(gp_id_t globPoolId, store_address_t storeId) override; + gp_id_t changedPoolVariableGpid; + store_address_t storeIdForChangedVariable; lp_var_t testUint8 = lp_var_t(this, lpool::uint8VarId); lp_var_t testFloat = lp_var_t(this, lpool::floatVarId); From 78b6a83285df57f1df6354a474cf774d45e30d9b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 11 Mar 2021 00:18:17 +0100 Subject: [PATCH 038/230] issues with virtual inheritanc3 --- datapool/PoolDataSetBase.cpp | 3 +-- datapool/SharedDataSetIF.h | 7 +++++-- datapoollocal/LocalPoolDataSetBase.cpp | 2 +- datapoollocal/SharedLocalDataSet.cpp | 18 +++++++++++++----- datapoollocal/SharedLocalDataSet.h | 3 ++- unittest/tests/datapoollocal/DataSetTest.cpp | 10 +++++++--- .../tests/datapoollocal/LocalPoolOwnerBase.h | 4 ++-- 7 files changed, 31 insertions(+), 16 deletions(-) diff --git a/datapool/PoolDataSetBase.cpp b/datapool/PoolDataSetBase.cpp index bdca22c3..73ec4bd7 100644 --- a/datapool/PoolDataSetBase.cpp +++ b/datapool/PoolDataSetBase.cpp @@ -8,8 +8,7 @@ PoolDataSetBase::PoolDataSetBase(PoolVariableIF** registeredVariablesArray, const size_t maxFillCount): registeredVariables(registeredVariablesArray), - maxFillCount(maxFillCount) { -} + maxFillCount(maxFillCount) {} PoolDataSetBase::~PoolDataSetBase() {} diff --git a/datapool/SharedDataSetIF.h b/datapool/SharedDataSetIF.h index b8d98794..da21f9cf 100644 --- a/datapool/SharedDataSetIF.h +++ b/datapool/SharedDataSetIF.h @@ -1,13 +1,16 @@ #ifndef FRAMEWORK_DATAPOOL_SHAREDDATASETIF_H_ #define FRAMEWORK_DATAPOOL_SHAREDDATASETIF_H_ + #include "PoolDataSetIF.h" -class SharedDataSetIF: public PoolDataSetIF { +class SharedDataSetIF: + public PoolDataSetIF { public: virtual ~SharedDataSetIF() {}; private: - virtual ReturnValue_t lockDataset(dur_millis_t mutexTimeout) = 0; + virtual ReturnValue_t lockDataset(MutexIF::TimeoutType timeoutType, + dur_millis_t mutexTimeout) = 0; virtual ReturnValue_t unlockDataset() = 0; }; diff --git a/datapoollocal/LocalPoolDataSetBase.cpp b/datapoollocal/LocalPoolDataSetBase.cpp index 3abbf0dd..d93b926d 100644 --- a/datapoollocal/LocalPoolDataSetBase.cpp +++ b/datapoollocal/LocalPoolDataSetBase.cpp @@ -44,7 +44,7 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner, LocalPoolDataSetBase::LocalPoolDataSetBase(sid_t sid, PoolVariableIF** registeredVariablesArray, const size_t maxNumberOfVariables): - PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) { + PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) { HasLocalDataPoolIF* hkOwner = objectManager->get( sid.objectId); if(hkOwner != nullptr) { diff --git a/datapoollocal/SharedLocalDataSet.cpp b/datapoollocal/SharedLocalDataSet.cpp index 9915628e..abcf7da9 100644 --- a/datapoollocal/SharedLocalDataSet.cpp +++ b/datapoollocal/SharedLocalDataSet.cpp @@ -8,10 +8,6 @@ SharedLocalDataSet::SharedLocalDataSet(object_id_t objectId, sid_t sid, datasetLock = MutexFactory::instance()->createMutex(); } -ReturnValue_t SharedLocalDataSet::lockDataset(dur_millis_t mutexTimeout) { - return datasetLock->lockMutex(MutexIF::TimeoutType::WAITING, mutexTimeout); -} - SharedLocalDataSet::SharedLocalDataSet(object_id_t objectId, HasLocalDataPoolIF *owner, uint32_t setId, const size_t maxSize): SystemObject(objectId), @@ -20,10 +16,22 @@ SharedLocalDataSet::SharedLocalDataSet(object_id_t objectId, datasetLock = MutexFactory::instance()->createMutex(); } +ReturnValue_t SharedLocalDataSet::lockDataset(MutexIF::TimeoutType timeoutType, + dur_millis_t mutexTimeout) { + if(datasetLock != nullptr) { + return datasetLock->lockMutex(timeoutType, mutexTimeout); + } + return HasReturnvaluesIF::RETURN_FAILED; +} + + SharedLocalDataSet::~SharedLocalDataSet() { MutexFactory::instance()->deleteMutex(datasetLock); } ReturnValue_t SharedLocalDataSet::unlockDataset() { - return datasetLock->unlockMutex(); + if(datasetLock != nullptr) { + return datasetLock->unlockMutex(); + } + return HasReturnvaluesIF::RETURN_FAILED; } diff --git a/datapoollocal/SharedLocalDataSet.h b/datapoollocal/SharedLocalDataSet.h index bbb47da4..8d12610a 100644 --- a/datapoollocal/SharedLocalDataSet.h +++ b/datapoollocal/SharedLocalDataSet.h @@ -25,7 +25,8 @@ public: virtual~ SharedLocalDataSet(); - ReturnValue_t lockDataset(dur_millis_t mutexTimeout) override; + ReturnValue_t lockDataset(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING, + dur_millis_t mutexTimeout = 20) override; ReturnValue_t unlockDataset() override; private: diff --git a/unittest/tests/datapoollocal/DataSetTest.cpp b/unittest/tests/datapoollocal/DataSetTest.cpp index 30b5bb05..ecc1921f 100644 --- a/unittest/tests/datapoollocal/DataSetTest.cpp +++ b/unittest/tests/datapoollocal/DataSetTest.cpp @@ -4,9 +4,9 @@ #include #include +#include #include #include -#include #include #include @@ -254,8 +254,12 @@ TEST_CASE("DataSetTest" , "[DataSetTest]") { } SECTION("SharedDataSet") { - object_id_t sharedSetId = objects::SHARED_SET_ID; - SharedLocalDataSet sharedSet(sharedSetId, poolOwner, 2, 5); +// object_id_t sharedSetId = objects::SHARED_SET_ID; +// SharedLocalDataSet sharedSet(sharedSetId, poolOwner, 2, 5); +// CHECK(sharedSet.initialize() == retval::CATCH_OK); +// CHECK(sharedSet.lockDataset() == retval::CATCH_OK); +// +// CHECK(sharedSet.unlockDataset() == retval::CATCH_OK); } /* we need to reset the subscription list because the pool owner diff --git a/unittest/tests/datapoollocal/LocalPoolOwnerBase.h b/unittest/tests/datapoollocal/LocalPoolOwnerBase.h index 7915eeb4..9a7639f8 100644 --- a/unittest/tests/datapoollocal/LocalPoolOwnerBase.h +++ b/unittest/tests/datapoollocal/LocalPoolOwnerBase.h @@ -36,11 +36,11 @@ static const gp_id_t uint64Vec2Id = gp_id_t(objects::TEST_LOCAL_POOL_OWNER_BASE, class LocalPoolStaticTestDataSet: public StaticLocalDataSet<3> { public: LocalPoolStaticTestDataSet(): - StaticLocalDataSet(lpool::testSid) { + StaticLocalDataSet(lpool::testSid) { } LocalPoolStaticTestDataSet(HasLocalDataPoolIF* owner, uint32_t setId): - StaticLocalDataSet(owner, setId) { + StaticLocalDataSet(owner, setId) { } lp_var_t localPoolVarUint8 = lp_var_t(lpool::uint8VarGpid, this); From 824f272432b51fee59e9061f6118e4f0aa2f4e47 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 11 Mar 2021 01:04:39 +0100 Subject: [PATCH 039/230] no virtual inhertience for now --- datapool/PoolDataSetIF.h | 4 ++-- datapool/SharedDataSetIF.h | 3 +-- unittest/tests/datapoollocal/DataSetTest.cpp | 12 ++++++------ unittest/tests/datapoollocal/LocalPoolOwnerBase.h | 10 ++++++++-- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/datapool/PoolDataSetIF.h b/datapool/PoolDataSetIF.h index 9151f2f8..f905cc4d 100644 --- a/datapool/PoolDataSetIF.h +++ b/datapool/PoolDataSetIF.h @@ -9,8 +9,8 @@ * and unlock a data pool and read/commit semantics. */ class PoolDataSetIF: - public DataSetIF, - public ReadCommitIF { + virtual public DataSetIF, + virtual public ReadCommitIF { public: virtual~ PoolDataSetIF() {}; diff --git a/datapool/SharedDataSetIF.h b/datapool/SharedDataSetIF.h index da21f9cf..4d23f87f 100644 --- a/datapool/SharedDataSetIF.h +++ b/datapool/SharedDataSetIF.h @@ -3,8 +3,7 @@ #include "PoolDataSetIF.h" -class SharedDataSetIF: - public PoolDataSetIF { +class SharedDataSetIF { public: virtual ~SharedDataSetIF() {}; diff --git a/unittest/tests/datapoollocal/DataSetTest.cpp b/unittest/tests/datapoollocal/DataSetTest.cpp index ecc1921f..06964d26 100644 --- a/unittest/tests/datapoollocal/DataSetTest.cpp +++ b/unittest/tests/datapoollocal/DataSetTest.cpp @@ -254,12 +254,12 @@ TEST_CASE("DataSetTest" , "[DataSetTest]") { } SECTION("SharedDataSet") { -// object_id_t sharedSetId = objects::SHARED_SET_ID; -// SharedLocalDataSet sharedSet(sharedSetId, poolOwner, 2, 5); -// CHECK(sharedSet.initialize() == retval::CATCH_OK); -// CHECK(sharedSet.lockDataset() == retval::CATCH_OK); -// -// CHECK(sharedSet.unlockDataset() == retval::CATCH_OK); + object_id_t sharedSetId = objects::SHARED_SET_ID; + SharedLocalDataSet sharedSet(sharedSetId, poolOwner, 2, 5); + CHECK(sharedSet.initialize() == retval::CATCH_OK); + CHECK(sharedSet.lockDataset() == retval::CATCH_OK); + + CHECK(sharedSet.unlockDataset() == retval::CATCH_OK); } /* we need to reset the subscription list because the pool owner diff --git a/unittest/tests/datapoollocal/LocalPoolOwnerBase.h b/unittest/tests/datapoollocal/LocalPoolOwnerBase.h index 9a7639f8..f08b9eb9 100644 --- a/unittest/tests/datapoollocal/LocalPoolOwnerBase.h +++ b/unittest/tests/datapoollocal/LocalPoolOwnerBase.h @@ -36,7 +36,8 @@ static const gp_id_t uint64Vec2Id = gp_id_t(objects::TEST_LOCAL_POOL_OWNER_BASE, class LocalPoolStaticTestDataSet: public StaticLocalDataSet<3> { public: LocalPoolStaticTestDataSet(): - StaticLocalDataSet(lpool::testSid) { + StaticLocalDataSet(lpool::testSid) { + } LocalPoolStaticTestDataSet(HasLocalDataPoolIF* owner, uint32_t setId): @@ -53,7 +54,12 @@ private: class LocalPoolTestDataSet: public LocalDataSet { public: LocalPoolTestDataSet(): - LocalDataSet(lpool::testSid, lpool::dataSetMaxVariables) { + LocalDataSet(lpool::testSid, lpool::dataSetMaxVariables), + localPoolVarUint8(lpool::uint8VarGpid, this), + localPoolVarFloat(lpool::floatVarGpid, this), + localPoolUint16Vec(lpool::uint16Vec3Gpid, this) + + { } LocalPoolTestDataSet(HasLocalDataPoolIF* owner, uint32_t setId): From 6f78c13dcfb8343563339c30d90f3cc5134ed38c Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 11 Mar 2021 11:06:23 +0100 Subject: [PATCH 040/230] added addtional nullptr check --- datapoollocal/LocalDataPoolManager.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/datapoollocal/LocalDataPoolManager.h b/datapoollocal/LocalDataPoolManager.h index d06cf2c6..2ec81f1c 100644 --- a/datapoollocal/LocalDataPoolManager.h +++ b/datapoollocal/LocalDataPoolManager.h @@ -391,6 +391,10 @@ protected: template inline ReturnValue_t LocalDataPoolManager::fetchPoolEntry(lp_id_t localPoolId, PoolEntry **poolEntry) { + if(poolEntry == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } + auto poolIter = localPoolMap.find(localPoolId); if (poolIter == localPoolMap.end()) { printWarningOrError(sif::OutputTypes::OUT_WARNING, "fetchPoolEntry", From 3bacc8ec53b1370ce6829af7e3c69ae7a0b21b5d Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 11 Mar 2021 12:04:54 +0100 Subject: [PATCH 041/230] more tests and bugfixes --- datapoollocal/LocalDataPoolManager.cpp | 20 ++++++-- datapoollocal/LocalPoolDataSetBase.cpp | 8 ++- datapoollocal/LocalPoolDataSetBase.h | 5 +- .../internal/LocalPoolDataSetAttorney.h | 5 +- housekeeping/PeriodicHousekeepingHelper.cpp | 11 ++-- housekeeping/PeriodicHousekeepingHelper.h | 7 ++- .../datapoollocal/LocalPoolManagerTest.cpp | 51 ++++++++++++++++++- .../datapoollocal/LocalPoolOwnerBase.cpp | 5 ++ .../tests/datapoollocal/LocalPoolOwnerBase.h | 15 ++---- unittest/tests/mocks/MessageQueueMockBase.h | 11 ++++ 10 files changed, 103 insertions(+), 35 deletions(-) diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index 83e30e82..cad54094 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -38,7 +38,11 @@ LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner, MessageQue hkQueue = queueToUse; } -LocalDataPoolManager::~LocalDataPoolManager() {} +LocalDataPoolManager::~LocalDataPoolManager() { + if(mutex != nullptr) { + MutexFactory::instance()->deleteMutex(mutex); + } +} ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) { if(queueToUse == nullptr) { @@ -375,7 +379,7 @@ ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(sid_t sid, LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, enableReporting); LocalPoolDataSetAttorney::setDiagnostic(*dataSet, isDiagnostics); LocalPoolDataSetAttorney::initializePeriodicHelper(*dataSet, collectionInterval, - owner->getPeriodicOperationFrequency(), isDiagnostics); + owner->getPeriodicOperationFrequency()); } hkReceivers.push_back(hkReceiver); @@ -518,11 +522,19 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage( } case(HousekeepingMessage::REPORT_DIAGNOSTICS_REPORT_STRUCTURES): { - return generateSetStructurePacket(sid, true); + result = generateSetStructurePacket(sid, true); + if(result == HasReturnvaluesIF::RETURN_OK) { + return result; + } + break; } case(HousekeepingMessage::REPORT_HK_REPORT_STRUCTURES): { - return generateSetStructurePacket(sid, false); + result = generateSetStructurePacket(sid, false); + if(result == HasReturnvaluesIF::RETURN_OK) { + return result; + } + break; } case(HousekeepingMessage::MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL): case(HousekeepingMessage::MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL): { diff --git a/datapoollocal/LocalPoolDataSetBase.cpp b/datapoollocal/LocalPoolDataSetBase.cpp index d93b926d..2a2444c4 100644 --- a/datapoollocal/LocalPoolDataSetBase.cpp +++ b/datapoollocal/LocalPoolDataSetBase.cpp @@ -264,11 +264,9 @@ bool LocalPoolDataSetBase::getReportingEnabled() const { return reportingEnabled; } -void LocalPoolDataSetBase::initializePeriodicHelper( - float collectionInterval, dur_millis_t minimumPeriodicInterval, - bool isDiagnostics, uint8_t nonDiagIntervalFactor) { - periodicHelper->initialize(collectionInterval, minimumPeriodicInterval, - isDiagnostics, nonDiagIntervalFactor); +void LocalPoolDataSetBase::initializePeriodicHelper(float collectionInterval, + dur_millis_t minimumPeriodicInterval, uint8_t nonDiagIntervalFactor) { + periodicHelper->initialize(collectionInterval, minimumPeriodicInterval, nonDiagIntervalFactor); } void LocalPoolDataSetBase::setChanged(bool changed) { diff --git a/datapoollocal/LocalPoolDataSetBase.h b/datapoollocal/LocalPoolDataSetBase.h index 39ea9f1a..ab67dc3f 100644 --- a/datapoollocal/LocalPoolDataSetBase.h +++ b/datapoollocal/LocalPoolDataSetBase.h @@ -191,9 +191,8 @@ protected: bool reportingEnabled = false; void setReportingEnabled(bool enabled); - void initializePeriodicHelper(float collectionInterval, - dur_millis_t minimumPeriodicInterval, - bool isDiagnostics, uint8_t nonDiagIntervalFactor = 5); + void initializePeriodicHelper(float collectionInterval, dur_millis_t minimumPeriodicInterval, + uint8_t nonDiagIntervalFactor = 5); /** * If the valid state of a dataset is always relevant to the whole diff --git a/datapoollocal/internal/LocalPoolDataSetAttorney.h b/datapoollocal/internal/LocalPoolDataSetAttorney.h index 7a34e9c8..f81428cd 100644 --- a/datapoollocal/internal/LocalPoolDataSetAttorney.h +++ b/datapoollocal/internal/LocalPoolDataSetAttorney.h @@ -14,9 +14,8 @@ private: } static void initializePeriodicHelper(LocalPoolDataSetBase& set, float collectionInterval, - uint32_t minimumPeriodicIntervalMs, - bool isDiagnostics, uint8_t nonDiagIntervalFactor = 5) { - set.initializePeriodicHelper(collectionInterval, minimumPeriodicIntervalMs, isDiagnostics, + uint32_t minimumPeriodicIntervalMs, uint8_t nonDiagIntervalFactor = 5) { + set.initializePeriodicHelper(collectionInterval, minimumPeriodicIntervalMs, nonDiagIntervalFactor); } diff --git a/housekeeping/PeriodicHousekeepingHelper.cpp b/housekeeping/PeriodicHousekeepingHelper.cpp index 5152706f..892eb354 100644 --- a/housekeeping/PeriodicHousekeepingHelper.cpp +++ b/housekeeping/PeriodicHousekeepingHelper.cpp @@ -6,11 +6,8 @@ PeriodicHousekeepingHelper::PeriodicHousekeepingHelper( LocalPoolDataSetBase* owner): owner(owner) {} - void PeriodicHousekeepingHelper::initialize(float collectionInterval, - dur_millis_t minimumPeriodicInterval, bool isDiagnostics, - uint8_t nonDiagIntervalFactor) { - this->isDiagnostics = isDiagnostics; + dur_millis_t minimumPeriodicInterval, uint8_t nonDiagIntervalFactor) { this->minimumPeriodicInterval = minimumPeriodicInterval; this->nonDiagIntervalFactor = nonDiagIntervalFactor; collectionIntervalTicks = intervalSecondsToIntervalTicks(collectionInterval); @@ -34,6 +31,11 @@ bool PeriodicHousekeepingHelper::checkOpNecessary() { uint32_t PeriodicHousekeepingHelper::intervalSecondsToIntervalTicks( float collectionIntervalSeconds) { + if(owner == nullptr) { + return 0; + } + bool isDiagnostics = owner->isDiagnostics(); + /* Avoid division by zero */ if(minimumPeriodicInterval == 0) { if(isDiagnostics) { @@ -85,3 +87,4 @@ void PeriodicHousekeepingHelper::changeCollectionInterval( float newIntervalSeconds) { collectionIntervalTicks = intervalSecondsToIntervalTicks(newIntervalSeconds); } + diff --git a/housekeeping/PeriodicHousekeepingHelper.h b/housekeeping/PeriodicHousekeepingHelper.h index 3e8d030e..3256fbff 100644 --- a/housekeeping/PeriodicHousekeepingHelper.h +++ b/housekeeping/PeriodicHousekeepingHelper.h @@ -10,16 +10,15 @@ class PeriodicHousekeepingHelper { public: PeriodicHousekeepingHelper(LocalPoolDataSetBase* owner); - void initialize(float collectionInterval, - dur_millis_t minimumPeriodicInterval, bool isDiagnostics, - uint8_t nonDiagIntervalFactor); + void initialize(float collectionInterval, dur_millis_t minimumPeriodicInterval, + uint8_t nonDiagIntervalFactor); void changeCollectionInterval(float newInterval); float getCollectionIntervalInSeconds() const; bool checkOpNecessary(); + private: LocalPoolDataSetBase* owner = nullptr; - bool isDiagnostics = true; uint8_t nonDiagIntervalFactor = 0; uint32_t intervalSecondsToIntervalTicks(float collectionIntervalSeconds); diff --git a/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp b/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp index 2d7294ef..c152078d 100644 --- a/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp +++ b/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp @@ -229,6 +229,7 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { /* Now HK packet should be sent as message immediately. */ REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); + CHECK(mqMock->popMessage() == retval::CATCH_OK); LocalPoolDataSetBase* setHandle = poolOwner->getDataSetHandle(lpool::testSid); REQUIRE(setHandle != nullptr); @@ -236,6 +237,7 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { setHandle, false) == retval::CATCH_OK); REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); + CHECK(mqMock->popMessage() == retval::CATCH_OK); CHECK(setHandle->getReportingEnabled() == true); CommandMessage hkCmd; @@ -244,17 +246,19 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { CHECK(setHandle->getReportingEnabled() == false); REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); + CHECK(mqMock->popMessage() == retval::CATCH_OK); + HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, true, false); CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); CHECK(setHandle->getReportingEnabled() == true); REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); - CHECK(messagesSent == 1); + CHECK(mqMock->popMessage() == retval::CATCH_OK); HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, false); CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); CHECK(setHandle->getReportingEnabled() == false); REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); - CHECK(messagesSent == 1); + CHECK(mqMock->popMessage() == retval::CATCH_OK); HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid, 0.4, false); @@ -264,6 +268,7 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { CHECK(poolOwner->dataset.getCollectionInterval() == 1.0); REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); + CHECK(mqMock->popMessage() == retval::CATCH_OK); HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, false); REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK); @@ -271,11 +276,13 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { /* Now HK packet should be sent as message. */ REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); + CHECK(mqMock->popMessage() == retval::CATCH_OK); HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, false); CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); + CHECK(mqMock->popMessage() == retval::CATCH_OK); HousekeepingMessage::setUpdateNotificationSetCommand(&hkCmd, lpool::testSid); sid_t sidToCheck; @@ -283,6 +290,46 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); CHECK(poolOwner->changedDataSetCallbackWasCalled(sidToCheck, storeId) == true); CHECK(sidToCheck == lpool::testSid); + + /* Now we test the handling is the dataset is set to diagnostic */ + poolOwner->dataset.setDiagnostic(true); + + HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, false); + CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == + static_cast(LocalDataPoolManager::WRONG_HK_PACKET_TYPE)); + /* We still expect a failure message being sent */ + REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + CHECK(messagesSent == 1); + CHECK(mqMock->popMessage() == retval::CATCH_OK); + + HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, + lpool::testSid, 0.4, false); + CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == + static_cast(LocalDataPoolManager::WRONG_HK_PACKET_TYPE)); + REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + CHECK(messagesSent == 1); + CHECK(mqMock->popMessage() == retval::CATCH_OK); + + HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, false); + CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == + static_cast(LocalDataPoolManager::WRONG_HK_PACKET_TYPE)); + REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + CHECK(messagesSent == 1); + CHECK(mqMock->popMessage() == retval::CATCH_OK); + + HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, true); + CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); + REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + CHECK(messagesSent == 1); + CHECK(mqMock->popMessage() == retval::CATCH_OK); + + HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid, 0.4, + true); + CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); + REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + CHECK(messagesSent == 1); + CHECK(mqMock->popMessage() == retval::CATCH_OK); + } /* we need to reset the subscription list because the pool owner diff --git a/unittest/tests/datapoollocal/LocalPoolOwnerBase.cpp b/unittest/tests/datapoollocal/LocalPoolOwnerBase.cpp index 0e2703a7..7ccceb06 100644 --- a/unittest/tests/datapoollocal/LocalPoolOwnerBase.cpp +++ b/unittest/tests/datapoollocal/LocalPoolOwnerBase.cpp @@ -6,6 +6,10 @@ LocalPoolOwnerBase::LocalPoolOwnerBase(object_id_t objectId): messageQueue = new MessageQueueMockBase(); } +LocalPoolOwnerBase::~LocalPoolOwnerBase() { + QueueFactory::instance()->deleteMessageQueue(messageQueue); +} + ReturnValue_t LocalPoolOwnerBase::initializeHkManager() { if(not initialized) { initialized = true; @@ -132,3 +136,4 @@ void LocalPoolOwnerBase::handleChangedPoolVariable(gp_id_t globPoolId, store_add this->changedPoolVariableGpid = globPoolId; this->storeIdForChangedVariable = storeId; } + diff --git a/unittest/tests/datapoollocal/LocalPoolOwnerBase.h b/unittest/tests/datapoollocal/LocalPoolOwnerBase.h index f08b9eb9..c045b6d3 100644 --- a/unittest/tests/datapoollocal/LocalPoolOwnerBase.h +++ b/unittest/tests/datapoollocal/LocalPoolOwnerBase.h @@ -54,13 +54,7 @@ private: class LocalPoolTestDataSet: public LocalDataSet { public: LocalPoolTestDataSet(): - LocalDataSet(lpool::testSid, lpool::dataSetMaxVariables), - localPoolVarUint8(lpool::uint8VarGpid, this), - localPoolVarFloat(lpool::floatVarGpid, this), - localPoolUint16Vec(lpool::uint16Vec3Gpid, this) - - { - } + LocalDataSet(lpool::testSid, lpool::dataSetMaxVariables) {} LocalPoolTestDataSet(HasLocalDataPoolIF* owner, uint32_t setId): LocalDataSet(owner, setId, lpool::dataSetMaxVariables) { @@ -70,6 +64,9 @@ public: lp_var_t localPoolVarFloat = lp_var_t(lpool::floatVarGpid, this); lp_vec_t localPoolUint16Vec = lp_vec_t(lpool::uint16Vec3Gpid, this); + void setDiagnostic(bool isDiagnostic) { + LocalPoolDataSetBase::setDiagnostic(isDiagnostic); + } private: }; @@ -78,9 +75,7 @@ class LocalPoolOwnerBase: public SystemObject, public HasLocalDataPoolIF { public: LocalPoolOwnerBase(object_id_t objectId = objects::TEST_LOCAL_POOL_OWNER_BASE); - ~LocalPoolOwnerBase() { - QueueFactory::instance()->deleteMessageQueue(messageQueue); - } + ~LocalPoolOwnerBase(); object_id_t getObjectId() const override { return SystemObject::getObjectId(); diff --git a/unittest/tests/mocks/MessageQueueMockBase.h b/unittest/tests/mocks/MessageQueueMockBase.h index 31146d34..3000f7fb 100644 --- a/unittest/tests/mocks/MessageQueueMockBase.h +++ b/unittest/tests/mocks/MessageQueueMockBase.h @@ -29,6 +29,16 @@ public: return tempMessageSent; } + /** + * Pop a message, clearing it in the process. + * @return + */ + ReturnValue_t popMessage() { + CommandMessage message; + message.clear(); + return receiveMessage(&message); + } + virtual ReturnValue_t reply( MessageQueueMessageIF* message ) { return sendMessage(myQueueId, message); }; @@ -36,6 +46,7 @@ public: MessageQueueId_t *receivedFrom) { return receiveMessage(message); } + virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message) { if(messagesSentQueue.empty()) { return MessageQueueIF::EMPTY; From 8b83de6ca9fbd9b574a5a178a4b884267527bacc Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 11 Mar 2021 12:33:26 +0100 Subject: [PATCH 042/230] added way to automatically clear unhandled messages --- datapoollocal/HasLocalDataPoolIF.h | 23 +++++++----- datapoollocal/LocalDataPoolManager.cpp | 19 +++++++--- housekeeping/HousekeepingMessage.cpp | 3 +- .../datapoollocal/LocalPoolManagerTest.cpp | 36 ++++++++++++++++++- .../datapoollocal/LocalPoolOwnerBase.cpp | 6 ++-- .../tests/datapoollocal/LocalPoolOwnerBase.h | 5 +-- 6 files changed, 73 insertions(+), 19 deletions(-) diff --git a/datapoollocal/HasLocalDataPoolIF.h b/datapoollocal/HasLocalDataPoolIF.h index ec25f082..54856fac 100644 --- a/datapoollocal/HasLocalDataPoolIF.h +++ b/datapoollocal/HasLocalDataPoolIF.h @@ -72,12 +72,15 @@ public: * notification is received. * @details HasLocalDataPoolIF * Can be overriden by the child class to handle changed datasets. - * @param sid - * @param storeId If a snapshot was requested, data will be located inside + * @param sid SID of the updated set + * @param storeId If a snapshot was requested, data will be located inside * the IPC store with this store ID. + * @param clearMessage If this is set to true, the pool manager will take care of + * clearing the store automatically */ virtual void handleChangedDataset(sid_t sid, - store_address_t storeId = storeId::INVALID_STORE_ADDRESS) { + store_address_t storeId = storeId::INVALID_STORE_ADDRESS, + bool* clearMessage = nullptr) { return; } @@ -85,13 +88,17 @@ public: * @brief This function will be called by the manager if an update * notification is received. * @details - * Can be overriden by the child class to handle changed pool IDs. - * @param sid - * @param storeId If a snapshot was requested, data will be located inside + * Can be overriden by the child class to handle changed pool variables. + * @param gpid GPID of the updated variable. + * @param storeId If a snapshot was requested, data will be located inside * the IPC store with this store ID. + * @param clearMessage Relevant for snapshots. If the boolean this points to is set to true, + * the pool manager will take care of clearing the store automatically + * after the callback. */ - virtual void handleChangedPoolVariable(gp_id_t globPoolId, - store_address_t storeId = storeId::INVALID_STORE_ADDRESS) { + virtual void handleChangedPoolVariable(gp_id_t gpid, + store_address_t storeId = storeId::INVALID_STORE_ADDRESS, + bool* clearMessage = nullptr) { return; } diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index cad54094..e9bb57c4 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -554,14 +554,15 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage( case(HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT): case(HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT): { LocalPoolDataSetBase* dataSet =HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid); - //LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid); if(command == HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT and LocalPoolDataSetAttorney::isDiagnostics(*dataSet)) { - return WRONG_HK_PACKET_TYPE; + result = WRONG_HK_PACKET_TYPE; + break; } else if(command == HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT and not LocalPoolDataSetAttorney::isDiagnostics(*dataSet)) { - return WRONG_HK_PACKET_TYPE; + result = WRONG_HK_PACKET_TYPE; + break; } return generateHousekeepingPacket(HousekeepingMessage::getSid(message), dataSet, true); @@ -580,14 +581,22 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage( case(HousekeepingMessage::UPDATE_SNAPSHOT_SET): { store_address_t storeId; HousekeepingMessage::getUpdateSnapshotSetCommand(message, &storeId); - owner->handleChangedDataset(sid, storeId); + bool clearMessage = true; + owner->handleChangedDataset(sid, storeId, &clearMessage); + if(clearMessage) { + message->clear(); + } return HasReturnvaluesIF::RETURN_OK; } case(HousekeepingMessage::UPDATE_SNAPSHOT_VARIABLE): { store_address_t storeId; gp_id_t globPoolId = HousekeepingMessage::getUpdateSnapshotVariableCommand(message, &storeId); - owner->handleChangedPoolVariable(globPoolId, storeId); + bool clearMessage = true; + owner->handleChangedPoolVariable(globPoolId, storeId, &clearMessage); + if(clearMessage) { + message->clear(); + } return HasReturnvaluesIF::RETURN_OK; } diff --git a/housekeeping/HousekeepingMessage.cpp b/housekeeping/HousekeepingMessage.cpp index 58f8551d..90ca73c8 100644 --- a/housekeeping/HousekeepingMessage.cpp +++ b/housekeeping/HousekeepingMessage.cpp @@ -157,7 +157,8 @@ void HousekeepingMessage::clear(CommandMessage* message) { case(DIAGNOSTICS_REPORT): case(HK_DEFINITIONS_REPORT): case(DIAGNOSTICS_DEFINITION_REPORT): - case(UPDATE_SNAPSHOT_SET): { + case(UPDATE_SNAPSHOT_SET): + case(UPDATE_SNAPSHOT_VARIABLE): { store_address_t storeId; getHkDataReply(message, &storeId); StorageManagerIF *ipcStore = objectManager->get( diff --git a/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp b/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp index c152078d..88332719 100644 --- a/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp +++ b/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp @@ -26,8 +26,11 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { CommandMessage messageSent; uint8_t messagesSent = 0; - SECTION("BasicTest") { + { + /* For code coverage, should not crash */ + LocalDataPoolManager manager(nullptr, nullptr); + } auto owner = poolOwner->poolManager.getOwner(); REQUIRE(owner != nullptr); CHECK(owner->getObjectId() == objects::TEST_LOCAL_POOL_OWNER_BASE); @@ -330,6 +333,37 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { CHECK(messagesSent == 1); CHECK(mqMock->popMessage() == retval::CATCH_OK); + HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, true, true); + CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); + REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + CHECK(messagesSent == 1); + CHECK(mqMock->popMessage() == retval::CATCH_OK); + + HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, true); + CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); + REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + CHECK(messagesSent == 1); + CHECK(mqMock->popMessage() == retval::CATCH_OK); + + HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, false); + CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == + static_cast(LocalDataPoolManager::WRONG_HK_PACKET_TYPE)); + REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + CHECK(messagesSent == 1); + CHECK(mqMock->popMessage() == retval::CATCH_OK); + + HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, true); + CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); + REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + CHECK(messagesSent == 1); + CHECK(mqMock->popMessage() == retval::CATCH_OK); + + HousekeepingMessage::setUpdateNotificationVariableCommand(&hkCmd, lpool::uint8VarGpid); + gp_id_t gpidToCheck; + CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); + CHECK(poolOwner->changedVariableCallbackWasCalled(gpidToCheck, storeId) == true); + CHECK(gpidToCheck == lpool::testSid); + } /* we need to reset the subscription list because the pool owner diff --git a/unittest/tests/datapoollocal/LocalPoolOwnerBase.cpp b/unittest/tests/datapoollocal/LocalPoolOwnerBase.cpp index 7ccceb06..991314a9 100644 --- a/unittest/tests/datapoollocal/LocalPoolOwnerBase.cpp +++ b/unittest/tests/datapoollocal/LocalPoolOwnerBase.cpp @@ -106,7 +106,8 @@ bool LocalPoolOwnerBase::changedDataSetCallbackWasCalled(sid_t &sid, store_addre return condition; } -void LocalPoolOwnerBase::handleChangedDataset(sid_t sid, store_address_t storeId) { +void LocalPoolOwnerBase::handleChangedDataset(sid_t sid, store_address_t storeId, + bool* clearMessage) { this->changedDatasetSid = sid; this->storeIdForChangedSet = storeId; } @@ -132,7 +133,8 @@ ReturnValue_t LocalPoolOwnerBase::initializeHkManagerAfterTaskCreation() { } -void LocalPoolOwnerBase::handleChangedPoolVariable(gp_id_t globPoolId, store_address_t storeId) { +void LocalPoolOwnerBase::handleChangedPoolVariable(gp_id_t globPoolId, store_address_t storeId, + bool* clearMessage) { this->changedPoolVariableGpid = globPoolId; this->storeIdForChangedVariable = storeId; } diff --git a/unittest/tests/datapoollocal/LocalPoolOwnerBase.h b/unittest/tests/datapoollocal/LocalPoolOwnerBase.h index c045b6d3..8d2073b0 100644 --- a/unittest/tests/datapoollocal/LocalPoolOwnerBase.h +++ b/unittest/tests/datapoollocal/LocalPoolOwnerBase.h @@ -160,11 +160,12 @@ public: LocalPoolTestDataSet dataset; private: - void handleChangedDataset(sid_t sid, store_address_t storeId) override; + void handleChangedDataset(sid_t sid, store_address_t storeId, bool* clearMessage) override; sid_t changedDatasetSid; store_address_t storeIdForChangedSet; - void handleChangedPoolVariable(gp_id_t globPoolId, store_address_t storeId) override; + void handleChangedPoolVariable(gp_id_t globPoolId, store_address_t storeId, + bool* clearMessage) override; gp_id_t changedPoolVariableGpid; store_address_t storeIdForChangedVariable; From e55f74a00ef51047f4a450d1e826ef0e081615e7 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 11 Mar 2021 12:34:25 +0100 Subject: [PATCH 043/230] default auto clearance --- datapoollocal/HasLocalDataPoolIF.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/datapoollocal/HasLocalDataPoolIF.h b/datapoollocal/HasLocalDataPoolIF.h index 54856fac..74e372c9 100644 --- a/datapoollocal/HasLocalDataPoolIF.h +++ b/datapoollocal/HasLocalDataPoolIF.h @@ -81,7 +81,9 @@ public: virtual void handleChangedDataset(sid_t sid, store_address_t storeId = storeId::INVALID_STORE_ADDRESS, bool* clearMessage = nullptr) { - return; + if(clearMessage != nullptr) { + *clearMessage = true; + } } /** @@ -99,7 +101,9 @@ public: virtual void handleChangedPoolVariable(gp_id_t gpid, store_address_t storeId = storeId::INVALID_STORE_ADDRESS, bool* clearMessage = nullptr) { - return; + if(clearMessage != nullptr) { + *clearMessage = true; + } } /** From 33823b445c79c8e273527642f412eba650545b25 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 11 Mar 2021 12:44:35 +0100 Subject: [PATCH 044/230] some more tests added --- datapoollocal/LocalDataPoolManager.cpp | 2 +- datapoollocal/localPoolDefinitions.h | 4 ++-- globalfunctions/arrayprinter.cpp | 4 ++++ .../tests/datapoollocal/LocalPoolManagerTest.cpp | 16 +++++++++++++++- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index e9bb57c4..94ee9c26 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -592,7 +592,7 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage( store_address_t storeId; gp_id_t globPoolId = HousekeepingMessage::getUpdateSnapshotVariableCommand(message, &storeId); - bool clearMessage = true; + bool clearMessage = true; owner->handleChangedPoolVariable(globPoolId, storeId, &clearMessage); if(clearMessage) { message->clear(); diff --git a/datapoollocal/localPoolDefinitions.h b/datapoollocal/localPoolDefinitions.h index af8ce711..daab8b9c 100644 --- a/datapoollocal/localPoolDefinitions.h +++ b/datapoollocal/localPoolDefinitions.h @@ -96,11 +96,11 @@ union gp_id_t { return raw == INVALID_GPID; } - bool operator==(const sid_t& other) const { + bool operator==(const gp_id_t& other) const { return raw == other.raw; } - bool operator!=(const sid_t& other) const { + bool operator!=(const gp_id_t& other) const { return not (raw == other.raw); } }; diff --git a/globalfunctions/arrayprinter.cpp b/globalfunctions/arrayprinter.cpp index 7dc056b0..20a64f5b 100644 --- a/globalfunctions/arrayprinter.cpp +++ b/globalfunctions/arrayprinter.cpp @@ -67,7 +67,9 @@ void arrayprinter::printHex(const uint8_t *data, size_t size, } } } +#if FSFW_DISABLE_PRINTOUT == 0 printf("[%s]\n", printBuffer); +#endif /* FSFW_DISABLE_PRINTOUT == 0 */ #endif } @@ -108,7 +110,9 @@ void arrayprinter::printDec(const uint8_t *data, size_t size, } } } +#if FSFW_DISABLE_PRINTOUT == 0 printf("[%s]\n", printBuffer); +#endif /* FSFW_DISABLE_PRINTOUT == 0 */ #endif } diff --git a/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp b/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp index 88332719..a98db610 100644 --- a/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp +++ b/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp @@ -362,7 +362,21 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { gp_id_t gpidToCheck; CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); CHECK(poolOwner->changedVariableCallbackWasCalled(gpidToCheck, storeId) == true); - CHECK(gpidToCheck == lpool::testSid); + CHECK(gpidToCheck == lpool::uint8VarGpid); + + HousekeepingMessage::setUpdateSnapshotSetCommand(&hkCmd, lpool::testSid, + storeId::INVALID_STORE_ADDRESS); + CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); + CHECK(poolOwner->changedDataSetCallbackWasCalled(sidToCheck, storeId) == true); + CHECK(sidToCheck == lpool::testSid); + + HousekeepingMessage::setUpdateSnapshotVariableCommand(&hkCmd, lpool::uint8VarGpid, + storeId::INVALID_STORE_ADDRESS); + CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); + CHECK(poolOwner->changedVariableCallbackWasCalled(gpidToCheck, storeId) == true); + CHECK(gpidToCheck == lpool::uint8VarGpid); + + poolOwner->poolManager.printPoolEntry(lpool::uint8VarId); } From 9602a3ed6a9b451ae9b704ba8a3fbbd6e85c9afe Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 11 Mar 2021 13:02:10 +0100 Subject: [PATCH 045/230] bugfix and a few more tests --- datapool/PoolDataSetBase.cpp | 4 ++++ datapoollocal/SharedLocalDataSet.cpp | 4 ++-- unittest/tests/datapoollocal/DataSetTest.cpp | 20 ++++++++++++++++++-- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/datapool/PoolDataSetBase.cpp b/datapool/PoolDataSetBase.cpp index 73ec4bd7..60f08b88 100644 --- a/datapool/PoolDataSetBase.cpp +++ b/datapool/PoolDataSetBase.cpp @@ -14,6 +14,10 @@ PoolDataSetBase::~PoolDataSetBase() {} ReturnValue_t PoolDataSetBase::registerVariable(PoolVariableIF *variable) { + if(registeredVariables == nullptr) { + /* Underlying container invalid */ + return HasReturnvaluesIF::RETURN_FAILED; + } if (state != States::STATE_SET_UNINITIALISED) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "DataSet::registerVariable: Call made in wrong position." << std::endl; diff --git a/datapoollocal/SharedLocalDataSet.cpp b/datapoollocal/SharedLocalDataSet.cpp index abcf7da9..84c2d1c3 100644 --- a/datapoollocal/SharedLocalDataSet.cpp +++ b/datapoollocal/SharedLocalDataSet.cpp @@ -3,7 +3,7 @@ SharedLocalDataSet::SharedLocalDataSet(object_id_t objectId, sid_t sid, const size_t maxSize): SystemObject(objectId), - LocalPoolDataSetBase(sid, nullptr, maxSize) { + LocalPoolDataSetBase(sid, nullptr, maxSize), poolVarVector(maxSize) { this->setContainer(poolVarVector.data()); datasetLock = MutexFactory::instance()->createMutex(); } @@ -11,7 +11,7 @@ SharedLocalDataSet::SharedLocalDataSet(object_id_t objectId, sid_t sid, SharedLocalDataSet::SharedLocalDataSet(object_id_t objectId, HasLocalDataPoolIF *owner, uint32_t setId, const size_t maxSize): SystemObject(objectId), - LocalPoolDataSetBase(owner, setId, nullptr, maxSize) { + LocalPoolDataSetBase(owner, setId, nullptr, maxSize), poolVarVector(maxSize) { this->setContainer(poolVarVector.data()); datasetLock = MutexFactory::instance()->createMutex(); } diff --git a/unittest/tests/datapoollocal/DataSetTest.cpp b/unittest/tests/datapoollocal/DataSetTest.cpp index 06964d26..ce4d9d43 100644 --- a/unittest/tests/datapoollocal/DataSetTest.cpp +++ b/unittest/tests/datapoollocal/DataSetTest.cpp @@ -255,11 +255,27 @@ TEST_CASE("DataSetTest" , "[DataSetTest]") { SECTION("SharedDataSet") { object_id_t sharedSetId = objects::SHARED_SET_ID; - SharedLocalDataSet sharedSet(sharedSetId, poolOwner, 2, 5); + SharedLocalDataSet sharedSet(sharedSetId, poolOwner, lpool::testSetId, 5); + localSet.localPoolVarUint8.setReadWriteMode(pool_rwm_t::VAR_WRITE); + localSet.localPoolUint16Vec.setReadWriteMode(pool_rwm_t::VAR_WRITE); + CHECK(sharedSet.registerVariable(&localSet.localPoolVarUint8) == retval::CATCH_OK); + CHECK(sharedSet.registerVariable(&localSet.localPoolUint16Vec) == retval::CATCH_OK); CHECK(sharedSet.initialize() == retval::CATCH_OK); CHECK(sharedSet.lockDataset() == retval::CATCH_OK); - CHECK(sharedSet.unlockDataset() == retval::CATCH_OK); + + { + //PoolReadGuard rg(&sharedSet); + //CHECK(rg.getReadResult() == retval::CATCH_OK); + localSet.localPoolVarUint8.value = 5; + localSet.localPoolUint16Vec.value[0] = 1; + localSet.localPoolUint16Vec.value[1] = 2; + localSet.localPoolUint16Vec.value[2] = 3; + CHECK(sharedSet.commit() == retval::CATCH_OK); + } + + sharedSet.setReadCommitProtectionBehaviour(true); + } /* we need to reset the subscription list because the pool owner From c527391b106d49b0d4d72590fb6c88fb0ac03e34 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 11 Mar 2021 13:14:49 +0100 Subject: [PATCH 046/230] removed unfisnihed stuff from PR --- osal/windows/CMakeLists.txt | 1 - osal/windows/TcWinTcpServer.cpp | 177 -------------------------------- osal/windows/TcWinTcpServer.h | 56 ---------- 3 files changed, 234 deletions(-) delete mode 100644 osal/windows/TcWinTcpServer.cpp delete mode 100644 osal/windows/TcWinTcpServer.h diff --git a/osal/windows/CMakeLists.txt b/osal/windows/CMakeLists.txt index 889ea339..a3a719e0 100644 --- a/osal/windows/CMakeLists.txt +++ b/osal/windows/CMakeLists.txt @@ -1,7 +1,6 @@ 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 deleted file mode 100644 index f85147f0..00000000 --- a/osal/windows/TcWinTcpServer.cpp +++ /dev/null @@ -1,177 +0,0 @@ -#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 deleted file mode 100644 index f8aebc53..00000000 --- a/osal/windows/TcWinTcpServer.h +++ /dev/null @@ -1,56 +0,0 @@ -#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 36e524abe3217e7f2a31986d3f59dfb98448ecfa Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 11 Mar 2021 14:46:22 +0100 Subject: [PATCH 047/230] more tests --- housekeeping/HousekeepingSnapshot.h | 18 +++++++-- .../datapoollocal/LocalPoolManagerTest.cpp | 40 ++++++++++++++++++- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/housekeeping/HousekeepingSnapshot.h b/housekeeping/HousekeepingSnapshot.h index 50afd4af..45b40d37 100644 --- a/housekeeping/HousekeepingSnapshot.h +++ b/housekeeping/HousekeepingSnapshot.h @@ -11,7 +11,8 @@ * @brief This helper class will be used to serialize and deserialize update housekeeping packets * into the store. */ -class HousekeepingSnapshot: public SerializeIF { +class HousekeepingSnapshot: + public SerializeIF { public: /** @@ -36,6 +37,17 @@ public: timeStamp(timeStamp), timeStampSize(timeStampSize), updateData(dataSetPtr) {}; + /** + * Update packet constructor for pool variables. + * @param timeStamp + * @param timeStampSize + * @param dataSetPtr + */ + HousekeepingSnapshot(CCSDSTime::CDS_short* cdsShort, LocalPoolObjectBase* dataSetPtr): + timeStamp(reinterpret_cast(cdsShort)), + timeStampSize(sizeof(CCSDSTime::CDS_short)), updateData(dataSetPtr) {}; + + /** * Update packet constructor for pool variables. * @param timeStamp @@ -47,8 +59,8 @@ public: timeStamp(timeStamp), timeStampSize(timeStampSize), updateData(dataSetPtr) {}; - virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, - size_t maxSize, Endianness streamEndianness) const { + virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize, + Endianness streamEndianness) const { if(timeStamp != nullptr) { /* Endianness will always be MACHINE, so we can simply use memcpy here. */ diff --git a/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp b/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp index a98db610..4df735cd 100644 --- a/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp +++ b/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp @@ -20,7 +20,7 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { REQUIRE(poolOwner->initializeHkManager() == retval::CATCH_OK); REQUIRE(poolOwner->initializeHkManagerAfterTaskCreation() == retval::CATCH_OK); - //REQUIRE(poolOwner->dataset.assignPointers() == retval::CATCH_OK); + MessageQueueMockBase* mqMock = poolOwner->getMockQueueHandle(); REQUIRE(mqMock != nullptr); CommandMessage messageSent; @@ -154,7 +154,21 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { auto poolVar = dynamic_cast*>( poolOwner->getPoolObjectHandle(lpool::uint8VarId)); REQUIRE(poolVar != nullptr); + + { + PoolReadGuard rg(poolVar); + CHECK(rg.getReadResult() == retval::CATCH_OK); + poolVar->value = 25; + } + poolVar->setChanged(true); + + /* Store current time, we are going to check the (approximate) time equality later */ + CCSDSTime::CDS_short timeCdsNow; + timeval now; + Clock::getClock_timeval(&now); + CCSDSTime::convertToCcsds(&timeCdsNow, &now); + REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK); /* Check update snapshot was sent. */ @@ -166,6 +180,30 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK); CHECK(messageSent.getCommand() == static_cast( HousekeepingMessage::UPDATE_SNAPSHOT_VARIABLE)); + /* Now we deserialize the snapshot into a new dataset instance */ + CCSDSTime::CDS_short cdsShort; + lp_var_t varCopy = lp_var_t(lpool::uint8VarGpid); + HousekeepingSnapshot snapshot(&cdsShort, &varCopy); + store_address_t storeId; + HousekeepingMessage::getUpdateSnapshotVariableCommand(&messageSent, &storeId); + ConstAccessorPair accessorPair = tglob::getIpcStoreHandle()->getData(storeId); + REQUIRE(accessorPair.first == retval::CATCH_OK); + const uint8_t* readOnlyPtr = accessorPair.second.data(); + size_t sizeToDeserialize = accessorPair.second.size(); + CHECK(varCopy.value == 0); + /* Fill the dataset and timestamp */ + REQUIRE(snapshot.deSerialize(&readOnlyPtr, &sizeToDeserialize, + SerializeIF::Endianness::MACHINE) == retval::CATCH_OK); + CHECK(varCopy.value == 25); + + /* Now we check that both times are equal */ + CHECK(cdsShort.pField == timeCdsNow.pField); + CHECK(cdsShort.dayLSB == Catch::Approx(timeCdsNow.dayLSB).margin(1)); + CHECK(cdsShort.dayMSB == Catch::Approx(timeCdsNow.dayMSB).margin(1)); + CHECK(cdsShort.msDay_h == Catch::Approx(timeCdsNow.msDay_h).margin(1)); + CHECK(cdsShort.msDay_hh == Catch::Approx(timeCdsNow.msDay_hh).margin(1)); + CHECK(cdsShort.msDay_l == Catch::Approx(timeCdsNow.msDay_l).margin(1)); + CHECK(cdsShort.msDay_ll == Catch::Approx(timeCdsNow.msDay_ll).margin(1)); } SECTION("VariableUpdateTest") { From 9eefd5b95da305f63205f026258426299c803e98 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 11 Mar 2021 14:47:47 +0100 Subject: [PATCH 048/230] 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 049/230] 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 050/230] 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 051/230] 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 052/230] 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 053/230] 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 054/230] 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 055/230] 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 056/230] 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 057/230] 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 058/230] 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 059/230] 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 060/230] 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 061/230] 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 062/230] 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 063/230] 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 064/230] 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): From 588f9471d8f4b730df5ddf6ff51c7e264ff4b142 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 15 Mar 2021 13:06:13 +0100 Subject: [PATCH 065/230] some stuff is buggy --- osal/windows/TcWinUdpPollingTask.cpp | 3 +++ osal/windows/TcWinUdpPollingTask.h | 3 --- osal/windows/TmTcWinUdpBridge.cpp | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osal/windows/TcWinUdpPollingTask.cpp b/osal/windows/TcWinUdpPollingTask.cpp index 324547fa..ce77deb9 100644 --- a/osal/windows/TcWinUdpPollingTask.cpp +++ b/osal/windows/TcWinUdpPollingTask.cpp @@ -5,6 +5,9 @@ #include +//! Debugging preprocessor define. +#define FSFW_UDP_RCV_WIRETAPPING_ENABLED 1 + TcWinUdpPollingTask::TcWinUdpPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge, size_t frameSize, double timeoutSeconds): SystemObject(objectId), diff --git a/osal/windows/TcWinUdpPollingTask.h b/osal/windows/TcWinUdpPollingTask.h index 707ad282..35e3a701 100644 --- a/osal/windows/TcWinUdpPollingTask.h +++ b/osal/windows/TcWinUdpPollingTask.h @@ -8,9 +8,6 @@ #include -//! Debugging preprocessor define. -#define FSFW_UDP_RCV_WIRETAPPING_ENABLED 0 - /** * @brief This class can be used to implement the polling of a Unix socket, * using UDP for now. diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index ca0fe2d1..c4c26e68 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -6,7 +6,7 @@ #include //! Debugging preprocessor define. -#define FSFW_UDP_SEND_WIRETAPPING_ENABLED 0 +#define FSFW_UDP_SEND_WIRETAPPING_ENABLED 1 const std::string TmTcWinUdpBridge::DEFAULT_UDP_SERVER_PORT = tcpip::DEFAULT_UDP_SERVER_PORT; @@ -112,8 +112,8 @@ ReturnValue_t TmTcWinUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { 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); + //clientAddress.sin_addr.s_addr = htons(INADDR_ANY); + //clientAddressLen = sizeof(serverAddress); char ipAddress [15]; sif::debug << "IP Address Sender: "<< inet_ntop(AF_INET, &clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; From ca4a0b1bb80107f150250c2c5e7cb04279b65561 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 15 Mar 2021 21:33:45 +0100 Subject: [PATCH 066/230] wiretapping disabled again --- osal/windows/TcWinUdpPollingTask.cpp | 2 +- osal/windows/TmTcWinUdpBridge.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osal/windows/TcWinUdpPollingTask.cpp b/osal/windows/TcWinUdpPollingTask.cpp index ce77deb9..980404f9 100644 --- a/osal/windows/TcWinUdpPollingTask.cpp +++ b/osal/windows/TcWinUdpPollingTask.cpp @@ -6,7 +6,7 @@ #include //! Debugging preprocessor define. -#define FSFW_UDP_RCV_WIRETAPPING_ENABLED 1 +#define FSFW_UDP_RCV_WIRETAPPING_ENABLED 0 TcWinUdpPollingTask::TcWinUdpPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge, size_t frameSize, diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index c4c26e68..f9c97caa 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -6,7 +6,7 @@ #include //! Debugging preprocessor define. -#define FSFW_UDP_SEND_WIRETAPPING_ENABLED 1 +#define FSFW_UDP_SEND_WIRETAPPING_ENABLED 0 const std::string TmTcWinUdpBridge::DEFAULT_UDP_SERVER_PORT = tcpip::DEFAULT_UDP_SERVER_PORT; From 1996f5949fbc1d3051d8aaa0f2c29e6b7700facf Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 16 Mar 2021 14:46:05 +0100 Subject: [PATCH 067/230] separate windows handling --- datapoollocal/LocalPoolDataSetBase.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/datapoollocal/LocalPoolDataSetBase.cpp b/datapoollocal/LocalPoolDataSetBase.cpp index 2a2444c4..16c6857d 100644 --- a/datapoollocal/LocalPoolDataSetBase.cpp +++ b/datapoollocal/LocalPoolDataSetBase.cpp @@ -96,15 +96,22 @@ ReturnValue_t LocalPoolDataSetBase::serializeWithValidityBuffer(uint8_t **buffer SerializeIF::Endianness streamEndianness) const { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; const uint8_t validityMaskSize = std::ceil(static_cast(fillCount)/8.0); + uint8_t* validityPtr = nullptr; +#ifdef _WIN32 /* Use a std::vector here because MSVC will (rightly) not create a fixed size array with a non constant size specifier */ std::vector validityMask(validityMaskSize); + validityPtr = validityMask.data(); +#else + uint8_t validityMask[validityMaskSize]; + validityPtr = validityMask; +#endif uint8_t validBufferIndex = 0; uint8_t validBufferIndexBit = 0; for (uint16_t count = 0; count < fillCount; count++) { if(registeredVariables[count]->isValid()) { /* Set bit at correct position */ - bitutil::bitSet(validityMask.data() + validBufferIndex, validBufferIndexBit); + bitutil::bitSet(validityMask + validBufferIndex, validBufferIndexBit); } if(validBufferIndexBit == 7) { validBufferIndex ++; @@ -125,7 +132,7 @@ ReturnValue_t LocalPoolDataSetBase::serializeWithValidityBuffer(uint8_t **buffer return SerializeIF::BUFFER_TOO_SHORT; } // copy validity buffer to end - std::memcpy(*buffer, validityMask.data(), validityMaskSize); + std::memcpy(*buffer, validityPtr, validityMaskSize); *size += validityMaskSize; return result; } From 26ce8d718557b9627dfeda374ab67197afdcd1e2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 16 Mar 2021 14:49:51 +0100 Subject: [PATCH 068/230] msc stuff --- datapoollocal/LocalPoolDataSetBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datapoollocal/LocalPoolDataSetBase.cpp b/datapoollocal/LocalPoolDataSetBase.cpp index 16c6857d..6aa66f82 100644 --- a/datapoollocal/LocalPoolDataSetBase.cpp +++ b/datapoollocal/LocalPoolDataSetBase.cpp @@ -97,7 +97,7 @@ ReturnValue_t LocalPoolDataSetBase::serializeWithValidityBuffer(uint8_t **buffer ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; const uint8_t validityMaskSize = std::ceil(static_cast(fillCount)/8.0); uint8_t* validityPtr = nullptr; -#ifdef _WIN32 +#ifdef _MSC_VER /* Use a std::vector here because MSVC will (rightly) not create a fixed size array with a non constant size specifier */ std::vector validityMask(validityMaskSize); From 8dec4c931147d7c3c39c812aaa985953f37380b2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 16 Mar 2021 14:53:17 +0100 Subject: [PATCH 069/230] updated pool data set base --- datapoollocal/LocalPoolDataSetBase.cpp | 30 +++++++++++++++++++------- datapoollocal/LocalPoolDataSetBase.h | 16 ++++++++++---- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/datapoollocal/LocalPoolDataSetBase.cpp b/datapoollocal/LocalPoolDataSetBase.cpp index 2d70712b..6aa66f82 100644 --- a/datapoollocal/LocalPoolDataSetBase.cpp +++ b/datapoollocal/LocalPoolDataSetBase.cpp @@ -44,7 +44,7 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner, LocalPoolDataSetBase::LocalPoolDataSetBase(sid_t sid, PoolVariableIF** registeredVariablesArray, const size_t maxNumberOfVariables): - PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) { + PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) { HasLocalDataPoolIF* hkOwner = objectManager->get( sid.objectId); if(hkOwner != nullptr) { @@ -96,15 +96,22 @@ ReturnValue_t LocalPoolDataSetBase::serializeWithValidityBuffer(uint8_t **buffer SerializeIF::Endianness streamEndianness) const { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; const uint8_t validityMaskSize = std::ceil(static_cast(fillCount)/8.0); + uint8_t* validityPtr = nullptr; +#ifdef _MSC_VER /* Use a std::vector here because MSVC will (rightly) not create a fixed size array with a non constant size specifier */ std::vector validityMask(validityMaskSize); + validityPtr = validityMask.data(); +#else + uint8_t validityMask[validityMaskSize]; + validityPtr = validityMask; +#endif uint8_t validBufferIndex = 0; uint8_t validBufferIndexBit = 0; for (uint16_t count = 0; count < fillCount; count++) { if(registeredVariables[count]->isValid()) { /* Set bit at correct position */ - bitutil::bitSet(validityMask.data() + validBufferIndex, validBufferIndexBit); + bitutil::bitSet(validityMask + validBufferIndex, validBufferIndexBit); } if(validBufferIndexBit == 7) { validBufferIndex ++; @@ -125,7 +132,7 @@ ReturnValue_t LocalPoolDataSetBase::serializeWithValidityBuffer(uint8_t **buffer return SerializeIF::BUFFER_TOO_SHORT; } // copy validity buffer to end - std::memcpy(*buffer, validityMask.data(), validityMaskSize); + std::memcpy(*buffer, validityPtr, validityMaskSize); *size += validityMaskSize; return result; } @@ -264,11 +271,9 @@ bool LocalPoolDataSetBase::getReportingEnabled() const { return reportingEnabled; } -void LocalPoolDataSetBase::initializePeriodicHelper( - float collectionInterval, dur_millis_t minimumPeriodicInterval, - bool isDiagnostics, uint8_t nonDiagIntervalFactor) { - periodicHelper->initialize(collectionInterval, minimumPeriodicInterval, - isDiagnostics, nonDiagIntervalFactor); +void LocalPoolDataSetBase::initializePeriodicHelper(float collectionInterval, + dur_millis_t minimumPeriodicInterval, uint8_t nonDiagIntervalFactor) { + periodicHelper->initialize(collectionInterval, minimumPeriodicInterval, nonDiagIntervalFactor); } void LocalPoolDataSetBase::setChanged(bool changed) { @@ -308,3 +313,12 @@ void LocalPoolDataSetBase::setAllVariablesReadOnly() { registeredVariables[idx]->setReadWriteMode(pool_rwm_t::VAR_READ); } } + +float LocalPoolDataSetBase::getCollectionInterval() const { + if(periodicHelper != nullptr) { + return periodicHelper->getCollectionIntervalInSeconds(); + } + else { + return 0.0; + } +} diff --git a/datapoollocal/LocalPoolDataSetBase.h b/datapoollocal/LocalPoolDataSetBase.h index 404509ae..ab67dc3f 100644 --- a/datapoollocal/LocalPoolDataSetBase.h +++ b/datapoollocal/LocalPoolDataSetBase.h @@ -166,6 +166,16 @@ public: object_id_t getCreatorObjectId(); + bool getReportingEnabled() const; + + /** + * Returns the current periodic HK generation interval this set + * belongs to a HK manager and the interval is not 0. Otherwise, + * returns 0.0 + * @return + */ + float getCollectionInterval() const; + protected: sid_t sid; //! This mutex is used if the data is created by one object only. @@ -180,11 +190,9 @@ protected: */ bool reportingEnabled = false; void setReportingEnabled(bool enabled); - bool getReportingEnabled() const; - void initializePeriodicHelper(float collectionInterval, - dur_millis_t minimumPeriodicInterval, - bool isDiagnostics, uint8_t nonDiagIntervalFactor = 5); + void initializePeriodicHelper(float collectionInterval, dur_millis_t minimumPeriodicInterval, + uint8_t nonDiagIntervalFactor = 5); /** * If the valid state of a dataset is always relevant to the whole From 12f47fdd0d2b6e005471344b32476145935e5bd3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 16 Mar 2021 15:32:58 +0100 Subject: [PATCH 070/230] removed commented code --- osal/windows/TmTcWinUdpBridge.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index f9c97caa..fd289ed8 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -112,8 +112,6 @@ ReturnValue_t TmTcWinUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { 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); char ipAddress [15]; sif::debug << "IP Address Sender: "<< inet_ntop(AF_INET, &clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; From 3f8fae24ddd47fb5f90d0f3e13c9acb2a9232819 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 16 Mar 2021 15:34:13 +0100 Subject: [PATCH 071/230] smaller tweak --- datapoollocal/LocalPoolDataSetBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datapoollocal/LocalPoolDataSetBase.cpp b/datapoollocal/LocalPoolDataSetBase.cpp index 6aa66f82..99c7a1cd 100644 --- a/datapoollocal/LocalPoolDataSetBase.cpp +++ b/datapoollocal/LocalPoolDataSetBase.cpp @@ -111,7 +111,7 @@ ReturnValue_t LocalPoolDataSetBase::serializeWithValidityBuffer(uint8_t **buffer for (uint16_t count = 0; count < fillCount; count++) { if(registeredVariables[count]->isValid()) { /* Set bit at correct position */ - bitutil::bitSet(validityMask + validBufferIndex, validBufferIndexBit); + bitutil::bitSet(validityPtr + validBufferIndex, validBufferIndexBit); } if(validBufferIndexBit == 7) { validBufferIndex ++; From 95096d83dec25af5f266fadb2dd73ce486bf3340 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 17 Mar 2021 15:43:01 +0100 Subject: [PATCH 072/230] fixed bug --- datapoollocal/LocalPoolDataSetBase.cpp | 2 +- osal/windows/TcWinTcpServer.cpp | 2 ++ osal/windows/TmTcWinUdpBridge.h | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/datapoollocal/LocalPoolDataSetBase.cpp b/datapoollocal/LocalPoolDataSetBase.cpp index 99c7a1cd..d7894048 100644 --- a/datapoollocal/LocalPoolDataSetBase.cpp +++ b/datapoollocal/LocalPoolDataSetBase.cpp @@ -103,7 +103,7 @@ ReturnValue_t LocalPoolDataSetBase::serializeWithValidityBuffer(uint8_t **buffer std::vector validityMask(validityMaskSize); validityPtr = validityMask.data(); #else - uint8_t validityMask[validityMaskSize]; + uint8_t validityMask[validityMaskSize] = {}; validityPtr = validityMask; #endif uint8_t validBufferIndex = 0; diff --git a/osal/windows/TcWinTcpServer.cpp b/osal/windows/TcWinTcpServer.cpp index 49c278c5..f68edfba 100644 --- a/osal/windows/TcWinTcpServer.cpp +++ b/osal/windows/TcWinTcpServer.cpp @@ -64,8 +64,10 @@ ReturnValue_t TcWinTcpServer::initialize() { retval = bind(listenerTcpSocket, addrResult->ai_addr, static_cast(addrResult->ai_addrlen)); if(retval == SOCKET_ERROR) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "TcWinTcpServer::TcWinTcpServer: Binding socket failed!" << std::endl; +#endif freeaddrinfo(addrResult); handleError(Protocol::TCP, ErrorSources::BIND_CALL); } diff --git a/osal/windows/TmTcWinUdpBridge.h b/osal/windows/TmTcWinUdpBridge.h index 51dcfe99..c2f7d6aa 100644 --- a/osal/windows/TmTcWinUdpBridge.h +++ b/osal/windows/TmTcWinUdpBridge.h @@ -3,6 +3,7 @@ #include "../../tmtcservices/TmTcBridge.h" +#include #include class TmTcWinUdpBridge: public TmTcBridge { From 1b8878a81f039bb813c718006c48e01b53191803 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 17 Mar 2021 15:46:17 +0100 Subject: [PATCH 073/230] more explicit --- datapoollocal/LocalPoolDataSetBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datapoollocal/LocalPoolDataSetBase.cpp b/datapoollocal/LocalPoolDataSetBase.cpp index d7894048..7f181c93 100644 --- a/datapoollocal/LocalPoolDataSetBase.cpp +++ b/datapoollocal/LocalPoolDataSetBase.cpp @@ -103,7 +103,7 @@ ReturnValue_t LocalPoolDataSetBase::serializeWithValidityBuffer(uint8_t **buffer std::vector validityMask(validityMaskSize); validityPtr = validityMask.data(); #else - uint8_t validityMask[validityMaskSize] = {}; + uint8_t validityMask[validityMaskSize] = {0}; validityPtr = validityMask; #endif uint8_t validBufferIndex = 0; From b41eb518e74d2803fde93ef87687b8f7c5979431 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 17 Mar 2021 23:28:01 +0100 Subject: [PATCH 074/230] improved internal error reporter --- internalError/InternalErrorReporter.cpp | 187 ++++++++++++------------ internalError/InternalErrorReporter.h | 87 +++++------ 2 files changed, 137 insertions(+), 137 deletions(-) diff --git a/internalError/InternalErrorReporter.cpp b/internalError/InternalErrorReporter.cpp index 7e5a316c..402071b2 100644 --- a/internalError/InternalErrorReporter.cpp +++ b/internalError/InternalErrorReporter.cpp @@ -3,19 +3,20 @@ #include "../ipc/QueueFactory.h" #include "../ipc/MutexFactory.h" #include "../serviceinterface/ServiceInterface.h" +#include "../datapool/PoolReadGuard.h" InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth): SystemObject(setObjectId), - commandQueue(QueueFactory::instance()-> - createMessageQueue(messageQueueDepth)), - poolManager(this, commandQueue), - internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID), - internalErrorDataset(this) { - mutex = MutexFactory::instance()->createMutex(); + commandQueue(QueueFactory::instance()-> + createMessageQueue(messageQueueDepth)), + poolManager(this, commandQueue), + internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID), + internalErrorDataset(this) { + mutex = MutexFactory::instance()->createMutex(); } InternalErrorReporter::~InternalErrorReporter() { - MutexFactory::instance()->deleteMutex(mutex); + MutexFactory::instance()->deleteMutex(mutex); } void InternalErrorReporter::setDiagnosticPrintout(bool enable) { @@ -23,126 +24,127 @@ void InternalErrorReporter::setDiagnosticPrintout(bool enable) { } ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) { - internalErrorDataset.read(timeoutType, timeoutMs); + CommandMessage message; + ReturnValue_t result = commandQueue->receiveMessage(&message); + if(result != MessageQueueIF::EMPTY) { + poolManager.handleHousekeepingMessage(&message); + } - uint32_t newQueueHits = getAndResetQueueHits(); - uint32_t newTmHits = getAndResetTmHits(); - uint32_t newStoreHits = getAndResetStoreHits(); + uint32_t newQueueHits = getAndResetQueueHits(); + uint32_t newTmHits = getAndResetTmHits(); + uint32_t newStoreHits = getAndResetStoreHits(); -#if FSFW_VERBOSE_LEVEL == 1 - if(diagnosticPrintout) { - if((newQueueHits > 0) or (newTmHits > 0) or (newStoreHits > 0)) { +#if FSFW_VERBOSE_LEVEL >= 1 + if(diagnosticPrintout) { + if((newQueueHits > 0) or (newTmHits > 0) or (newStoreHits > 0)) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::debug << "InternalErrorReporter::performOperation: Errors " - << "occured!" << std::endl; - sif::debug << "Queue errors: " << newQueueHits << std::endl; - sif::debug << "TM errors: " << newTmHits << std::endl; - sif::debug << "Store errors: " << newStoreHits << std::endl; + sif::debug << "InternalErrorReporter::performOperation: Errors " + << "occured!" << std::endl; + sif::debug << "Queue errors: " << newQueueHits << std::endl; + sif::debug << "TM errors: " << newTmHits << std::endl; + sif::debug << "Store errors: " << newStoreHits << std::endl; #else - sif::printDebug("InternalErrorReporter::performOperation: Errors occured!\n"); - sif::printDebug("Queue errors: %lu\n", static_cast(newQueueHits)); - sif::printDebug("TM errors: %lu\n", static_cast(newTmHits)); - sif::printDebug("Store errors: %lu\n", static_cast(newStoreHits)); + sif::printDebug("InternalErrorReporter::performOperation: Errors occured!\n"); + sif::printDebug("Queue errors: %lu\n", static_cast(newQueueHits)); + sif::printDebug("TM errors: %lu\n", static_cast(newTmHits)); + sif::printDebug("Store errors: %lu\n", static_cast(newStoreHits)); #endif - } - } + } + } #endif - internalErrorDataset.queueHits.value += newQueueHits; - internalErrorDataset.storeHits.value += newStoreHits; - internalErrorDataset.tmHits.value += newTmHits; - internalErrorDataset.setValidity(true, true); - internalErrorDataset.commit(timeoutType, timeoutMs); + PoolReadGuard readGuard(&internalErrorDataset); + internalErrorDataset.read(timeoutType, timeoutMs); + if(readGuard.getReadResult() == HasReturnvaluesIF::RETURN_OK) { + internalErrorDataset.queueHits.value += newQueueHits; + internalErrorDataset.storeHits.value += newStoreHits; + internalErrorDataset.tmHits.value += newTmHits; + internalErrorDataset.setValidity(true, true); + } - poolManager.performHkOperation(); - - CommandMessage message; - ReturnValue_t result = commandQueue->receiveMessage(&message); - if(result != MessageQueueIF::EMPTY) { - poolManager.handleHousekeepingMessage(&message); - } - return HasReturnvaluesIF::RETURN_OK; + poolManager.performHkOperation(); + return HasReturnvaluesIF::RETURN_OK; } void InternalErrorReporter::queueMessageNotSent() { - incrementQueueHits(); + incrementQueueHits(); } void InternalErrorReporter::lostTm() { - incrementTmHits(); + incrementTmHits(); } uint32_t InternalErrorReporter::getAndResetQueueHits() { - uint32_t value; - mutex->lockMutex(timeoutType, timeoutMs); - value = queueHits; - queueHits = 0; - mutex->unlockMutex(); - return value; + uint32_t value; + mutex->lockMutex(timeoutType, timeoutMs); + value = queueHits; + queueHits = 0; + mutex->unlockMutex(); + return value; } uint32_t InternalErrorReporter::getQueueHits() { - uint32_t value; - mutex->lockMutex(timeoutType, timeoutMs); - value = queueHits; - mutex->unlockMutex(); - return value; + uint32_t value; + mutex->lockMutex(timeoutType, timeoutMs); + value = queueHits; + mutex->unlockMutex(); + return value; } void InternalErrorReporter::incrementQueueHits() { - mutex->lockMutex(timeoutType, timeoutMs); - queueHits++; - mutex->unlockMutex(); + mutex->lockMutex(timeoutType, timeoutMs); + queueHits++; + mutex->unlockMutex(); } uint32_t InternalErrorReporter::getAndResetTmHits() { - uint32_t value; - mutex->lockMutex(timeoutType, timeoutMs); - value = tmHits; - tmHits = 0; - mutex->unlockMutex(); - return value; + uint32_t value; + mutex->lockMutex(timeoutType, timeoutMs); + value = tmHits; + tmHits = 0; + mutex->unlockMutex(); + return value; } uint32_t InternalErrorReporter::getTmHits() { - uint32_t value; - mutex->lockMutex(timeoutType, timeoutMs); - value = tmHits; - mutex->unlockMutex(); - return value; + uint32_t value; + mutex->lockMutex(timeoutType, timeoutMs); + value = tmHits; + mutex->unlockMutex(); + return value; } void InternalErrorReporter::incrementTmHits() { - mutex->lockMutex(timeoutType, timeoutMs); - tmHits++; - mutex->unlockMutex(); + mutex->lockMutex(timeoutType, timeoutMs); + tmHits++; + mutex->unlockMutex(); } void InternalErrorReporter::storeFull() { - incrementStoreHits(); + incrementStoreHits(); } uint32_t InternalErrorReporter::getAndResetStoreHits() { - uint32_t value; - mutex->lockMutex(timeoutType, timeoutMs); - value = storeHits; - storeHits = 0; - mutex->unlockMutex(); - return value; + uint32_t value; + mutex->lockMutex(timeoutType, timeoutMs); + value = storeHits; + storeHits = 0; + mutex->unlockMutex(); + return value; } uint32_t InternalErrorReporter::getStoreHits() { - uint32_t value; - mutex->lockMutex(timeoutType, timeoutMs); - value = storeHits; - mutex->unlockMutex(); - return value; + uint32_t value; + mutex->lockMutex(timeoutType, timeoutMs); + value = storeHits; + mutex->unlockMutex(); + return value; } void InternalErrorReporter::incrementStoreHits() { - mutex->lockMutex(timeoutType, timeoutMs); - storeHits++; - mutex->unlockMutex(); + mutex->lockMutex(timeoutType, timeoutMs); + storeHits++; + mutex->unlockMutex(); } object_id_t InternalErrorReporter::getObjectId() const { @@ -155,14 +157,11 @@ MessageQueueId_t InternalErrorReporter::getCommandQueue() const { ReturnValue_t InternalErrorReporter::initializeLocalDataPool( localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) { - localDataPoolMap.emplace(errorPoolIds::TM_HITS, - new PoolEntry()); - localDataPoolMap.emplace(errorPoolIds::QUEUE_HITS, - new PoolEntry()); - localDataPoolMap.emplace(errorPoolIds::STORE_HITS, - new PoolEntry()); - poolManager.subscribeForPeriodicPacket(internalErrorSid, false, - getPeriodicOperationFrequency(), true); + localDataPoolMap.emplace(errorPoolIds::TM_HITS, new PoolEntry()); + localDataPoolMap.emplace(errorPoolIds::QUEUE_HITS, new PoolEntry()); + localDataPoolMap.emplace(errorPoolIds::STORE_HITS, new PoolEntry()); + poolManager.subscribeForPeriodicPacket(internalErrorSid, false, getPeriodicOperationFrequency(), + true); internalErrorDataset.setValidity(true, true); return HasReturnvaluesIF::RETURN_OK; } @@ -192,9 +191,9 @@ ReturnValue_t InternalErrorReporter::initializeAfterTaskCreation() { } void InternalErrorReporter::setMutexTimeout(MutexIF::TimeoutType timeoutType, - uint32_t timeoutMs) { - this->timeoutType = timeoutType; - this->timeoutMs = timeoutMs; + uint32_t timeoutMs) { + this->timeoutType = timeoutType; + this->timeoutMs = timeoutMs; } LocalDataPoolManager* InternalErrorReporter::getHkManagerHandle() { diff --git a/internalError/InternalErrorReporter.h b/internalError/InternalErrorReporter.h index a237418e..580cb8f6 100644 --- a/internalError/InternalErrorReporter.h +++ b/internalError/InternalErrorReporter.h @@ -17,77 +17,78 @@ * All functions were kept virtual so this class can be extended easily * to store custom internal errors (e.g. communication interface errors). */ -class InternalErrorReporter: public SystemObject, - public ExecutableObjectIF, - public InternalErrorReporterIF, - public HasLocalDataPoolIF { +class InternalErrorReporter: + public SystemObject, + public ExecutableObjectIF, + public InternalErrorReporterIF, + public HasLocalDataPoolIF { public: - InternalErrorReporter(object_id_t setObjectId, - uint32_t messageQueueDepth = 5); + InternalErrorReporter(object_id_t setObjectId, + uint32_t messageQueueDepth = 5); - /** - * Enable diagnostic printout. Please note that this feature will - * only work if DEBUG has been supplied to the build defines. - * @param enable - */ - void setDiagnosticPrintout(bool enable); + /** + * Enable diagnostic printout. Please note that this feature will + * only work if DEBUG has been supplied to the build defines. + * @param enable + */ + void setDiagnosticPrintout(bool enable); - void setMutexTimeout(MutexIF::TimeoutType timeoutType, - uint32_t timeoutMs); + void setMutexTimeout(MutexIF::TimeoutType timeoutType, + uint32_t timeoutMs); - virtual ~InternalErrorReporter(); + virtual ~InternalErrorReporter(); virtual object_id_t getObjectId() const override; virtual MessageQueueId_t getCommandQueue() const override; virtual ReturnValue_t initializeLocalDataPool( - localpool::DataPool& localDataPoolMap, + localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) override; virtual dur_millis_t getPeriodicOperationFrequency() const override; virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; - LocalDataPoolManager* getHkManagerHandle() override; + LocalDataPoolManager* getHkManagerHandle() override; virtual ReturnValue_t initialize() override; virtual ReturnValue_t initializeAfterTaskCreation() override; - virtual ReturnValue_t performOperation(uint8_t opCode) override; + virtual ReturnValue_t performOperation(uint8_t opCode) override; - virtual void queueMessageNotSent(); + virtual void queueMessageNotSent(); - virtual void lostTm(); + virtual void lostTm(); - virtual void storeFull(); + virtual void storeFull(); - virtual void setTaskIF(PeriodicTaskIF* task) override; + virtual void setTaskIF(PeriodicTaskIF* task) override; protected: - MessageQueueIF* commandQueue; - LocalDataPoolManager poolManager; + MessageQueueIF* commandQueue; + LocalDataPoolManager poolManager; - PeriodicTaskIF* executingTask = nullptr; + PeriodicTaskIF* executingTask = nullptr; - MutexIF* mutex = nullptr; - MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; - uint32_t timeoutMs = 20; + MutexIF* mutex = nullptr; + MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; + uint32_t timeoutMs = 20; - sid_t internalErrorSid; - InternalErrorDataset internalErrorDataset; + sid_t internalErrorSid; + InternalErrorDataset internalErrorDataset; - bool diagnosticPrintout = true; + bool diagnosticPrintout = true; - uint32_t queueHits = 0; - uint32_t tmHits = 0; - uint32_t storeHits = 0; + uint32_t queueHits = 0; + uint32_t tmHits = 0; + uint32_t storeHits = 0; - uint32_t getAndResetQueueHits(); - uint32_t getQueueHits(); - void incrementQueueHits(); + uint32_t getAndResetQueueHits(); + uint32_t getQueueHits(); + void incrementQueueHits(); - uint32_t getAndResetTmHits(); - uint32_t getTmHits(); - void incrementTmHits(); + uint32_t getAndResetTmHits(); + uint32_t getTmHits(); + void incrementTmHits(); - uint32_t getAndResetStoreHits(); - uint32_t getStoreHits(); - void incrementStoreHits(); + uint32_t getAndResetStoreHits(); + uint32_t getStoreHits(); + void incrementStoreHits(); }; From a4ca61d8343dcc64fc4667d2ac3ad74045825059 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 18 Mar 2021 00:01:29 +0100 Subject: [PATCH 075/230] bugfix and printout improvement --- datapool/PoolDataSetBase.cpp | 8 ++++---- internalError/InternalErrorReporter.cpp | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/datapool/PoolDataSetBase.cpp b/datapool/PoolDataSetBase.cpp index bdca22c3..cd4eb426 100644 --- a/datapool/PoolDataSetBase.cpp +++ b/datapool/PoolDataSetBase.cpp @@ -61,11 +61,11 @@ ReturnValue_t PoolDataSetBase::read(MutexIF::TimeoutType timeoutType, } else { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "DataSet::read(): Call made in wrong position. Don't forget to commit" - " member datasets!" << std::endl; + sif::warning << "PoolDataSetBase::read: Call made in wrong position. Don't forget to " + "commit member datasets!" << std::endl; #else - sif::printError("DataSet::read(): Call made in wrong position. Don't forget to commit" - " member datasets!\n"); + sif::printWarning("PoolDataSetBase::read: Call made in wrong position. Don't forget to " + "commit member datasets!\n"); #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ result = SET_WAS_ALREADY_READ; } diff --git a/internalError/InternalErrorReporter.cpp b/internalError/InternalErrorReporter.cpp index 402071b2..af9acc0d 100644 --- a/internalError/InternalErrorReporter.cpp +++ b/internalError/InternalErrorReporter.cpp @@ -54,7 +54,6 @@ ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) { #endif PoolReadGuard readGuard(&internalErrorDataset); - internalErrorDataset.read(timeoutType, timeoutMs); if(readGuard.getReadResult() == HasReturnvaluesIF::RETURN_OK) { internalErrorDataset.queueHits.value += newQueueHits; internalErrorDataset.storeHits.value += newStoreHits; From aa849894c65309a269475dca704b6bddb07702b7 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 18 Mar 2021 20:09:19 +0100 Subject: [PATCH 076/230] tiny form improvement --- datapoollocal/LocalPoolDataSetBase.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/datapoollocal/LocalPoolDataSetBase.cpp b/datapoollocal/LocalPoolDataSetBase.cpp index 7f181c93..a72e9db1 100644 --- a/datapoollocal/LocalPoolDataSetBase.cpp +++ b/datapoollocal/LocalPoolDataSetBase.cpp @@ -58,8 +58,7 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(sid_t sid, PoolVariableIF** registere this->sid = sid; } -LocalPoolDataSetBase::LocalPoolDataSetBase( - PoolVariableIF **registeredVariablesArray, +LocalPoolDataSetBase::LocalPoolDataSetBase(PoolVariableIF **registeredVariablesArray, const size_t maxNumberOfVariables, bool protectEveryReadCommitCall): PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) { this->setReadCommitProtectionBehaviour(protectEveryReadCommitCall); From fe2b3a01cf73b2dec12699365a4e5bb9acb689c2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 20 Mar 2021 12:38:51 +0100 Subject: [PATCH 077/230] important bugfix --- osal/windows/TmTcWinUdpBridge.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index fd289ed8..8755c84a 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -58,6 +58,9 @@ ReturnValue_t TmTcWinUdpBridge::initialize() { hints.ai_family = AF_INET; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; + /* See: + https://docs.microsoft.com/en-us/windows/win32/api/ws2tcpip/nf-ws2tcpip-getaddrinfo + for information about AI_PASSIVE. */ hints.ai_flags = AI_PASSIVE; /* Set up UDP socket: @@ -151,11 +154,9 @@ void TmTcWinUdpBridge::checkAndSetClientAddress(sockaddr_in& newAddress) { #endif 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 to reply to */ + clientAddress = newAddress; + clientAddressLen = sizeof(clientAddress); } void TmTcWinUdpBridge::setMutexProperties(MutexIF::TimeoutType timeoutType, From e44f8bfea38f5e876328af9d26806dc4d94bf8e8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 20 Mar 2021 12:40:25 +0100 Subject: [PATCH 078/230] important bugfixes --- osal/linux/TmTcUnixUdpBridge.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/osal/linux/TmTcUnixUdpBridge.cpp b/osal/linux/TmTcUnixUdpBridge.cpp index 2f620849..fa7913ea 100644 --- a/osal/linux/TmTcUnixUdpBridge.cpp +++ b/osal/linux/TmTcUnixUdpBridge.cpp @@ -150,11 +150,9 @@ void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in& newAddress) { #endif 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 to reply to. */ + clientAddress = newAddress; + clientAddressLen = sizeof(clientAddress); } void TmTcUnixUdpBridge::setMutexProperties(MutexIF::TimeoutType timeoutType, From 0da95b75a230e5e12dd0bb15f6ba8e4813f9f143 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 20 Mar 2021 12:49:15 +0100 Subject: [PATCH 079/230] fixed for hosted OSAL --- osal/host/MessageQueue.cpp | 8 +++----- osal/host/QueueMapManager.cpp | 4 ++-- osal/windows/TmTcWinUdpBridge.cpp | 3 ++- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/osal/host/MessageQueue.cpp b/osal/host/MessageQueue.cpp index dfc045e8..18272a68 100644 --- a/osal/host/MessageQueue.cpp +++ b/osal/host/MessageQueue.cpp @@ -3,7 +3,7 @@ #include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../ipc/MutexFactory.h" -#include "../../ipc/MutexHelper.h" +#include "../../ipc/MutexGuard.h" MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize): messageSize(maxMessageSize), messageDepth(messageDepth) { @@ -63,9 +63,7 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { if(messageQueue.empty()) { return MessageQueueIF::EMPTY; } - // not sure this will work.. - //*message = std::move(messageQueue.front()); - MutexHelper mutexLock(queueLock, MutexIF::TimeoutType::WAITING, 20); + MutexGuard mutexLock(queueLock, MutexIF::TimeoutType::WAITING, 20); MessageQueueMessage* currentMessage = &messageQueue.front(); std::copy(currentMessage->getBuffer(), currentMessage->getBuffer() + messageSize, message->getBuffer()); @@ -130,7 +128,7 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, return HasReturnvaluesIF::RETURN_FAILED; } if(targetQueue->messageQueue.size() < targetQueue->messageDepth) { - MutexHelper mutexLock(targetQueue->queueLock, + MutexGuard mutexLock(targetQueue->queueLock, MutexIF::TimeoutType::WAITING, 20); // not ideal, works for now though. MessageQueueMessage* mqmMessage = diff --git a/osal/host/QueueMapManager.cpp b/osal/host/QueueMapManager.cpp index 2a54f813..b50d62dc 100644 --- a/osal/host/QueueMapManager.cpp +++ b/osal/host/QueueMapManager.cpp @@ -2,7 +2,7 @@ #include "../../serviceinterface/ServiceInterface.h" #include "../../ipc/MutexFactory.h" -#include "../../ipc/MutexHelper.h" +#include "../../ipc/MutexGuard.h" QueueMapManager* QueueMapManager::mqManagerInstance = nullptr; @@ -43,7 +43,7 @@ ReturnValue_t QueueMapManager::addMessageQueue( MessageQueueIF* QueueMapManager::getMessageQueue( MessageQueueId_t messageQueueId) const { - MutexHelper(mapLock, MutexIF::TimeoutType::WAITING, 50); + MutexGuard(mapLock, MutexIF::TimeoutType::WAITING, 50); auto queueIter = queueMap.find(messageQueueId); if(queueIter != queueMap.end()) { return queueIter->second; diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index 94805cdc..9e91db2b 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -1,5 +1,6 @@ -#include #include "TmTcWinUdpBridge.h" +#include + TmTcWinUdpBridge::TmTcWinUdpBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId, object_id_t tcStoreId, From 8f17d6623af0a2d6448c8255c471820d2836a894 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 20 Mar 2021 12:54:05 +0100 Subject: [PATCH 080/230] removed duplicate include --- osal/windows/TmTcWinUdpBridge.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index 67e908a0..a7201bb0 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -1,7 +1,6 @@ #include "TmTcWinUdpBridge.h" #include "tcpipHelpers.h" -#include #include #include From 951eb40e96c933d3524114037113f68c455b5200 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 20 Mar 2021 13:14:30 +0100 Subject: [PATCH 081/230] relativ include --- osal/windows/TmTcWinUdpBridge.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index 4959705a..03ca52cd 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -1,8 +1,8 @@ #include "TmTcWinUdpBridge.h" #include "tcpipHelpers.h" -#include -#include +#include "../../ipc/MutexGuard.h" +#include "../../serviceinterface/ServiceInterface.h" #include From 83d0db824289b28dbad81cce0c80276c4fc839c8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 20 Mar 2021 15:53:43 +0100 Subject: [PATCH 082/230] fixed udp bridge --- osal/linux/TmTcUnixUdpBridge.cpp | 10 ---------- osal/linux/TmTcUnixUdpBridge.h | 4 ---- 2 files changed, 14 deletions(-) diff --git a/osal/linux/TmTcUnixUdpBridge.cpp b/osal/linux/TmTcUnixUdpBridge.cpp index fa7913ea..767c3cfe 100644 --- a/osal/linux/TmTcUnixUdpBridge.cpp +++ b/osal/linux/TmTcUnixUdpBridge.cpp @@ -103,11 +103,6 @@ ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { /* 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: "<< @@ -160,8 +155,3 @@ void TmTcUnixUdpBridge::setMutexProperties(MutexIF::TimeoutType timeoutType, 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..c39c43f7 100644 --- a/osal/linux/TmTcUnixUdpBridge.h +++ b/osal/linux/TmTcUnixUdpBridge.h @@ -30,8 +30,6 @@ public: void checkAndSetClientAddress(sockaddr_in& clientAddress); - void setClientAddressToAny(bool ipAddrAnySet); - protected: virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override; @@ -42,8 +40,6 @@ private: 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; From d625642abcc481b73c06a42c0b87fa614d36294b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 21 Mar 2021 00:30:33 +0100 Subject: [PATCH 083/230] created common OSAL stuff to unify UDP code --- osal/common/CMakeLists.txt | 19 +++++-- osal/common/TcpIpBase.cpp | 52 +++++++++++++++++++ osal/common/TcpIpBase.h | 49 +++++++++++++++++ .../TcpTmTcServer.cpp} | 42 +++++++-------- .../TcpTmTcServer.h} | 10 ++-- .../UdpTcPollingTask.cpp} | 41 +++++++++------ .../UdpTcPollingTask.h} | 12 +++-- .../UdpTmTcBridge.cpp} | 50 +++++++++++------- .../UdpTmTcBridge.h} | 13 ++--- osal/common/tcpipCommon.h | 3 +- osal/{windows => common}/tcpipHelpers.h | 2 +- osal/windows/CMakeLists.txt | 8 --- osal/windows/tcpipHelpers.cpp | 2 +- 13 files changed, 214 insertions(+), 89 deletions(-) create mode 100644 osal/common/TcpIpBase.cpp create mode 100644 osal/common/TcpIpBase.h rename osal/{windows/TcWinTcpServer.cpp => common/TcpTmTcServer.cpp} (73%) rename osal/{windows/TcWinTcpServer.h => common/TcpTmTcServer.h} (84%) rename osal/{windows/TcWinUdpPollingTask.cpp => common/UdpTcPollingTask.cpp} (75%) rename osal/{windows/TcWinUdpPollingTask.h => common/UdpTcPollingTask.h} (88%) rename osal/{windows/TmTcWinUdpBridge.cpp => common/UdpTmTcBridge.cpp} (77%) rename osal/{windows/TmTcWinUdpBridge.h => common/UdpTmTcBridge.h} (82%) rename osal/{windows => common}/tcpipHelpers.h (89%) diff --git a/osal/common/CMakeLists.txt b/osal/common/CMakeLists.txt index b77985fb..af76484d 100644 --- a/osal/common/CMakeLists.txt +++ b/osal/common/CMakeLists.txt @@ -1,3 +1,16 @@ -target_sources(${LIB_FSFW_NAME} PRIVATE - tcpipCommon.cpp -) +if(DEFINED WIN32 OR DEFINED UNIX) + target_sources(${LIB_FSFW_NAME} PRIVATE + tcpipCommon.cpp + TcpIpBase.cpp + UdpTcPollingTask.cpp + UdpTmTcBridge.cpp + TcpTmTcServer.cpp + ) +endif() + +if(WIN32) + target_link_libraries(${LIB_FSFW_NAME} PRIVATE + wsock32 + ws2_32 + ) +endif() \ No newline at end of file diff --git a/osal/common/TcpIpBase.cpp b/osal/common/TcpIpBase.cpp new file mode 100644 index 00000000..03de81b1 --- /dev/null +++ b/osal/common/TcpIpBase.cpp @@ -0,0 +1,52 @@ +#include "TcpIpBase.h" + +#ifdef __unix__ + +#include + +#endif + +TcpIpBase::TcpIpBase() { + closeSocket(serverSocket); +} + +TcpIpBase::~TcpIpBase() { +#ifdef _WIN32 + WSACleanup(); +#endif +} + + +int TcpIpBase::closeSocket(socket_t socket) { +#ifdef _WIN32 + return closesocket(socket); +#elif defined(__unix__) + return close(socket) +#endif +} + +int TcpIpBase::getLastSocketError() { +#ifdef _WIN32 + return WSAGetLastError(); +#elif defined(__unix__) + return errno; +#endif +} + +ReturnValue_t TcpIpBase::initialize() { +#ifdef _WIN32 + /* 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; + } +#endif + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/osal/common/TcpIpBase.h b/osal/common/TcpIpBase.h new file mode 100644 index 00000000..8da217bc --- /dev/null +++ b/osal/common/TcpIpBase.h @@ -0,0 +1,49 @@ +#ifndef FSFW_OSAL_COMMON_TCPIPIF_H_ +#define FSFW_OSAL_COMMON_TCPIPIF_H_ + +#include + +#ifdef _WIN32 + +#include + +#elif defined(__unix__) + + +#endif + +class TcpIpBase { +protected: + +#ifdef _WIN32 + static constexpr int SHUT_RECV = SD_RECEIVE; + static constexpr int SHUT_SEND = SD_SEND; + static constexpr int SHUT_BOTH = SD_BOTH; + + using socket_t = SOCKET; +#elif defined(__unix__) + using socket_t = int; + + static constexpr int INVALID_SOCKET = -1; + static constexpr int SOCKET_ERROR = -1; + + static constexpr int SHUT_RECV = SHUT_RD; + static constexpr int SHUT_SEND = SHUT_WR; + static constexpr int SHUT_BOTH = SHUT_RDWR; +#endif + + TcpIpBase(); + virtual ~TcpIpBase(); + + ReturnValue_t initialize(); + + int closeSocket(socket_t socket); + + int getLastSocketError(); + + socket_t serverSocket = 0; + +}; + + +#endif /* FSFW_OSAL_COMMON_TCPIPIF_H_ */ diff --git a/osal/windows/TcWinTcpServer.cpp b/osal/common/TcpTmTcServer.cpp similarity index 73% rename from osal/windows/TcWinTcpServer.cpp rename to osal/common/TcpTmTcServer.cpp index f68edfba..320b937d 100644 --- a/osal/windows/TcWinTcpServer.cpp +++ b/osal/common/TcpTmTcServer.cpp @@ -1,14 +1,16 @@ -#include "TcWinTcpServer.h" +#include "TcpTmTcServer.h" #include "tcpipHelpers.h" #include "../../serviceinterface/ServiceInterface.h" +#ifdef _WIN32 #include #include +#endif -const std::string TcWinTcpServer::DEFAULT_TCP_SERVER_PORT = "7301"; -const std::string TcWinTcpServer::DEFAULT_TCP_CLIENT_PORT = "7302"; +const std::string TcpTmTcServer::DEFAULT_TCP_SERVER_PORT = "7301"; +const std::string TcpTmTcServer::DEFAULT_TCP_CLIENT_PORT = "7302"; -TcWinTcpServer::TcWinTcpServer(object_id_t objectId, object_id_t tmtcUnixUdpBridge, +TcpTmTcServer::TcpTmTcServer(object_id_t objectId, object_id_t tmtcUnixUdpBridge, std::string customTcpServerPort): SystemObject(objectId), tcpPort(customTcpServerPort) { if(tcpPort == "") { @@ -16,23 +18,17 @@ TcWinTcpServer::TcWinTcpServer(object_id_t objectId, object_id_t tmtcUnixUdpBrid } } -ReturnValue_t TcWinTcpServer::initialize() { +ReturnValue_t TcpTmTcServer::initialize() { using namespace tcpip; + + ReturnValue_t result = TcpIpBase::initialize(); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + 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; - } + struct addrinfo hints = { 0 }; ZeroMemory(&hints, sizeof (hints)); hints.ai_family = AF_INET; @@ -43,7 +39,7 @@ ReturnValue_t TcWinTcpServer::initialize() { 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!" << + sif::warning << "TcWinTcpServer::TcpTmTcServer: Retrieving address info failed!" << std::endl; #endif handleError(Protocol::TCP, ErrorSources::GETADDRINFO_CALL); @@ -65,7 +61,7 @@ ReturnValue_t TcWinTcpServer::initialize() { retval = bind(listenerTcpSocket, addrResult->ai_addr, static_cast(addrResult->ai_addrlen)); if(retval == SOCKET_ERROR) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "TcWinTcpServer::TcWinTcpServer: Binding socket failed!" << + sif::warning << "TcWinTcpServer::TcpTmTcServer: Binding socket failed!" << std::endl; #endif freeaddrinfo(addrResult); @@ -77,12 +73,12 @@ ReturnValue_t TcWinTcpServer::initialize() { } -TcWinTcpServer::~TcWinTcpServer() { +TcpTmTcServer::~TcpTmTcServer() { closesocket(listenerTcpSocket); WSACleanup(); } -ReturnValue_t TcWinTcpServer::performOperation(uint8_t opCode) { +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; @@ -110,7 +106,7 @@ ReturnValue_t TcWinTcpServer::performOperation(uint8_t opCode) { receptionBuffer.size(), 0); if(retval > 0) { #if FSFW_TCP_RCV_WIRETAPPING_ENABLED == 1 - sif::info << "TcWinTcpServer::performOperation: Received " << retval << " bytes." + sif::info << "TcpTmTcServer::performOperation: Received " << retval << " bytes." std::endl; #endif handleError(Protocol::TCP, ErrorSources::RECV_CALL, 500); diff --git a/osal/windows/TcWinTcpServer.h b/osal/common/TcpTmTcServer.h similarity index 84% rename from osal/windows/TcWinTcpServer.h rename to osal/common/TcpTmTcServer.h index bd9f3576..ff6eb610 100644 --- a/osal/windows/TcWinTcpServer.h +++ b/osal/common/TcpTmTcServer.h @@ -1,6 +1,7 @@ #ifndef FSFW_OSAL_WINDOWS_TCWINTCPSERVER_H_ #define FSFW_OSAL_WINDOWS_TCWINTCPSERVER_H_ +#include "TcpIpBase.h" #include "../../objectmanager/SystemObject.h" #include "../../tasks/ExecutableObjectIF.h" @@ -15,17 +16,18 @@ * @details * Based on: https://docs.microsoft.com/en-us/windows/win32/winsock/complete-server-code */ -class TcWinTcpServer: +class TcpTmTcServer: public SystemObject, + public TcpIpBase, 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, + TcpTmTcServer(object_id_t objectId, object_id_t tmtcUnixUdpBridge, std::string customTcpServerPort = ""); - virtual~ TcWinTcpServer(); + virtual~ TcpTmTcServer(); ReturnValue_t initialize() override; ReturnValue_t performOperation(uint8_t opCode) override; @@ -33,7 +35,7 @@ public: private: std::string tcpPort; - SOCKET listenerTcpSocket = 0; + socket_t listenerTcpSocket = 0; struct sockaddr_in tcpAddress; int tcpAddrLen = sizeof(tcpAddress); int currentBacklog = 3; diff --git a/osal/windows/TcWinUdpPollingTask.cpp b/osal/common/UdpTcPollingTask.cpp similarity index 75% rename from osal/windows/TcWinUdpPollingTask.cpp rename to osal/common/UdpTcPollingTask.cpp index 980404f9..506f1c98 100644 --- a/osal/windows/TcWinUdpPollingTask.cpp +++ b/osal/common/UdpTcPollingTask.cpp @@ -1,4 +1,4 @@ -#include "TcWinUdpPollingTask.h" +#include "UdpTcPollingTask.h" #include "tcpipHelpers.h" #include "../../globalfunctions/arrayprinter.h" #include "../../serviceinterface/ServiceInterfaceStream.h" @@ -8,7 +8,7 @@ //! Debugging preprocessor define. #define FSFW_UDP_RCV_WIRETAPPING_ENABLED 0 -TcWinUdpPollingTask::TcWinUdpPollingTask(object_id_t objectId, +UdpTcPollingTask::UdpTcPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge, size_t frameSize, double timeoutSeconds): SystemObject(objectId), tmtcBridgeId(tmtcUnixUdpBridge) { @@ -32,9 +32,9 @@ TcWinUdpPollingTask::TcWinUdpPollingTask(object_id_t objectId, } } -TcWinUdpPollingTask::~TcWinUdpPollingTask() {} +UdpTcPollingTask::~UdpTcPollingTask() {} -ReturnValue_t TcWinUdpPollingTask::performOperation(uint8_t opCode) { +ReturnValue_t UdpTcPollingTask::performOperation(uint8_t opCode) { /* Sender Address is cached here. */ struct sockaddr_in senderAddress; int senderAddressSize = sizeof(senderAddress); @@ -52,13 +52,13 @@ ReturnValue_t TcWinUdpPollingTask::performOperation(uint8_t opCode) { if(bytesReceived == SOCKET_ERROR) { /* Handle error */ #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TcWinUdpPollingTask::performOperation: Reception error." << std::endl; + sif::error << "UdpTcPollingTask::performOperation: Reception error." << std::endl; #endif tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::RECVFROM_CALL, 1000); continue; } #if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1 - sif::debug << "TcWinUdpPollingTask::performOperation: " << bytesReceived << + sif::debug << "UdpTcPollingTask::performOperation: " << bytesReceived << " bytes received" << std::endl; #endif @@ -72,7 +72,7 @@ ReturnValue_t TcWinUdpPollingTask::performOperation(uint8_t opCode) { } -ReturnValue_t TcWinUdpPollingTask::handleSuccessfullTcRead(size_t bytesRead) { +ReturnValue_t UdpTcPollingTask::handleSuccessfullTcRead(size_t bytesRead) { store_address_t storeId; #if FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1 @@ -83,7 +83,7 @@ ReturnValue_t TcWinUdpPollingTask::handleSuccessfullTcRead(size_t bytesRead) { if (result != HasReturnvaluesIF::RETURN_OK) { #if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning<< "TcWinUdpPollingTask::transferPusToSoftwareBus: Data storage failed." << + sif::warning<< "UdpTcPollingTask::transferPusToSoftwareBus: Data storage failed." << std::endl; sif::warning << "Packet size: " << bytesRead << std::endl; #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ @@ -97,7 +97,7 @@ ReturnValue_t TcWinUdpPollingTask::handleSuccessfullTcRead(size_t bytesRead) { if (result != HasReturnvaluesIF::RETURN_OK) { #if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "TcWinUdpPollingTask::handleSuccessfullTcRead: " + sif::warning << "UdpTcPollingTask::handleSuccessfullTcRead: " " Sending message to queue failed" << std::endl; #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ #endif /* FSFW_VERBOSE_LEVEL >= 1 */ @@ -106,37 +106,44 @@ ReturnValue_t TcWinUdpPollingTask::handleSuccessfullTcRead(size_t bytesRead) { return result; } -ReturnValue_t TcWinUdpPollingTask::initialize() { +ReturnValue_t UdpTcPollingTask::initialize() { tcStore = objectManager->get(objects::TC_STORE); if (tcStore == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TcWinUdpPollingTask::initialize: TC store uninitialized!" << std::endl; + sif::error << "UdpTcPollingTask::initialize: TC store uninitialized!" << std::endl; #endif return ObjectManagerIF::CHILD_INIT_FAILED; } - tmtcBridge = objectManager->get(tmtcBridgeId); + tmtcBridge = objectManager->get(tmtcBridgeId); if(tmtcBridge == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TcWinUdpPollingTask::initialize: Invalid TMTC bridge object!" << + sif::error << "UdpTcPollingTask::initialize: Invalid TMTC bridge object!" << std::endl; #endif return ObjectManagerIF::CHILD_INIT_FAILED; } + + ReturnValue_t result = TcpIpBase::initialize(); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t TcWinUdpPollingTask::initializeAfterTaskCreation() { +ReturnValue_t UdpTcPollingTask::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*/ + ensures that it is set up regardless of which class was initialized first */ serverUdpSocket = tmtcBridge->serverSocket; return HasReturnvaluesIF::RETURN_OK; } -void TcWinUdpPollingTask::setTimeout(double timeoutSeconds) { +void UdpTcPollingTask::setTimeout(double timeoutSeconds) { +#ifdef _WIN32 DWORD timeoutMs = timeoutSeconds * 1000.0; int result = setsockopt(serverUdpSocket, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast(&timeoutMs), sizeof(DWORD)); @@ -146,4 +153,6 @@ void TcWinUdpPollingTask::setTimeout(double timeoutSeconds) { "receive timeout failed with " << strerror(errno) << std::endl; #endif } +#elif defined(__unix__) +#endif } diff --git a/osal/windows/TcWinUdpPollingTask.h b/osal/common/UdpTcPollingTask.h similarity index 88% rename from osal/windows/TcWinUdpPollingTask.h rename to osal/common/UdpTcPollingTask.h index 35e3a701..6b11cc5a 100644 --- a/osal/windows/TcWinUdpPollingTask.h +++ b/osal/common/UdpTcPollingTask.h @@ -1,7 +1,7 @@ #ifndef FSFW_OSAL_WINDOWS_TCSOCKETPOLLINGTASK_H_ #define FSFW_OSAL_WINDOWS_TCSOCKETPOLLINGTASK_H_ -#include "TmTcWinUdpBridge.h" +#include "UdpTmTcBridge.h" #include "../../objectmanager/SystemObject.h" #include "../../tasks/ExecutableObjectIF.h" #include "../../storagemanager/StorageManagerIF.h" @@ -17,7 +17,9 @@ * This class caches the IP address of the sender. It is assumed there * is only one sender for now. */ -class TcWinUdpPollingTask: public SystemObject, +class UdpTcPollingTask: + public TcpIpBase, + public SystemObject, public ExecutableObjectIF { friend class TmTcWinUdpBridge; public: @@ -25,9 +27,9 @@ public: //! 0.5 default milliseconds timeout for now. static constexpr timeval DEFAULT_TIMEOUT = {0, 500}; - TcWinUdpPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge, + UdpTcPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge, size_t frameSize = 0, double timeoutSeconds = -1); - virtual~ TcWinUdpPollingTask(); + virtual~ UdpTcPollingTask(); /** * Turn on optional timeout for UDP polling. In the default mode, @@ -46,7 +48,7 @@ protected: private: //! TMTC bridge is cached. object_id_t tmtcBridgeId = objects::NO_OBJECT; - TmTcWinUdpBridge* tmtcBridge = nullptr; + UdpTmTcBridge* tmtcBridge = nullptr; MessageQueueId_t targetTcDestination = MessageQueueIF::NO_QUEUE; //! See: https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-recvfrom diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/common/UdpTmTcBridge.cpp similarity index 77% rename from osal/windows/TmTcWinUdpBridge.cpp rename to osal/common/UdpTmTcBridge.cpp index 8755c84a..be586745 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/common/UdpTmTcBridge.cpp @@ -1,16 +1,24 @@ -#include "TmTcWinUdpBridge.h" #include "tcpipHelpers.h" #include #include +#include + +#ifdef _WIN32 #include +#elif defined(__unix__) + +#include + +#endif + //! Debugging preprocessor define. #define FSFW_UDP_SEND_WIRETAPPING_ENABLED 0 -const std::string TmTcWinUdpBridge::DEFAULT_UDP_SERVER_PORT = tcpip::DEFAULT_UDP_SERVER_PORT; +const std::string UdpTmTcBridge::DEFAULT_UDP_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; -TmTcWinUdpBridge::TmTcWinUdpBridge(object_id_t objectId, object_id_t tcDestination, +UdpTmTcBridge::UdpTmTcBridge(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 == "") { @@ -24,16 +32,18 @@ TmTcWinUdpBridge::TmTcWinUdpBridge(object_id_t objectId, object_id_t tcDestinati communicationLinkUp = false; } -ReturnValue_t TmTcWinUdpBridge::initialize() { +ReturnValue_t UdpTmTcBridge::initialize() { ReturnValue_t result = TmTcBridge::initialize(); if(result != HasReturnvaluesIF::RETURN_OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TmTcWinUdpBridge::initialize: TmTcBridge initialization failed!" + sif::error << "TmTcUdpBridge::initialize: TmTcBridge initialization failed!" << std::endl; #endif return result; } + +#ifdef _WIN32 /* Initiates Winsock DLL. */ WSAData wsaData; WORD wVersionRequested = MAKEWORD(2, 2); @@ -42,26 +52,28 @@ ReturnValue_t TmTcWinUdpBridge::initialize() { /* 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: " << + sif::error << "TmTcUdpBridge::TmTcUdpBridge: WSAStartup failed with error: " << err << std::endl; #else - sif::printError("TmTcWinUdpBridge::TmTcWinUdpBridge: WSAStartup failed with error: %d\n", + sif::printError("TmTcUdpBridge::TmTcUdpBridge: WSAStartup failed with error: %d\n", err); #endif return HasReturnvaluesIF::RETURN_FAILED; } +#endif struct addrinfo *addrResult = nullptr; - struct addrinfo hints; + struct addrinfo hints = { 0 }; - ZeroMemory(&hints, sizeof (hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; +#ifdef _WIN32 /* See: https://docs.microsoft.com/en-us/windows/win32/api/ws2tcpip/nf-ws2tcpip-getaddrinfo for information about AI_PASSIVE. */ hints.ai_flags = AI_PASSIVE; +#endif /* Set up UDP socket: https://en.wikipedia.org/wiki/Getaddrinfo @@ -70,7 +82,7 @@ ReturnValue_t TmTcWinUdpBridge::initialize() { 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!" << + sif::warning << "TmTcUdpBridge::TmTcUdpBridge: Retrieving address info failed!" << std::endl; #endif return HasReturnvaluesIF::RETURN_FAILED; @@ -79,7 +91,7 @@ ReturnValue_t TmTcWinUdpBridge::initialize() { 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!" << + sif::warning << "TmTcUdpBridge::TmTcUdpBridge: Could not open UDP socket!" << std::endl; #endif freeaddrinfo(addrResult); @@ -90,7 +102,7 @@ ReturnValue_t TmTcWinUdpBridge::initialize() { 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 " + sif::error << "TmTcUdpBridge::TmTcUdpBridge: Could not bind " "local port (" << udpServerPort << ") to server socket!" << std::endl; #endif freeaddrinfo(addrResult); @@ -100,15 +112,13 @@ ReturnValue_t TmTcWinUdpBridge::initialize() { return HasReturnvaluesIF::RETURN_OK; } -TmTcWinUdpBridge::~TmTcWinUdpBridge() { +UdpTmTcBridge::~UdpTmTcBridge() { if(mutex != nullptr) { MutexFactory::instance()->deleteMutex(mutex); } - closesocket(serverSocket); - WSACleanup(); } -ReturnValue_t TmTcWinUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { +ReturnValue_t UdpTmTcBridge::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 */ @@ -130,18 +140,18 @@ ReturnValue_t TmTcWinUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { ); if(bytesSent == SOCKET_ERROR) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "TmTcWinUdpBridge::sendTm: Send operation failed." << std::endl; + sif::warning << "TmTcUdpBridge::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" + sif::debug << "TmTcUdpBridge::sendTm: " << bytesSent << " bytes were" " sent." << std::endl; #endif return HasReturnvaluesIF::RETURN_OK; } -void TmTcWinUdpBridge::checkAndSetClientAddress(sockaddr_in& newAddress) { +void UdpTmTcBridge::checkAndSetClientAddress(sockaddr_in& newAddress) { /* The target address can be set by different threads so this lock ensures thread-safety */ MutexGuard lock(mutex, timeoutType, mutexTimeoutMs); @@ -159,7 +169,7 @@ void TmTcWinUdpBridge::checkAndSetClientAddress(sockaddr_in& newAddress) { clientAddressLen = sizeof(clientAddress); } -void TmTcWinUdpBridge::setMutexProperties(MutexIF::TimeoutType timeoutType, +void UdpTmTcBridge::setMutexProperties(MutexIF::TimeoutType timeoutType, dur_millis_t timeoutMs) { this->timeoutType = timeoutType; this->mutexTimeoutMs = timeoutMs; diff --git a/osal/windows/TmTcWinUdpBridge.h b/osal/common/UdpTmTcBridge.h similarity index 82% rename from osal/windows/TmTcWinUdpBridge.h rename to osal/common/UdpTmTcBridge.h index c2f7d6aa..fcf2baec 100644 --- a/osal/windows/TmTcWinUdpBridge.h +++ b/osal/common/UdpTmTcBridge.h @@ -1,20 +1,22 @@ #ifndef FSFW_OSAL_WINDOWS_TMTCWINUDPBRIDGE_H_ #define FSFW_OSAL_WINDOWS_TMTCWINUDPBRIDGE_H_ +#include "TcpIpBase.h" #include "../../tmtcservices/TmTcBridge.h" #include -#include -class TmTcWinUdpBridge: public TmTcBridge { - friend class TcWinUdpPollingTask; +class UdpTmTcBridge: + public TmTcBridge, + public TcpIpBase { + friend class UdpTcPollingTask; public: /* The ports chosen here should not be used by any other process. */ static const std::string DEFAULT_UDP_SERVER_PORT; - TmTcWinUdpBridge(object_id_t objectId, object_id_t tcDestination, + UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId, object_id_t tcStoreId, std::string udpServerPort = ""); - virtual~ TmTcWinUdpBridge(); + virtual~ UdpTmTcBridge(); /** * Set properties of internal mutex. @@ -29,7 +31,6 @@ protected: virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override; private: - SOCKET serverSocket = 0; std::string udpServerPort; struct sockaddr_in clientAddress; diff --git a/osal/common/tcpipCommon.h b/osal/common/tcpipCommon.h index 9b38c9fb..dc5ada52 100644 --- a/osal/common/tcpipCommon.h +++ b/osal/common/tcpipCommon.h @@ -6,8 +6,7 @@ namespace tcpip { -const char* const DEFAULT_UDP_SERVER_PORT = "7301"; -const char* const DEFAULT_TCP_SERVER_PORT = "7303"; +const char* const DEFAULT_SERVER_PORT = "7301"; enum class Protocol { UDP, diff --git a/osal/windows/tcpipHelpers.h b/osal/common/tcpipHelpers.h similarity index 89% rename from osal/windows/tcpipHelpers.h rename to osal/common/tcpipHelpers.h index 01f009b9..9764a93f 100644 --- a/osal/windows/tcpipHelpers.h +++ b/osal/common/tcpipHelpers.h @@ -2,7 +2,7 @@ #define FSFW_OSAL_WINDOWS_TCPIPHELPERS_H_ #include "../../timemanager/clockDefinitions.h" -#include "../common/tcpipCommon.h" +#include "tcpipCommon.h" namespace tcpip { diff --git a/osal/windows/CMakeLists.txt b/osal/windows/CMakeLists.txt index a2b31688..1bb39b37 100644 --- a/osal/windows/CMakeLists.txt +++ b/osal/windows/CMakeLists.txt @@ -1,11 +1,3 @@ target_sources(${LIB_FSFW_NAME} PRIVATE - TcWinUdpPollingTask.cpp - TmTcWinUdpBridge.cpp - TcWinTcpServer.cpp tcpipHelpers.cpp ) - -target_link_libraries(${LIB_FSFW_NAME} PRIVATE - wsock32 - ws2_32 -) \ No newline at end of file diff --git a/osal/windows/tcpipHelpers.cpp b/osal/windows/tcpipHelpers.cpp index ef07f5ca..03278a92 100644 --- a/osal/windows/tcpipHelpers.cpp +++ b/osal/windows/tcpipHelpers.cpp @@ -1,4 +1,4 @@ -#include "tcpipHelpers.h" +#include "../common/tcpipHelpers.h" #include #include "../../tasks/TaskFactory.h" From 86577f4b80aa8566a5212edd2712e804b279d638 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 21 Mar 2021 12:51:28 +0100 Subject: [PATCH 084/230] 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_ */ From b5a14bb9dfbb57dbfcc89c8fab19a244c5396598 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 21 Mar 2021 13:02:14 +0100 Subject: [PATCH 085/230] deleted old linux code --- osal/common/UdpTcPollingTask.cpp | 172 +++++++++++++++------------- osal/common/UdpTcPollingTask.h | 4 +- osal/common/UdpTmTcBridge.cpp | 14 ++- osal/linux/TcUnixUdpPollingTask.cpp | 152 ------------------------ osal/linux/TcUnixUdpPollingTask.h | 67 ----------- osal/linux/TmTcUnixUdpBridge.cpp | 167 --------------------------- osal/linux/TmTcUnixUdpBridge.h | 53 --------- osal/linux/tcpipHelpers.cpp | 2 +- osal/linux/tcpipHelpers.h | 14 --- 9 files changed, 102 insertions(+), 543 deletions(-) delete mode 100644 osal/linux/TcUnixUdpPollingTask.cpp delete mode 100644 osal/linux/TcUnixUdpPollingTask.h delete mode 100644 osal/linux/TmTcUnixUdpBridge.cpp delete mode 100644 osal/linux/TmTcUnixUdpBridge.h delete mode 100644 osal/linux/tcpipHelpers.h diff --git a/osal/common/UdpTcPollingTask.cpp b/osal/common/UdpTcPollingTask.cpp index 3d51e118..bace593f 100644 --- a/osal/common/UdpTcPollingTask.cpp +++ b/osal/common/UdpTcPollingTask.cpp @@ -18,27 +18,27 @@ #define FSFW_UDP_RCV_WIRETAPPING_ENABLED 0 UdpTcPollingTask::UdpTcPollingTask(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; - } + object_id_t tmtcUnixUdpBridge, size_t maxRecvSize, + double timeoutSeconds): SystemObject(objectId), + tmtcBridgeId(tmtcUnixUdpBridge) { + if(frameSize > 0) { + this->frameSize = frameSize; + } + else { + this->frameSize = DEFAULT_MAX_RECV_SIZE; + } - /* Set up reception buffer with specified frame size. + /* Set up reception buffer with specified frame size. For now, it is assumed that only one frame is held in the buffer! */ - receptionBuffer.reserve(this->frameSize); - receptionBuffer.resize(this->frameSize); + receptionBuffer.reserve(this->frameSize); + receptionBuffer.resize(this->frameSize); - if(timeoutSeconds == -1) { - receptionTimeout = DEFAULT_TIMEOUT; - } - else { - receptionTimeout = timevalOperations::toTimeval(timeoutSeconds); - } + if(timeoutSeconds == -1) { + receptionTimeout = DEFAULT_TIMEOUT; + } + else { + receptionTimeout = timevalOperations::toTimeval(timeoutSeconds); + } } UdpTcPollingTask::~UdpTcPollingTask() {} @@ -48,120 +48,130 @@ ReturnValue_t UdpTcPollingTask::performOperation(uint8_t opCode) { struct sockaddr senderAddress; socklen_t senderAddressSize = sizeof(senderAddress); - /* Poll for new UDP datagrams in permanent loop. */ - while(true) { - int bytesReceived = recvfrom( - this->serverSocket, - reinterpret_cast(receptionBuffer.data()), - frameSize, - receptionFlags, - &senderAddress, - &senderAddressSize - ); - if(bytesReceived == SOCKET_ERROR) { - /* Handle error */ + /* Poll for new UDP datagrams in permanent loop. */ + while(true) { + int bytesReceived = recvfrom( + this->serverSocket, + reinterpret_cast(receptionBuffer.data()), + frameSize, + receptionFlags, + &senderAddress, + &senderAddressSize + ); + if(bytesReceived == SOCKET_ERROR) { + /* Handle error */ #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "UdpTcPollingTask::performOperation: Reception error." << std::endl; + sif::error << "UdpTcPollingTask::performOperation: Reception error." << std::endl; #endif - tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::RECVFROM_CALL, 1000); - continue; - } + tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::RECVFROM_CALL, 1000); + continue; + } #if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1 - sif::debug << "UdpTcPollingTask::performOperation: " << bytesReceived << - " bytes received" << std::endl; + sif::debug << "UdpTcPollingTask::performOperation: " << bytesReceived << + " bytes received" << std::endl; #endif - ReturnValue_t result = handleSuccessfullTcRead(bytesReceived); - if(result != HasReturnvaluesIF::RETURN_FAILED) { + ReturnValue_t result = handleSuccessfullTcRead(bytesReceived); + if(result != HasReturnvaluesIF::RETURN_FAILED) { - } - tmtcBridge->checkAndSetClientAddress(senderAddress); - } - return HasReturnvaluesIF::RETURN_OK; + } + tmtcBridge->checkAndSetClientAddress(senderAddress); + } + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t UdpTcPollingTask::handleSuccessfullTcRead(size_t bytesRead) { - store_address_t storeId; + 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) { + 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<< "UdpTcPollingTask::transferPusToSoftwareBus: Data storage failed." << - std::endl; - sif::warning << "Packet size: " << bytesRead << std::endl; + sif::warning<< "UdpTcPollingTask::transferPusToSoftwareBus: Data storage failed." << + std::endl; + sif::warning << "Packet size: " << bytesRead << std::endl; #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ #endif /* FSFW_VERBOSE_LEVEL >= 1 */ - return HasReturnvaluesIF::RETURN_FAILED; - } + return HasReturnvaluesIF::RETURN_FAILED; + } - TmTcMessage message(storeId); + TmTcMessage message(storeId); - result = MessageQueueSenderIF::sendMessage(targetTcDestination, &message); - if (result != HasReturnvaluesIF::RETURN_OK) { + result = MessageQueueSenderIF::sendMessage(targetTcDestination, &message); + if (result != HasReturnvaluesIF::RETURN_OK) { #if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "UdpTcPollingTask::handleSuccessfullTcRead: " - " Sending message to queue failed" << std::endl; + sif::warning << "UdpTcPollingTask::handleSuccessfullTcRead: " + " Sending message to queue failed" << std::endl; #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ #endif /* FSFW_VERBOSE_LEVEL >= 1 */ - tcStore->deleteData(storeId); - } - return result; + tcStore->deleteData(storeId); + } + return result; } ReturnValue_t UdpTcPollingTask::initialize() { - tcStore = objectManager->get(objects::TC_STORE); - if (tcStore == nullptr) { + tcStore = objectManager->get(objects::TC_STORE); + if (tcStore == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "UdpTcPollingTask::initialize: TC store uninitialized!" << std::endl; + sif::error << "UdpTcPollingTask::initialize: TC store uninitialized!" << std::endl; #endif - return ObjectManagerIF::CHILD_INIT_FAILED; - } + return ObjectManagerIF::CHILD_INIT_FAILED; + } - tmtcBridge = objectManager->get(tmtcBridgeId); - if(tmtcBridge == nullptr) { + tmtcBridge = objectManager->get(tmtcBridgeId); + if(tmtcBridge == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "UdpTcPollingTask::initialize: Invalid TMTC bridge object!" << - std::endl; + sif::error << "UdpTcPollingTask::initialize: Invalid TMTC bridge object!" << + std::endl; #endif - return ObjectManagerIF::CHILD_INIT_FAILED; - } + return ObjectManagerIF::CHILD_INIT_FAILED; + } ReturnValue_t result = TcpIpBase::initialize(); if(result != HasReturnvaluesIF::RETURN_OK) { return result; } - return HasReturnvaluesIF::RETURN_OK; + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t UdpTcPollingTask::initializeAfterTaskCreation() { - /* Initialize the destination after task creation. This ensures + /* 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 + 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 */ this->serverSocket = tmtcBridge->serverSocket; - return HasReturnvaluesIF::RETURN_OK; + return HasReturnvaluesIF::RETURN_OK; } void UdpTcPollingTask::setTimeout(double timeoutSeconds) { #ifdef _WIN32 - DWORD timeoutMs = timeoutSeconds * 1000.0; - int result = setsockopt(serverUdpSocket, SOL_SOCKET, SO_RCVTIMEO, - reinterpret_cast(&timeoutMs), sizeof(DWORD)); - if(result == -1) { + DWORD timeoutMs = timeoutSeconds * 1000.0; + int result = setsockopt(serverUdpSocket, SOL_SOCKET, SO_RCVTIMEO, + reinterpret_cast(&timeoutMs), sizeof(DWORD)); + if(result == -1) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TcWinUdpPollingTask::TcSocketPollingTask: Setting " - "receive timeout failed with " << strerror(errno) << std::endl; + sif::error << "TcWinUdpPollingTask::TcSocketPollingTask: Setting " + "receive timeout failed with " << strerror(errno) << std::endl; #endif - } + } #elif defined(__unix__) + timeval tval; + tval = timevalOperations::toTimeval(timeoutSeconds); + int result = setsockopt(serverSocket, 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 + } #endif } diff --git a/osal/common/UdpTcPollingTask.h b/osal/common/UdpTcPollingTask.h index 4df62b94..ae1c4c44 100644 --- a/osal/common/UdpTcPollingTask.h +++ b/osal/common/UdpTcPollingTask.h @@ -23,12 +23,12 @@ class UdpTcPollingTask: public ExecutableObjectIF { friend class TmTcWinUdpBridge; public: - static constexpr size_t DEFAULT_MAX_FRAME_SIZE = 2048; + static constexpr size_t DEFAULT_MAX_RECV_SIZE = 1500; //! 0.5 default milliseconds timeout for now. static constexpr timeval DEFAULT_TIMEOUT = {0, 500}; UdpTcPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge, - size_t frameSize = 0, double timeoutSeconds = -1); + size_t maxRecvSize = 0, double timeoutSeconds = -1); virtual~ UdpTcPollingTask(); /** diff --git a/osal/common/UdpTmTcBridge.cpp b/osal/common/UdpTmTcBridge.cpp index a8975c0e..ae74e94b 100644 --- a/osal/common/UdpTmTcBridge.cpp +++ b/osal/common/UdpTmTcBridge.cpp @@ -70,12 +70,14 @@ ReturnValue_t UdpTmTcBridge::initialize() { hints.ai_family = AF_INET; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; -#ifdef _WIN32 - /* See: - https://docs.microsoft.com/en-us/windows/win32/api/ws2tcpip/nf-ws2tcpip-getaddrinfo - for information about AI_PASSIVE. */ - hints.ai_flags = AI_PASSIVE; -#endif +//#ifdef _WIN32 +// /* See: +// https://docs.microsoft.com/en-us/windows/win32/api/ws2tcpip/nf-ws2tcpip-getaddrinfo +// and +// +// for information about AI_PASSIVE. */ +// hints.ai_flags = AI_PASSIVE; +//#endif /* Set up UDP socket: https://en.wikipedia.org/wiki/Getaddrinfo diff --git a/osal/linux/TcUnixUdpPollingTask.cpp b/osal/linux/TcUnixUdpPollingTask.cpp deleted file mode 100644 index ec3687b9..00000000 --- a/osal/linux/TcUnixUdpPollingTask.cpp +++ /dev/null @@ -1,152 +0,0 @@ -//#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 deleted file mode 100644 index 1040d1a2..00000000 --- a/osal/linux/TcUnixUdpPollingTask.h +++ /dev/null @@ -1,67 +0,0 @@ -//#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 deleted file mode 100644 index c0cd6877..00000000 --- a/osal/linux/TmTcUnixUdpBridge.cpp +++ /dev/null @@ -1,167 +0,0 @@ -//#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 deleted file mode 100644 index b4b00950..00000000 --- a/osal/linux/TmTcUnixUdpBridge.h +++ /dev/null @@ -1,53 +0,0 @@ -//#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_ */ diff --git a/osal/linux/tcpipHelpers.cpp b/osal/linux/tcpipHelpers.cpp index 1c380769..4c1b9a78 100644 --- a/osal/linux/tcpipHelpers.cpp +++ b/osal/linux/tcpipHelpers.cpp @@ -1,4 +1,4 @@ -#include "tcpipHelpers.h" +#include "../common/tcpipHelpers.h" #include "../../tasks/TaskFactory.h" diff --git a/osal/linux/tcpipHelpers.h b/osal/linux/tcpipHelpers.h deleted file mode 100644 index 6b337c62..00000000 --- a/osal/linux/tcpipHelpers.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef FSFW_OSAL_LINUX_TCPIPHELPERS_H_ -#define FSFW_OSAL_LINUX_TCPIPHELPERS_H_ - -#include "../../timemanager/clockDefinitions.h" -#include "../common/tcpipCommon.h" - -namespace tcpip { - - -void handleError(Protocol protocol, ErrorSources errorSrc, dur_millis_t sleepDuration = 0); - -} - -#endif /* FSFW_OSAL_LINUX_TCPIPHELPERS_H_ */ From 078116c7be61cd5bd74e1b8c49c87950a6dab7ef Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 21 Mar 2021 14:38:28 +0100 Subject: [PATCH 086/230] generic windows udp bridge working as well --- osal/common/TcpIpBase.cpp | 37 ++++++++++++++++---------------- osal/common/UdpTcPollingTask.cpp | 2 +- osal/common/UdpTmTcBridge.cpp | 10 +-------- osal/common/UdpTmTcBridge.h | 8 ++++++- 4 files changed, 28 insertions(+), 29 deletions(-) diff --git a/osal/common/TcpIpBase.cpp b/osal/common/TcpIpBase.cpp index 35524743..279fd1c4 100644 --- a/osal/common/TcpIpBase.cpp +++ b/osal/common/TcpIpBase.cpp @@ -8,32 +8,16 @@ #endif TcpIpBase::TcpIpBase() { - closeSocket(serverSocket); + } TcpIpBase::~TcpIpBase() { + closeSocket(serverSocket); #ifdef _WIN32 WSACleanup(); #endif } - -int TcpIpBase::closeSocket(socket_t socket) { -#ifdef _WIN32 - return closesocket(socket); -#elif defined(__unix__) - return close(socket); -#endif -} - -int TcpIpBase::getLastSocketError() { -#ifdef _WIN32 - return WSAGetLastError(); -#elif defined(__unix__) - return errno; -#endif -} - ReturnValue_t TcpIpBase::initialize() { #ifdef _WIN32 /* Initiates Winsock DLL. */ @@ -51,3 +35,20 @@ ReturnValue_t TcpIpBase::initialize() { #endif return HasReturnvaluesIF::RETURN_OK; } + +int TcpIpBase::closeSocket(socket_t socket) { +#ifdef _WIN32 + return closesocket(socket); +#elif defined(__unix__) + return close(socket); +#endif +} + +int TcpIpBase::getLastSocketError() { +#ifdef _WIN32 + return WSAGetLastError(); +#elif defined(__unix__) + return errno; +#endif +} + diff --git a/osal/common/UdpTcPollingTask.cpp b/osal/common/UdpTcPollingTask.cpp index bace593f..759cee05 100644 --- a/osal/common/UdpTcPollingTask.cpp +++ b/osal/common/UdpTcPollingTask.cpp @@ -154,7 +154,7 @@ ReturnValue_t UdpTcPollingTask::initializeAfterTaskCreation() { void UdpTcPollingTask::setTimeout(double timeoutSeconds) { #ifdef _WIN32 DWORD timeoutMs = timeoutSeconds * 1000.0; - int result = setsockopt(serverUdpSocket, SOL_SOCKET, SO_RCVTIMEO, + int result = setsockopt(serverSocket, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast(&timeoutMs), sizeof(DWORD)); if(result == -1) { #if FSFW_CPP_OSTREAM_ENABLED == 1 diff --git a/osal/common/UdpTmTcBridge.cpp b/osal/common/UdpTmTcBridge.cpp index ae74e94b..7f3dc929 100644 --- a/osal/common/UdpTmTcBridge.cpp +++ b/osal/common/UdpTmTcBridge.cpp @@ -65,19 +65,11 @@ ReturnValue_t UdpTmTcBridge::initialize() { #endif struct addrinfo *addrResult = nullptr; - struct addrinfo hints = { 0 }; + struct addrinfo hints = {}; hints.ai_family = AF_INET; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; -//#ifdef _WIN32 -// /* See: -// https://docs.microsoft.com/en-us/windows/win32/api/ws2tcpip/nf-ws2tcpip-getaddrinfo -// and -// -// for information about AI_PASSIVE. */ -// hints.ai_flags = AI_PASSIVE; -//#endif /* Set up UDP socket: https://en.wikipedia.org/wiki/Getaddrinfo diff --git a/osal/common/UdpTmTcBridge.h b/osal/common/UdpTmTcBridge.h index afc8ee98..6f38034e 100644 --- a/osal/common/UdpTmTcBridge.h +++ b/osal/common/UdpTmTcBridge.h @@ -4,8 +4,14 @@ #include "TcpIpBase.h" #include "../../tmtcservices/TmTcBridge.h" -#ifdef __unix__ +#ifdef _WIN32 + +#include + +#elif defined(__unix__) + #include + #endif #include From e3c44fd27f8a8a20ad25d291d7cc6e96e0e43114 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 21 Mar 2021 16:20:13 +0100 Subject: [PATCH 087/230] implemented deadlien missed print for host --- osal/host/PeriodicTask.cpp | 33 ++------ osal/host/TaskFactory.cpp | 39 +++++++++- osal/linux/PosixThread.cpp | 16 ++-- osal/windows/CMakeLists.txt | 1 + osal/windows/winTaskHelpers.cpp | 130 ++++++++++++++++++++++++++++++++ osal/windows/winTaskHelpers.h | 40 ++++++++++ tasks/TaskFactory.h | 16 +++- tasks/Typedef.h | 2 +- 8 files changed, 236 insertions(+), 41 deletions(-) create mode 100644 osal/windows/winTaskHelpers.cpp create mode 100644 osal/windows/winTaskHelpers.h diff --git a/osal/host/PeriodicTask.cpp b/osal/host/PeriodicTask.cpp index 7663d522..4c0bf338 100644 --- a/osal/host/PeriodicTask.cpp +++ b/osal/host/PeriodicTask.cpp @@ -10,6 +10,7 @@ #if defined(WIN32) #include +#include #elif defined(LINUX) #include #endif @@ -22,33 +23,11 @@ PeriodicTask::PeriodicTask(const char *name, TaskPriority setPriority, // It is propably possible to set task priorities by using the native // task handles for Windows / Linux mainThread = std::thread(&PeriodicTask::taskEntryPoint, this, this); -#if defined(WIN32) - /* List of possible priority classes: - * https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ - * nf-processthreadsapi-setpriorityclass - * And respective thread priority numbers: - * https://docs.microsoft.com/en-us/windows/ - * win32/procthread/scheduling-priorities */ - int result = SetPriorityClass( - reinterpret_cast(mainThread.native_handle()), - ABOVE_NORMAL_PRIORITY_CLASS); - if(result != 0) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PeriodicTask: Windows SetPriorityClass failed with code " - << GetLastError() << std::endl; -#endif - } - result = SetThreadPriority( - reinterpret_cast(mainThread.native_handle()), - THREAD_PRIORITY_NORMAL); - if(result != 0) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PeriodicTask: Windows SetPriorityClass failed with code " - << GetLastError() << std::endl; -#endif - } -#elif defined(LINUX) - // we can just copy and paste the code from linux here. +#if defined(_WIN32) + tasks::setTaskPriority(reinterpret_cast(mainThread.native_handle()), setPriority); + tasks::insertTaskName(mainThread.get_id(), taskName); +#elif defined(__unix__) + // TODO: We could reuse existing code here. #endif } diff --git a/osal/host/TaskFactory.cpp b/osal/host/TaskFactory.cpp index 4fafd349..4ac44364 100644 --- a/osal/host/TaskFactory.cpp +++ b/osal/host/TaskFactory.cpp @@ -1,14 +1,20 @@ +#include "../../tasks/TaskFactory.h" #include "../../osal/host/FixedTimeslotTask.h" #include "../../osal/host/PeriodicTask.h" -#include "../../tasks/TaskFactory.h" #include "../../returnvalues/HasReturnvaluesIF.h" #include "../../tasks/PeriodicTaskIF.h" +#ifdef _WIN32 + +#include "../windows/winTaskHelpers.h" + +#endif + #include TaskFactory* TaskFactory::factoryInstance = new TaskFactory(); -// Will propably not be used for hosted implementation +// Not used for the host implementation for now because C++ thread abstraction is used const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = 0; TaskFactory::TaskFactory() { @@ -49,8 +55,33 @@ ReturnValue_t TaskFactory::delayTask(uint32_t delayMs){ } void TaskFactory::printMissedDeadline() { - /* TODO: Implement */ - return; +#ifdef __unix__ + char name[20] = {0}; + int status = pthread_getname_np(pthread_self(), name, sizeof(name)); +#if FSFW_CPP_OSTREAM_ENABLED == 1 + if(status == 0) { + sif::warning << "TaskFactory::printMissedDeadline: " << name << "" << std::endl; + } + else { + sif::warning << "TaskFactory::printMissedDeadline: Unknown task name" << status << + std::endl; + } +#else + if(status == 0) { + sif::printWarning("TaskFactory::printMissedDeadline: %s\n", name); + } + else { + sif::printWarning("TaskFactory::printMissedDeadline: Unknown task name\n", name); + } +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#elif defined(_WIN32) + std::string name = tasks::getTaskName(std::this_thread::get_id()); +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "TaskFactory::printMissedDeadline: " << name << std::endl; +#else + sif::printWarning("TaskFactory::printMissedDeadline: %s\n", name); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* defined(_WIN32) */ } diff --git a/osal/linux/PosixThread.cpp b/osal/linux/PosixThread.cpp index bd8e7258..5296dfb5 100644 --- a/osal/linux/PosixThread.cpp +++ b/osal/linux/PosixThread.cpp @@ -6,7 +6,7 @@ #include PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_): - thread(0),priority(priority_),stackSize(stackSize_) { + thread(0), priority(priority_), stackSize(stackSize_) { name[0] = '\0'; std::strncat(name, name_, PTHREAD_MAX_NAMELEN - 1); } @@ -75,18 +75,18 @@ bool PosixThread::delayUntil(uint64_t* const prevoiusWakeTime_ms, if (currentTime_ms < *prevoiusWakeTime_ms) { /* The tick count has overflowed since this function was - lasted called. In this case the only time we should ever - actually delay is if the wake time has also overflowed, - and the wake time is greater than the tick time. When this - is the case it is as if neither time had overflowed. */ + lasted called. In this case the only time we should ever + actually delay is if the wake time has also overflowed, + and the wake time is greater than the tick time. When this + is the case it is as if neither time had overflowed. */ if ((nextTimeToWake_ms < *prevoiusWakeTime_ms) && (nextTimeToWake_ms > currentTime_ms)) { shouldDelay = true; } } else { - /* The tick time has not overflowed. In this case we will - delay if either the wake time has overflowed, and/or the - tick time is less than the wake time. */ + /* The tick time has not overflowed. In this case we will + delay if either the wake time has overflowed, and/or the + tick time is less than the wake time. */ if ((nextTimeToWake_ms < *prevoiusWakeTime_ms) || (nextTimeToWake_ms > currentTime_ms)) { shouldDelay = true; diff --git a/osal/windows/CMakeLists.txt b/osal/windows/CMakeLists.txt index 1bb39b37..36a54765 100644 --- a/osal/windows/CMakeLists.txt +++ b/osal/windows/CMakeLists.txt @@ -1,3 +1,4 @@ target_sources(${LIB_FSFW_NAME} PRIVATE tcpipHelpers.cpp + winTaskHelpers.cpp ) diff --git a/osal/windows/winTaskHelpers.cpp b/osal/windows/winTaskHelpers.cpp new file mode 100644 index 00000000..e96cd70e --- /dev/null +++ b/osal/windows/winTaskHelpers.cpp @@ -0,0 +1,130 @@ +#include +#include + +std::mutex nameMapLock; +std::map taskNameMap; + +TaskPriority tasks::makeWinPriority(PriorityClass prioClass, PriorityNumber prioNumber) { + return (static_cast(prioClass) << 16) | static_cast (prioNumber); +} + +void tasks::getWinPriorityParameters(TaskPriority priority, + DWORD& priorityClass, int& priorityNumber) { + PriorityClass classInternal = static_cast(priority >> 16 & 0xff); + PriorityNumber numberInternal = static_cast(priority & 0xff); + switch(classInternal) { + case(CLASS_IDLE): { + priorityClass = IDLE_PRIORITY_CLASS; + break; + } + case(CLASS_BELOW_NORMAL): { + priorityClass = BELOW_NORMAL_PRIORITY_CLASS; + break; + } + case(CLASS_NORMAL): { + priorityClass = NORMAL_PRIORITY_CLASS; + break; + } + case(CLASS_ABOVE_NORMAL): { + priorityClass = ABOVE_NORMAL_PRIORITY_CLASS; + break; + } + case(CLASS_HIGH): { + priorityClass = HIGH_PRIORITY_CLASS; + break; + } + case(CLASS_REALTIME): { + priorityClass = REALTIME_PRIORITY_CLASS; + break; + } + default: { + priorityClass = NORMAL_PRIORITY_CLASS; + } + } + + switch(numberInternal) { + case(IDLE): { + priorityNumber = THREAD_PRIORITY_IDLE; + break; + } + case(LOWEST): { + priorityNumber = THREAD_PRIORITY_LOWEST; + break; + } + case(BELOW_NORMAL): { + priorityNumber = THREAD_PRIORITY_BELOW_NORMAL; + break; + } + case(NORMAL): { + priorityNumber = THREAD_PRIORITY_NORMAL; + break; + } + case(ABOVE_NORMAL): { + priorityNumber = THREAD_PRIORITY_ABOVE_NORMAL; + break; + } + case(HIGHEST): { + priorityNumber = THREAD_PRIORITY_HIGHEST; + break; + } + case(CRITICAL): { + priorityNumber = THREAD_PRIORITY_TIME_CRITICAL; + break; + } + default: { + priorityNumber = THREAD_PRIORITY_NORMAL; + } + } +} + +ReturnValue_t tasks::setTaskPriority(HANDLE nativeHandle, TaskPriority priority) { + /* List of possible priority classes: + https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setpriorityclass + And respective thread priority numbers: + https://docs.microsoft.com/en-us/windows/win32/procthread/scheduling-priorities + */ + DWORD dwPriorityClass = 0; + int nPriorityNumber = 0; + tasks::getWinPriorityParameters(priority, dwPriorityClass, nPriorityNumber); + int result = SetPriorityClass( + reinterpret_cast(nativeHandle), + dwPriorityClass); + if(result != 0) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "PeriodicTask: Windows SetPriorityClass failed with code " + << GetLastError() << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; +#endif + } + result = SetThreadPriority( + reinterpret_cast(nativeHandle), + nPriorityNumber); + if(result != 0) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "PeriodicTask: Windows SetPriorityClass failed with code " + << GetLastError() << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; +#endif + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t tasks::insertTaskName(std::thread::id threadId, std::string taskName) { + std::lock_guard lg(nameMapLock); + auto returnPair = taskNameMap.emplace(threadId, taskName); + if(not returnPair.second) { + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; +} + +std::string tasks::getTaskName(std::thread::id threadId) { + std::lock_guard lg(nameMapLock); + auto resultIter = taskNameMap.find(threadId); + if(resultIter != taskNameMap.end()) { + return resultIter->second; + } + else { + return "Unknown task"; + } +} diff --git a/osal/windows/winTaskHelpers.h b/osal/windows/winTaskHelpers.h new file mode 100644 index 00000000..d17b611a --- /dev/null +++ b/osal/windows/winTaskHelpers.h @@ -0,0 +1,40 @@ +#include "../../tasks/TaskFactory.h" + +#include +#include + +#ifdef _WIN32 + +namespace tasks { + +enum PriorityClass: uint16_t { + CLASS_IDLE, + CLASS_BELOW_NORMAL, + CLASS_NORMAL, + CLASS_ABOVE_NORMAL, + CLASS_HIGH, + CLASS_REALTIME +}; +enum PriorityNumber: uint16_t { + IDLE, + LOWEST, + BELOW_NORMAL, + NORMAL, + ABOVE_NORMAL, + HIGHEST, + CRITICAL +}; +TaskPriority makeWinPriority(PriorityClass prioClass = PriorityClass::CLASS_NORMAL, + PriorityNumber prioNumber = PriorityNumber::NORMAL); +void getWinPriorityParameters(TaskPriority priority, DWORD& priorityClass, + int& priorityNumber); + +ReturnValue_t setTaskPriority(HANDLE nativeHandle, TaskPriority priority); + +ReturnValue_t insertTaskName(std::thread::id threadId, std::string taskName); +std::string getTaskName(std::thread::id threadId); + +} + +#endif + diff --git a/tasks/TaskFactory.h b/tasks/TaskFactory.h index 03b5163c..4fba345f 100644 --- a/tasks/TaskFactory.h +++ b/tasks/TaskFactory.h @@ -22,9 +22,23 @@ public: /** * Creates a new periodic task and returns the interface pointer. * @param name_ Name of the task - * @param taskPriority_ Priority of the task + * @param taskPriority_ + * Priority of the task. This value might have different ranges for the various OSALs. + * Linux: Value ranging from 0 to 99 with 99 being the highest value. + * Host: Value can be retrieved by using the #tasks::makeWinPriority function. + * FreeRTOS: Value depends on the FreeRTOS configuration, higher number means higher priority + * RTEMS: Values ranging from 0 to 99 with 99 being the highest value. + * * @param stackSize_ Stack Size of the task + * This value might have different recommended ranges for the various OSALs. + * Linux: Lowest limit is the PeriodicTaskIF::MINIMUM_STACK_SIZE value + * Host: Value is ignored for now because the C++ threading abstraction layer is used. + * FreeRTOS: Stack size in bytes. It is recommended to specify at least 1kB of stack for + * FSFW tasks, but the lowest possible size is specified in the FreeRTOSConfig.h file. + * RTEMS: Lowest limit is the PeriodicTaskIF::MINIMUM_STACK_SIZE value. + * * @param period_ Period of the task + * * @param deadLineMissedFunction_ Function to be called if a deadline was missed * @return PeriodicTaskIF* Pointer to the newly created Task */ diff --git a/tasks/Typedef.h b/tasks/Typedef.h index 07d96b00..55f6bda2 100644 --- a/tasks/Typedef.h +++ b/tasks/Typedef.h @@ -2,7 +2,7 @@ #define FRAMEWORK_TASKS_TYPEDEF_H_ typedef const char* TaskName; -typedef uint8_t TaskPriority; +typedef uint32_t TaskPriority; typedef size_t TaskStackSize; typedef double TaskPeriod; typedef void (*TaskDeadlineMissedFunction)(); From 614d1ccb7c0cb99acfafef1e137247db44d3e989 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 21 Mar 2021 16:29:04 +0100 Subject: [PATCH 088/230] resorted functions --- osal/common/TcpIpBase.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osal/common/TcpIpBase.cpp b/osal/common/TcpIpBase.cpp index 279fd1c4..27384ecc 100644 --- a/osal/common/TcpIpBase.cpp +++ b/osal/common/TcpIpBase.cpp @@ -11,13 +11,6 @@ TcpIpBase::TcpIpBase() { } -TcpIpBase::~TcpIpBase() { - closeSocket(serverSocket); -#ifdef _WIN32 - WSACleanup(); -#endif -} - ReturnValue_t TcpIpBase::initialize() { #ifdef _WIN32 /* Initiates Winsock DLL. */ @@ -36,6 +29,13 @@ ReturnValue_t TcpIpBase::initialize() { return HasReturnvaluesIF::RETURN_OK; } +TcpIpBase::~TcpIpBase() { + closeSocket(serverSocket); +#ifdef _WIN32 + WSACleanup(); +#endif +} + int TcpIpBase::closeSocket(socket_t socket) { #ifdef _WIN32 return closesocket(socket); From 0c77ce4dcfc66384758971dab61d9086911bf125 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 22 Mar 2021 15:23:47 +0100 Subject: [PATCH 089/230] important bugfix --- controller/ExtendedControllerBase.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/controller/ExtendedControllerBase.h b/controller/ExtendedControllerBase.h index d5d43933..d7f87c98 100644 --- a/controller/ExtendedControllerBase.h +++ b/controller/ExtendedControllerBase.h @@ -65,7 +65,8 @@ protected: virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) override = 0; - virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override = 0; + virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid, store_address_t storeId, + bool* clearMessage = nullptr) override = 0; }; From f6afa36b1c1cbb987be63cd7ad9de24e71ec91ba Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 22 Mar 2021 15:24:25 +0100 Subject: [PATCH 090/230] small tweak --- controller/ExtendedControllerBase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controller/ExtendedControllerBase.h b/controller/ExtendedControllerBase.h index d7f87c98..2c2030bf 100644 --- a/controller/ExtendedControllerBase.h +++ b/controller/ExtendedControllerBase.h @@ -66,7 +66,7 @@ protected: virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) override = 0; virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid, store_address_t storeId, - bool* clearMessage = nullptr) override = 0; + bool* clearMessage) override = 0; }; From 31758833468a063e71854b0eb3046eae2eb17cdf Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 22 Mar 2021 15:28:36 +0100 Subject: [PATCH 091/230] oopsie --- controller/ExtendedControllerBase.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/controller/ExtendedControllerBase.h b/controller/ExtendedControllerBase.h index 2c2030bf..d5d43933 100644 --- a/controller/ExtendedControllerBase.h +++ b/controller/ExtendedControllerBase.h @@ -65,8 +65,7 @@ protected: virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) override = 0; - virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid, store_address_t storeId, - bool* clearMessage) override = 0; + virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override = 0; }; From 1c021651d73259b61147cfbbf73b9eaca69b0cd8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Mar 2021 11:26:44 +0100 Subject: [PATCH 092/230] missing include added --- osal/host/TaskFactory.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/osal/host/TaskFactory.cpp b/osal/host/TaskFactory.cpp index 4ac44364..1c40c99a 100644 --- a/osal/host/TaskFactory.cpp +++ b/osal/host/TaskFactory.cpp @@ -3,6 +3,7 @@ #include "../../osal/host/PeriodicTask.h" #include "../../returnvalues/HasReturnvaluesIF.h" #include "../../tasks/PeriodicTaskIF.h" +#include "../../serviceinterface/ServiceInterface.h" #ifdef _WIN32 From d4ab2c6cdbe66d3398720b5d621868fe6a0aa7fd Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Mar 2021 11:32:35 +0100 Subject: [PATCH 093/230] corrected doc --- tasks/TaskFactory.h | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/tasks/TaskFactory.h b/tasks/TaskFactory.h index 4fba345f..7990a9ce 100644 --- a/tasks/TaskFactory.h +++ b/tasks/TaskFactory.h @@ -24,18 +24,21 @@ public: * @param name_ Name of the task * @param taskPriority_ * Priority of the task. This value might have different ranges for the various OSALs. - * Linux: Value ranging from 0 to 99 with 99 being the highest value. - * Host: Value can be retrieved by using the #tasks::makeWinPriority function. - * FreeRTOS: Value depends on the FreeRTOS configuration, higher number means higher priority - * RTEMS: Values ranging from 0 to 99 with 99 being the highest value. + * - Linux Value ranging from 0 to 99 with 99 being the highest value. + * - Host For Windows, the value can be retrieved by using the #tasks::makeWinPriority + * function. For Linux, same priority system as specified above. MacOS not tested + * yet + * - FreeRTOS Value depends on the FreeRTOS configuration, higher number means higher priority + * - RTEMS Values ranging from 0 to 99 with 99 being the highest value. * * @param stackSize_ Stack Size of the task * This value might have different recommended ranges for the various OSALs. - * Linux: Lowest limit is the PeriodicTaskIF::MINIMUM_STACK_SIZE value - * Host: Value is ignored for now because the C++ threading abstraction layer is used. - * FreeRTOS: Stack size in bytes. It is recommended to specify at least 1kB of stack for - * FSFW tasks, but the lowest possible size is specified in the FreeRTOSConfig.h file. - * RTEMS: Lowest limit is the PeriodicTaskIF::MINIMUM_STACK_SIZE value. + * - Linux Lowest limit is the PeriodicTaskIF::MINIMUM_STACK_SIZE value + * - Host Value is ignored for now because the C++ threading abstraction layer is used. + * - FreeRTOS Stack size in bytes. It is recommended to specify at least 1kB of stack for + * FSFW tasks, but the lowest possible size is specified in the + * FreeRTOSConfig.h file. + * - RTEMS Lowest limit is specified the PeriodicTaskIF::MINIMUM_STACK_SIZE value. * * @param period_ Period of the task * From 1d3d2be853232ab113e789cb61c07afff2e40194 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Mar 2021 11:33:40 +0100 Subject: [PATCH 094/230] more doc --- tasks/TaskFactory.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tasks/TaskFactory.h b/tasks/TaskFactory.h index 7990a9ce..d4795202 100644 --- a/tasks/TaskFactory.h +++ b/tasks/TaskFactory.h @@ -51,7 +51,8 @@ public: TaskDeadlineMissedFunction deadLineMissedFunction_); /** - * + * The meaning for the variables for fixed timeslot tasks is the same as for periodic tasks. + * See #createPeriodicTask documentation. * @param name_ Name of the task * @param taskPriority_ Priority of the task * @param stackSize_ Stack Size of the task From b1670decf73776e4742af39791583d5d35bb2e54 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Mar 2021 11:35:23 +0100 Subject: [PATCH 095/230] Using C++ way of zero initializing struct --- osal/common/TcpTmTcServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osal/common/TcpTmTcServer.cpp b/osal/common/TcpTmTcServer.cpp index 2da5da95..296afad8 100644 --- a/osal/common/TcpTmTcServer.cpp +++ b/osal/common/TcpTmTcServer.cpp @@ -33,7 +33,7 @@ ReturnValue_t TcpTmTcServer::initialize() { int retval = 0; struct addrinfo *addrResult = nullptr; - struct addrinfo hints = { 0 }; + struct addrinfo hints = {}; hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; From a5f44b858035d2d931ee79c622dfe7ab11c3a7f9 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Mar 2021 14:25:50 +0100 Subject: [PATCH 096/230] doc updatedoc updatedd --- osal/common/UdpTcPollingTask.h | 9 ++------- osal/common/UdpTmTcBridge.h | 4 ++++ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/osal/common/UdpTcPollingTask.h b/osal/common/UdpTcPollingTask.h index ae1c4c44..052eced5 100644 --- a/osal/common/UdpTcPollingTask.h +++ b/osal/common/UdpTcPollingTask.h @@ -9,13 +9,8 @@ #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. + * @brief This class should be used with the UdpTmTcBridge to implement a UDP server + * for receiving and sending PUS TMTC. */ class UdpTcPollingTask: public TcpIpBase, diff --git a/osal/common/UdpTmTcBridge.h b/osal/common/UdpTmTcBridge.h index 6f38034e..8b8d1949 100644 --- a/osal/common/UdpTmTcBridge.h +++ b/osal/common/UdpTmTcBridge.h @@ -16,6 +16,10 @@ #include +/** + * @brief This class should be used with the UdpTcPollingTask to implement a UDP server + * for receiving and sending PUS TMTC. + */ class UdpTmTcBridge: public TmTcBridge, public TcpIpBase { From bdd9889718a26e130f43c9439033e68f28436cf1 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Mar 2021 14:28:01 +0100 Subject: [PATCH 097/230] pool read guard in scope --- internalError/InternalErrorReporter.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/internalError/InternalErrorReporter.cpp b/internalError/InternalErrorReporter.cpp index af9acc0d..78618448 100644 --- a/internalError/InternalErrorReporter.cpp +++ b/internalError/InternalErrorReporter.cpp @@ -53,12 +53,14 @@ ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) { } #endif - PoolReadGuard readGuard(&internalErrorDataset); - if(readGuard.getReadResult() == HasReturnvaluesIF::RETURN_OK) { - internalErrorDataset.queueHits.value += newQueueHits; - internalErrorDataset.storeHits.value += newStoreHits; - internalErrorDataset.tmHits.value += newTmHits; - internalErrorDataset.setValidity(true, true); + { + PoolReadGuard readGuard(&internalErrorDataset); + if(readGuard.getReadResult() == HasReturnvaluesIF::RETURN_OK) { + internalErrorDataset.queueHits.value += newQueueHits; + internalErrorDataset.storeHits.value += newStoreHits; + internalErrorDataset.tmHits.value += newTmHits; + internalErrorDataset.setValidity(true, true); + } } poolManager.performHkOperation(); From d781c6fcecceef0602a147ffbecf7255f24fdcfd Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Mar 2021 14:40:30 +0100 Subject: [PATCH 098/230] name storage abstraction available for linux as well --- osal/host/CMakeLists.txt | 1 + osal/host/PeriodicTask.cpp | 1 + osal/host/TaskFactory.cpp | 28 +--------------------------- osal/host/taskHelpers.cpp | 27 +++++++++++++++++++++++++++ osal/host/taskHelpers.h | 16 ++++++++++++++++ osal/windows/winTaskHelpers.cpp | 23 ----------------------- osal/windows/winTaskHelpers.h | 3 --- 7 files changed, 46 insertions(+), 53 deletions(-) create mode 100644 osal/host/taskHelpers.cpp create mode 100644 osal/host/taskHelpers.h diff --git a/osal/host/CMakeLists.txt b/osal/host/CMakeLists.txt index 367f721e..2d29ce5d 100644 --- a/osal/host/CMakeLists.txt +++ b/osal/host/CMakeLists.txt @@ -10,6 +10,7 @@ target_sources(${LIB_FSFW_NAME} QueueMapManager.cpp SemaphoreFactory.cpp TaskFactory.cpp + taskHelpers.cpp ) if(UNIX) diff --git a/osal/host/PeriodicTask.cpp b/osal/host/PeriodicTask.cpp index 4c0bf338..4a02ee0d 100644 --- a/osal/host/PeriodicTask.cpp +++ b/osal/host/PeriodicTask.cpp @@ -1,5 +1,6 @@ #include "Mutex.h" #include "PeriodicTask.h" +#include "taskHelpers.h" #include "../../ipc/MutexFactory.h" #include "../../serviceinterface/ServiceInterfaceStream.h" diff --git a/osal/host/TaskFactory.cpp b/osal/host/TaskFactory.cpp index 1c40c99a..71d0bf8b 100644 --- a/osal/host/TaskFactory.cpp +++ b/osal/host/TaskFactory.cpp @@ -1,3 +1,4 @@ +#include "taskHelpers.h" #include "../../tasks/TaskFactory.h" #include "../../osal/host/FixedTimeslotTask.h" #include "../../osal/host/PeriodicTask.h" @@ -5,12 +6,6 @@ #include "../../tasks/PeriodicTaskIF.h" #include "../../serviceinterface/ServiceInterface.h" -#ifdef _WIN32 - -#include "../windows/winTaskHelpers.h" - -#endif - #include TaskFactory* TaskFactory::factoryInstance = new TaskFactory(); @@ -56,33 +51,12 @@ ReturnValue_t TaskFactory::delayTask(uint32_t delayMs){ } void TaskFactory::printMissedDeadline() { -#ifdef __unix__ - char name[20] = {0}; - int status = pthread_getname_np(pthread_self(), name, sizeof(name)); -#if FSFW_CPP_OSTREAM_ENABLED == 1 - if(status == 0) { - sif::warning << "TaskFactory::printMissedDeadline: " << name << "" << std::endl; - } - else { - sif::warning << "TaskFactory::printMissedDeadline: Unknown task name" << status << - std::endl; - } -#else - if(status == 0) { - sif::printWarning("TaskFactory::printMissedDeadline: %s\n", name); - } - else { - sif::printWarning("TaskFactory::printMissedDeadline: Unknown task name\n", name); - } -#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ -#elif defined(_WIN32) std::string name = tasks::getTaskName(std::this_thread::get_id()); #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "TaskFactory::printMissedDeadline: " << name << std::endl; #else sif::printWarning("TaskFactory::printMissedDeadline: %s\n", name); #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ -#endif /* defined(_WIN32) */ } diff --git a/osal/host/taskHelpers.cpp b/osal/host/taskHelpers.cpp new file mode 100644 index 00000000..be4c29ad --- /dev/null +++ b/osal/host/taskHelpers.cpp @@ -0,0 +1,27 @@ +#include "taskHelpers.h" +#include +#include + +std::mutex nameMapLock; +std::map taskNameMap; + +ReturnValue_t tasks::insertTaskName(std::thread::id threadId, std::string taskName) { + std::lock_guard lg(nameMapLock); + auto returnPair = taskNameMap.emplace(threadId, taskName); + if(not returnPair.second) { + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; +} + +std::string tasks::getTaskName(std::thread::id threadId) { + std::lock_guard lg(nameMapLock); + auto resultIter = taskNameMap.find(threadId); + if(resultIter != taskNameMap.end()) { + return resultIter->second; + } + else { + return "Unknown task"; + } +} + diff --git a/osal/host/taskHelpers.h b/osal/host/taskHelpers.h new file mode 100644 index 00000000..fa00490f --- /dev/null +++ b/osal/host/taskHelpers.h @@ -0,0 +1,16 @@ +#ifndef FSFW_OSAL_HOST_TASKHELPERS_H_ +#define FSFW_OSAL_HOST_TASKHELPERS_H_ + +#include +#include + +namespace tasks { + +ReturnValue_t insertTaskName(std::thread::id threadId, std::string taskName); +std::string getTaskName(std::thread::id threadId); + +} + + + +#endif /* FSFW_OSAL_HOST_TASKHELPERS_H_ */ diff --git a/osal/windows/winTaskHelpers.cpp b/osal/windows/winTaskHelpers.cpp index e96cd70e..6765b952 100644 --- a/osal/windows/winTaskHelpers.cpp +++ b/osal/windows/winTaskHelpers.cpp @@ -1,9 +1,6 @@ #include #include -std::mutex nameMapLock; -std::map taskNameMap; - TaskPriority tasks::makeWinPriority(PriorityClass prioClass, PriorityNumber prioNumber) { return (static_cast(prioClass) << 16) | static_cast (prioNumber); } @@ -108,23 +105,3 @@ ReturnValue_t tasks::setTaskPriority(HANDLE nativeHandle, TaskPriority priority) } return HasReturnvaluesIF::RETURN_OK; } - -ReturnValue_t tasks::insertTaskName(std::thread::id threadId, std::string taskName) { - std::lock_guard lg(nameMapLock); - auto returnPair = taskNameMap.emplace(threadId, taskName); - if(not returnPair.second) { - return HasReturnvaluesIF::RETURN_FAILED; - } - return HasReturnvaluesIF::RETURN_OK; -} - -std::string tasks::getTaskName(std::thread::id threadId) { - std::lock_guard lg(nameMapLock); - auto resultIter = taskNameMap.find(threadId); - if(resultIter != taskNameMap.end()) { - return resultIter->second; - } - else { - return "Unknown task"; - } -} diff --git a/osal/windows/winTaskHelpers.h b/osal/windows/winTaskHelpers.h index d17b611a..64e52672 100644 --- a/osal/windows/winTaskHelpers.h +++ b/osal/windows/winTaskHelpers.h @@ -31,9 +31,6 @@ void getWinPriorityParameters(TaskPriority priority, DWORD& priorityClass, ReturnValue_t setTaskPriority(HANDLE nativeHandle, TaskPriority priority); -ReturnValue_t insertTaskName(std::thread::id threadId, std::string taskName); -std::string getTaskName(std::thread::id threadId); - } #endif From aaceac81af9061892e8d25e66dec9bf963a21d65 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Mar 2021 14:45:33 +0100 Subject: [PATCH 099/230] updated fixed timeslot task --- osal/host/FixedTimeslotTask.cpp | 36 +++++++-------------------------- osal/host/PeriodicTask.cpp | 4 ++-- 2 files changed, 9 insertions(+), 31 deletions(-) diff --git a/osal/host/FixedTimeslotTask.cpp b/osal/host/FixedTimeslotTask.cpp index 272d99b9..3b169b5a 100644 --- a/osal/host/FixedTimeslotTask.cpp +++ b/osal/host/FixedTimeslotTask.cpp @@ -1,9 +1,8 @@ +#include "taskHelpers.h" #include "../../osal/host/FixedTimeslotTask.h" - #include "../../ipc/MutexFactory.h" #include "../../osal/host/Mutex.h" #include "../../osal/host/FixedTimeslotTask.h" - #include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../tasks/ExecutableObjectIF.h" @@ -12,6 +11,7 @@ #if defined(WIN32) #include +#include "../windows/winTaskHelpers.h" #elif defined(LINUX) #include #endif @@ -24,34 +24,12 @@ FixedTimeslotTask::FixedTimeslotTask(const char *name, TaskPriority setPriority, // It is propably possible to set task priorities by using the native // task handles for Windows / Linux mainThread = std::thread(&FixedTimeslotTask::taskEntryPoint, this, this); -#if defined(WIN32) - /* List of possible priority classes: - * https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ - * nf-processthreadsapi-setpriorityclass - * And respective thread priority numbers: - * https://docs.microsoft.com/en-us/windows/ - * win32/procthread/scheduling-priorities */ - int result = SetPriorityClass( - reinterpret_cast(mainThread.native_handle()), - ABOVE_NORMAL_PRIORITY_CLASS); - if(result != 0) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "FixedTimeslotTask: Windows SetPriorityClass failed with code " - << GetLastError() << std::endl; -#endif - } - result = SetThreadPriority( - reinterpret_cast(mainThread.native_handle()), - THREAD_PRIORITY_NORMAL); - if(result != 0) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "FixedTimeslotTask: Windows SetPriorityClass failed with code " - << GetLastError() << std::endl; -#endif - } -#elif defined(LINUX) - // TODO: we can just copy and paste the code from the linux OSAL here. +#if defined(_WIN32) + tasks::setTaskPriority(reinterpret_cast(mainThread.native_handle()), setPriority); +#elif defined(__unix__) + // TODO: We could reuse existing code here. #endif + tasks::insertTaskName(mainThread.get_id(), taskName); } FixedTimeslotTask::~FixedTimeslotTask(void) { diff --git a/osal/host/PeriodicTask.cpp b/osal/host/PeriodicTask.cpp index 4a02ee0d..d7abf9d0 100644 --- a/osal/host/PeriodicTask.cpp +++ b/osal/host/PeriodicTask.cpp @@ -12,7 +12,7 @@ #if defined(WIN32) #include #include -#elif defined(LINUX) +#elif defined(__unix__) #include #endif @@ -26,10 +26,10 @@ PeriodicTask::PeriodicTask(const char *name, TaskPriority setPriority, mainThread = std::thread(&PeriodicTask::taskEntryPoint, this, this); #if defined(_WIN32) tasks::setTaskPriority(reinterpret_cast(mainThread.native_handle()), setPriority); - tasks::insertTaskName(mainThread.get_id(), taskName); #elif defined(__unix__) // TODO: We could reuse existing code here. #endif + tasks::insertTaskName(mainThread.get_id(), taskName); } PeriodicTask::~PeriodicTask(void) { From 9e559658a7ab16cc6d600cd0008802ae48069953 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 25 Mar 2021 15:35:05 +0100 Subject: [PATCH 100/230] added way to add additional include paths and libraries --- CMakeLists.txt | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3b0917fd..6d6fd5ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,7 +32,9 @@ elseif(${OS_FSFW} STREQUAL linux) set(OS_FSFW_NAME "Linux") elseif(${OS_FSFW} STREQUAL freertos) set(OS_FSFW_NAME "FreeRTOS") - target_link_libraries(${LIB_FSFW_NAME} ${LIB_OS_NAME}) + target_link_libraries(${LIB_FSFW_NAME} PRIVATE + ${LIB_OS_NAME} + ) elseif(${OS_FSFW} STREQUAL rtems) set(OS_FSFW_NAME "RTEMS") else() @@ -107,6 +109,21 @@ else() ) endif() +foreach(INCLUDE_PATH ${FSFW_ADDITIONAL_INC_PATH}) + if(IS_ABSOLUTE ${INCLUDE_PATH}) + set(CURR_ABS_INC_PATH "${FREERTOS_PATH}") + else() + get_filename_component(CURR_ABS_INC_PATH + ${INCLUDE_PATH} REALPATH BASE_DIR ${CMAKE_SOURCE_DIR}) + endif() + + if(CMAKE_VERBOSE) + message(STATUS "FSFW include path: ${CURR_ABS_INC_PATH}") + endif() + + list(APPEND FSFW_ADD_INC_PATHS_ABS ${CURR_ABS_INC_PATH}) +endforeach() + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") if(NOT DEFINED FSFW_WARNING_FLAGS) set(FSFW_WARNING_FLAGS @@ -140,9 +157,14 @@ target_include_directories(${LIB_FSFW_NAME} INTERFACE target_include_directories(${LIB_FSFW_NAME} PRIVATE ${CMAKE_SOURCE_DIR} ${FSFW_CONFIG_PATH_ABSOLUTE} + ${FSFW_ADD_INC_PATHS_ABS} ) target_compile_options(${LIB_FSFW_NAME} PRIVATE ${FSFW_WARNING_FLAGS} ${COMPILER_FLAGS} ) + +target_link_libraries(${LIB_FSFW_NAME} PRIVATE + ${FSFW_ADDITIONAL_LINK_LIBS} +) \ No newline at end of file From 581832e4f433b8e2b32418ab7a24f9ba256fb334 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 25 Mar 2021 18:05:18 +0100 Subject: [PATCH 101/230] added unittest folder --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d6fd5ed..58ad644b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -90,6 +90,7 @@ add_subdirectory(timemanager) add_subdirectory(tmstorage) add_subdirectory(tmtcpacket) add_subdirectory(tmtcservices) +add_subdirectory(unittest) # The project CMakeLists file has to set the FSFW_CONFIG_PATH and add it. # If this is not given, we include the default configuration and emit a warning. From 1d818294e4b697a61f45831bc825793c66d9d40c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 25 Mar 2021 18:48:00 +0100 Subject: [PATCH 102/230] added option to remove unused code --- CMakeLists.txt | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 58ad644b..f9f49794 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,13 @@ cmake_minimum_required(VERSION 3.13) +option(FSFW_GENERATE_SECTIONS + "Generate function and data sections. Required to remove unused code" ON +) + +if(FSFW_GENERATE_SECTIONS) + option(FSFW_REMOVE_UNUSED_CODE "Remove unused code" ON) +endif() + option(FSFW_WARNING_SHADOW_LOCAL_GCC "Enable -Wshadow=local warning in GCC" ON) # Options to exclude parts of the FSFW from compilation. option(FSFW_USE_RMAP "Compile with RMAP" ON) @@ -135,7 +143,20 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") -Wno-psabi ) endif() - + + if(FSFW_GENERATE_SECTIONS) + target_compile_options(${LIB_FSFW_NAME} PRIVATE + "-ffunction-sections" + "-fdata-sections" + ) + endif() + + if(FSFW_REMOVE_UNUSED_CODE) + target_link_options(${LIB_FSFW_NAME} PRIVATE + "Wl,--gc-sections" + ) + endif() + if(FSFW_WARNING_SHADOW_LOCAL_GCC) list(APPEND WARNING_FLAGS "-Wshadow=local") endif() From 3a90578780582e0fd8d06dab3bd44dbef066f012 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 27 Mar 2021 10:40:38 +0100 Subject: [PATCH 103/230] minor bridge improveements --- tmtcservices/TmTcBridge.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index 228bf4f5..f99b9051 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -4,6 +4,8 @@ #include "../serviceinterface/ServiceInterface.h" #include "../globalfunctions/arrayprinter.h" +#define TMTCBRIDGE_WIRETAPPING 0 + TmTcBridge::TmTcBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId, object_id_t tcStoreId): SystemObject(objectId),tmStoreId(tmStoreId), tcStoreId(tcStoreId), @@ -234,17 +236,11 @@ ReturnValue_t TmTcBridge::handleStoredTm() { void TmTcBridge::registerCommConnect() { if(not communicationLinkUp) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - //sif::info << "TMTC Bridge: Registered Comm Link Connect" << std::endl; -#endif communicationLinkUp = true; } } void TmTcBridge::registerCommDisconnect() { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - //sif::info << "TMTC Bridge: Registered Comm Link Disconnect" << std::endl; -#endif if(communicationLinkUp) { communicationLinkUp = false; } From eea482b4388dcfd9365a12015588dedc370dd2c1 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 27 Mar 2021 21:27:46 +0100 Subject: [PATCH 104/230] added specific compile definitions --- CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3b0917fd..852c18b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,15 +26,20 @@ if(NOT OS_FSFW) endif() +set(FSFW_OSAL_DEFINITION FSFW_HOST) + if(${OS_FSFW} STREQUAL host) set(OS_FSFW_NAME "Host") elseif(${OS_FSFW} STREQUAL linux) set(OS_FSFW_NAME "Linux") + set(FSFW_OSAL_DEFINITION FSFW_LINUX) elseif(${OS_FSFW} STREQUAL freertos) set(OS_FSFW_NAME "FreeRTOS") target_link_libraries(${LIB_FSFW_NAME} ${LIB_OS_NAME}) + set(FSFW_OSAL_DEFINITION FSFW_FREERTOS) elseif(${OS_FSFW} STREQUAL rtems) set(OS_FSFW_NAME "RTEMS") + set(FSFW_OSAL_DEFINITION FSFW_RTEMS) else() message(WARNING "Invalid operating system for FSFW specified! Setting to host.." @@ -43,6 +48,10 @@ else() set(OS_FSFW "host") endif() +target_compile_definitions(${LIB_FSFW_NAME} INTERFACE PRIVATE + ${FSFW_OSAL_DEFINITION} +) + message(STATUS "Compiling FSFW for the ${OS_FSFW_NAME} operating system.") add_subdirectory(action) From 3a75be2683ac48ed7efa03e10f97e308fee99323 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 27 Mar 2021 21:51:04 +0100 Subject: [PATCH 105/230] this version is working --- CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 73b6b873..ff060d7b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,7 +58,11 @@ else() set(OS_FSFW "host") endif() -target_compile_definitions(${LIB_FSFW_NAME} INTERFACE PRIVATE +target_compile_definitions(${LIB_FSFW_NAME} PRIVATE + ${FSFW_OSAL_DEFINITION} +) + +target_compile_definitions(${LIB_FSFW_NAME} INTERFACE ${FSFW_OSAL_DEFINITION} ) From 3429918f5e35ed9ed942c946fdf0d19ed6379f26 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 30 Mar 2021 00:25:22 +0200 Subject: [PATCH 106/230] fixed cmakelists for linux --- osal/CMakeLists.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/osal/CMakeLists.txt b/osal/CMakeLists.txt index e4f1de7c..6cda0c88 100644 --- a/osal/CMakeLists.txt +++ b/osal/CMakeLists.txt @@ -10,11 +10,6 @@ elseif(${OS_FSFW} STREQUAL "host") if (WIN32) add_subdirectory(windows) elseif(UNIX) - target_sources(${LIB_FSFW_NAME} - PUBLIC - linux/TcUnixUdpPollingTask.cpp - linux/TmTcUnixUdpBridge.cpp - ) endif () else() From 435c6e641021ce450ba88b1cb57c960a5548f784 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 30 Mar 2021 00:37:10 +0200 Subject: [PATCH 107/230] bugfix for linux/host --- osal/CMakeLists.txt | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/osal/CMakeLists.txt b/osal/CMakeLists.txt index 6cda0c88..76b939b1 100644 --- a/osal/CMakeLists.txt +++ b/osal/CMakeLists.txt @@ -1,30 +1,34 @@ # Check the OS_FSFW variable if(${OS_FSFW} STREQUAL "freertos") - add_subdirectory(FreeRTOS) + add_subdirectory(FreeRTOS) elseif(${OS_FSFW} STREQUAL "rtems") - add_subdirectory(rtems) + add_subdirectory(rtems) elseif(${OS_FSFW} STREQUAL "linux") - add_subdirectory(linux) + add_subdirectory(linux) elseif(${OS_FSFW} STREQUAL "host") - add_subdirectory(host) - if (WIN32) - add_subdirectory(windows) - elseif(UNIX) - endif () + add_subdirectory(host) + if (WIN32) + add_subdirectory(windows) + elseif(UNIX) + # We still need to pull in some Linux specific sources + target_sources(${LIB_FSFW_NAME} PUBLIC + linux/tcpipHelpers.cpp + ) + endif () else() - message(WARNING "The OS_FSFW variable was not set. Assuming host OS..") - # Not set. Assumuing this is a host build, try to determine host OS - if (WIN32) - add_subdirectory(host) - add_subdirectory(windows) - elseif (UNIX) - add_subdirectory(linux) - else () - # MacOS or other OSes have not been tested yet / are not supported. - message(FATAL_ERROR "The host OS could not be determined! Aborting.") - endif() + message(WARNING "The OS_FSFW variable was not set. Assuming host OS..") + # Not set. Assumuing this is a host build, try to determine host OS + if (WIN32) + add_subdirectory(host) + add_subdirectory(windows) + elseif (UNIX) + add_subdirectory(linux) + else () + # MacOS or other OSes have not been tested yet / are not supported. + message(FATAL_ERROR "The host OS could not be determined! Aborting.") + endif() endif() From d1a256cbf66223fe47dcb1c7b8c825b6fcfa943c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 31 Mar 2021 19:53:58 +0200 Subject: [PATCH 108/230] added missing include --- osal/linux/tcpipHelpers.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/osal/linux/tcpipHelpers.cpp b/osal/linux/tcpipHelpers.cpp index 4c1b9a78..3e8f6009 100644 --- a/osal/linux/tcpipHelpers.cpp +++ b/osal/linux/tcpipHelpers.cpp @@ -1,5 +1,6 @@ #include "../common/tcpipHelpers.h" +#include "../../serviceinterface/ServiceInterface.h" #include "../../tasks/TaskFactory.h" #include From dea2205908f29cbb700ad85c2614da71b6efccfc Mon Sep 17 00:00:00 2001 From: IRS Cleanroom Laptop Date: Thu, 1 Apr 2021 15:20:53 +0200 Subject: [PATCH 109/230] improved output --- devicehandlers/DeviceHandlerBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 0649aaa0..e46bd5de 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -1516,7 +1516,7 @@ void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType, } else if(errorType == sif::OutputTypes::OUT_ERROR) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "DeviceHandlerBase::" << functionName << ": Object ID " + sif::error << "DeviceHandlerBase::" << functionName << ": Object ID 0x" << std::hex << std::setw(8) << std::setfill('0') << this->getObjectId() << " | " << errorPrint << std::dec << std::setfill(' ') << std::endl; From 0e76333d3315f2278397935d220c20f64b6e838a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 7 Apr 2021 12:03:28 +0200 Subject: [PATCH 110/230] minor improvements for PUS distributor --- tcdistribution/PUSDistributor.cpp | 121 +++++++++++++++++------------- 1 file changed, 68 insertions(+), 53 deletions(-) diff --git a/tcdistribution/PUSDistributor.cpp b/tcdistribution/PUSDistributor.cpp index 00fd9029..0a95c5ef 100644 --- a/tcdistribution/PUSDistributor.cpp +++ b/tcdistribution/PUSDistributor.cpp @@ -1,22 +1,24 @@ #include "CCSDSDistributorIF.h" #include "PUSDistributor.h" -#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../serviceinterface/ServiceInterface.h" #include "../tmtcpacket/pus/TcPacketStored.h" #include "../tmtcservices/PusVerificationReport.h" +#define PUS_DISTRIBUTOR_DEBUGGING 1 + PUSDistributor::PUSDistributor(uint16_t setApid, object_id_t setObjectId, - object_id_t setPacketSource) : - TcDistributor(setObjectId), checker(setApid), verifyChannel(), - tcStatus(RETURN_FAILED), packetSource(setPacketSource) {} + object_id_t setPacketSource) : + TcDistributor(setObjectId), checker(setApid), verifyChannel(), + tcStatus(RETURN_FAILED), packetSource(setPacketSource) {} PUSDistributor::~PUSDistributor() {} PUSDistributor::TcMqMapIter PUSDistributor::selectDestination() { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - // sif:: debug << "PUSDistributor::handlePacket received: " - // << this->current_packet_id.store_index << ", " - // << this->current_packet_id.packet_index << std::endl; +#if FSFW_CPP_OSTREAM_ENABLED == 1 && PUS_DISTRIBUTOR_DEBUGGING == 1 + store_address_t storeId = this->currentMessage.getStorageId()); + sif:: debug << "PUSDistributor::handlePacket received: " << storeId.poolIndex << ", " << + storeId.packetIndex << std::endl; #endif TcMqMapIter queueMapIt = this->queueMap.end(); if(this->currentPacket == nullptr) { @@ -25,15 +27,17 @@ PUSDistributor::TcMqMapIter PUSDistributor::selectDestination() { this->currentPacket->setStoreAddress(this->currentMessage.getStorageId()); if (currentPacket->getWholeData() != nullptr) { tcStatus = checker.checkPacket(currentPacket); -#ifdef DEBUG if(tcStatus != HasReturnvaluesIF::RETURN_OK) { +#if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::debug << "PUSDistributor::handlePacket: Packet format " - << "invalid, code "<< static_cast(tcStatus) - << std::endl; + sif::debug << "PUSDistributor::handlePacket: Packet format invalid, code " << + static_cast(tcStatus) << std::endl; +#else + sif::printDebug("PUSDistributor::handlePacket: Packet format invalid, code %d\n", + static_cast(tcStatus)); +#endif #endif } -#endif uint32_t queue_id = currentPacket->getService(); queueMapIt = this->queueMap.find(queue_id); } @@ -43,11 +47,12 @@ PUSDistributor::TcMqMapIter PUSDistributor::selectDestination() { if (queueMapIt == this->queueMap.end()) { tcStatus = DESTINATION_NOT_FOUND; -#ifdef DEBUG +#if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::debug << "PUSDistributor::handlePacket: Destination not found, " - << "code "<< static_cast(tcStatus) << std::endl; -#endif + sif::debug << "PUSDistributor::handlePacket: Destination not found" << std::endl; +#else + sif::printDebug("PUSDistributor::handlePacket: Destination not found\n"); +#endif /* !FSFW_CPP_OSTREAM_ENABLED == 1 */ #endif } @@ -62,46 +67,54 @@ PUSDistributor::TcMqMapIter PUSDistributor::selectDestination() { ReturnValue_t PUSDistributor::registerService(AcceptsTelecommandsIF* service) { - uint16_t serviceId = service->getIdentifier(); + uint16_t serviceId = service->getIdentifier(); +#if PUS_DISTRIBUTOR_DEBUGGING == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - // sif::info << "Service ID: " << (int)serviceId << std::endl; + sif::info << "Service ID: " << static_cast(serviceId) << std::endl; +#else + sif::printInfo("Service ID: %d\n", static_cast(serviceId)); #endif - MessageQueueId_t queue = service->getRequestQueue(); - auto returnPair = queueMap.emplace(serviceId, queue); - if (not returnPair.second) { +#endif + MessageQueueId_t queue = service->getRequestQueue(); + auto returnPair = queueMap.emplace(serviceId, queue); + if (not returnPair.second) { +#if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PUSDistributor::registerService: Service ID already" - " exists in map." << std::endl; + sif::error << "PUSDistributor::registerService: Service ID already" + " exists in map" << std::endl; +#else + sif::printError("PUSDistributor::registerService: Service ID already exists in map\n"); #endif - return SERVICE_ID_ALREADY_EXISTS; - } - return HasReturnvaluesIF::RETURN_OK; +#endif + return SERVICE_ID_ALREADY_EXISTS; + } + return HasReturnvaluesIF::RETURN_OK; } MessageQueueId_t PUSDistributor::getRequestQueue() { - return tcQueue->getId(); + return tcQueue->getId(); } ReturnValue_t PUSDistributor::callbackAfterSending(ReturnValue_t queueStatus) { - if (queueStatus != RETURN_OK) { - tcStatus = queueStatus; - } - if (tcStatus != RETURN_OK) { - this->verifyChannel.sendFailureReport(tc_verification::ACCEPTANCE_FAILURE, - currentPacket, tcStatus); - // A failed packet is deleted immediately after reporting, - // otherwise it will block memory. - currentPacket->deletePacket(); - return RETURN_FAILED; - } else { - this->verifyChannel.sendSuccessReport(tc_verification::ACCEPTANCE_SUCCESS, - currentPacket); - return RETURN_OK; - } + if (queueStatus != RETURN_OK) { + tcStatus = queueStatus; + } + if (tcStatus != RETURN_OK) { + this->verifyChannel.sendFailureReport(tc_verification::ACCEPTANCE_FAILURE, + currentPacket, tcStatus); + // A failed packet is deleted immediately after reporting, + // otherwise it will block memory. + currentPacket->deletePacket(); + return RETURN_FAILED; + } else { + this->verifyChannel.sendSuccessReport(tc_verification::ACCEPTANCE_SUCCESS, + currentPacket); + return RETURN_OK; + } } uint16_t PUSDistributor::getIdentifier() { - return checker.getApid(); + return checker.getApid(); } ReturnValue_t PUSDistributor::initialize() { @@ -111,15 +124,17 @@ ReturnValue_t PUSDistributor::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } - CCSDSDistributorIF* ccsdsDistributor = - objectManager->get(packetSource); - if (ccsdsDistributor == nullptr) { + CCSDSDistributorIF* ccsdsDistributor = + objectManager->get(packetSource); + if (ccsdsDistributor == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PUSDistributor::initialize: Packet source invalid." - << " Make sure it exists and implements CCSDSDistributorIF!" - << std::endl; + sif::error << "PUSDistributor::initialize: Packet source invalid" << std::endl; + sif::error << " Make sure it exists and implements CCSDSDistributorIF!" << std::endl; +#else + sif::printError("PUSDistributor::initialize: Packet source invalid\n"); + sif::printError("Make sure it exists and implements CCSDSDistributorIF\n"); #endif - return RETURN_FAILED; - } - return ccsdsDistributor->registerApplication(this); + return RETURN_FAILED; + } + return ccsdsDistributor->registerApplication(this); } From 7322a7d0f53e0ae72b69cac1a4abffbe74543365 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 7 Apr 2021 12:09:06 +0200 Subject: [PATCH 111/230] improvements for ccsds distributor --- tcdistribution/CCSDSDistributor.cpp | 31 ++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/tcdistribution/CCSDSDistributor.cpp b/tcdistribution/CCSDSDistributor.cpp index b795854f..f3864066 100644 --- a/tcdistribution/CCSDSDistributor.cpp +++ b/tcdistribution/CCSDSDistributor.cpp @@ -1,8 +1,10 @@ #include "CCSDSDistributor.h" -#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../serviceinterface/ServiceInterface.h" #include "../tmtcpacket/SpacePacketBase.h" +#define CCSDS_DISTRIBUTOR_DEBUGGING 1 + CCSDSDistributor::CCSDSDistributor(uint16_t setDefaultApid, object_id_t setObjectId): TcDistributor(setObjectId), defaultApid( setDefaultApid ) { @@ -11,26 +13,36 @@ CCSDSDistributor::CCSDSDistributor(uint16_t setDefaultApid, CCSDSDistributor::~CCSDSDistributor() {} TcDistributor::TcMqMapIter CCSDSDistributor::selectDestination() { +#if CCSDS_DISTRIBUTOR_DEBUGGING == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 -// sif::debug << "CCSDSDistributor::selectDestination received: " << -// this->currentMessage.getStorageId().pool_index << ", " << -// this->currentMessage.getStorageId().packet_index << std::endl; + sif::debug << "CCSDSDistributor::selectDestination received: " << + this->currentMessage.getStorageId().poolIndex << ", " << + this->currentMessage.getStorageId().packetIndex << std::endl; +#else + sif::printDebug("CCSDSDistributor::selectDestination received: %d, %d\n", + currentMessage.getStorageId().poolIndex, currentMessage.getStorageId().packetIndex); +#endif #endif const uint8_t* packet = nullptr; size_t size = 0; ReturnValue_t result = this->tcStore->getData(currentMessage.getStorageId(), &packet, &size ); if(result != HasReturnvaluesIF::RETURN_OK) { +#if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "CCSDSDistributor::selectDestination: Getting data from" " store failed!" << std::endl; +#else + sif::printError("CCSDSDistributor::selectDestination: Getting data from" + " store failed!\n"); +#endif #endif } SpacePacketBase currentPacket(packet); -#if FSFW_CPP_OSTREAM_ENABLED == 1 -// sif:: info << "CCSDSDistributor::selectDestination has packet with APID " -// << std::hex << currentPacket.getAPID() << std::dec << std::endl; +#if FSFW_CPP_OSTREAM_ENABLED == 1 && CCSDS_DISTRIBUTOR_DEBUGGING == 1 + sif::info << "CCSDSDistributor::selectDestination has packet with APID " << std::hex << + currentPacket.getAPID() << std::dec << std::endl; #endif TcMqMapIter position = this->queueMap.find(currentPacket.getAPID()); if ( position != this->queueMap.end() ) { @@ -76,9 +88,14 @@ ReturnValue_t CCSDSDistributor::initialize() { ReturnValue_t status = this->TcDistributor::initialize(); this->tcStore = objectManager->get( objects::TC_STORE ); if (this->tcStore == nullptr) { +#if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "CCSDSDistributor::initialize: Could not initialize" " TC store!" << std::endl; +#else + sif::printError("CCSDSDistributor::initialize: Could not initialize" + " TC store!\n"); +#endif #endif status = RETURN_FAILED; } From 3ff54844153aa81cbb0c5c6b5546be4bd4a30904 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 7 Apr 2021 13:44:03 +0200 Subject: [PATCH 112/230] disabled debugging mode --- tcdistribution/CCSDSDistributor.cpp | 2 +- tcdistribution/PUSDistributor.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tcdistribution/CCSDSDistributor.cpp b/tcdistribution/CCSDSDistributor.cpp index f3864066..62cbfbf2 100644 --- a/tcdistribution/CCSDSDistributor.cpp +++ b/tcdistribution/CCSDSDistributor.cpp @@ -3,7 +3,7 @@ #include "../serviceinterface/ServiceInterface.h" #include "../tmtcpacket/SpacePacketBase.h" -#define CCSDS_DISTRIBUTOR_DEBUGGING 1 +#define CCSDS_DISTRIBUTOR_DEBUGGING 0 CCSDSDistributor::CCSDSDistributor(uint16_t setDefaultApid, object_id_t setObjectId): diff --git a/tcdistribution/PUSDistributor.cpp b/tcdistribution/PUSDistributor.cpp index 0a95c5ef..abdd1f8d 100644 --- a/tcdistribution/PUSDistributor.cpp +++ b/tcdistribution/PUSDistributor.cpp @@ -5,7 +5,7 @@ #include "../tmtcpacket/pus/TcPacketStored.h" #include "../tmtcservices/PusVerificationReport.h" -#define PUS_DISTRIBUTOR_DEBUGGING 1 +#define PUS_DISTRIBUTOR_DEBUGGING 0 PUSDistributor::PUSDistributor(uint16_t setApid, object_id_t setObjectId, object_id_t setPacketSource) : From 43ddb445737575a8847e895aea279a57f4e0a6a1 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 7 Apr 2021 22:12:01 +0200 Subject: [PATCH 113/230] fixed temperature sensor object --- thermal/TemperatureSensor.h | 54 +++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/thermal/TemperatureSensor.h b/thermal/TemperatureSensor.h index 2b1fb1f0..ceb8a861 100644 --- a/thermal/TemperatureSensor.h +++ b/thermal/TemperatureSensor.h @@ -1,11 +1,14 @@ #ifndef TEMPERATURESENSOR_H_ #define TEMPERATURESENSOR_H_ -#include "../thermal/AbstractTemperatureSensor.h" -#include "../datapoolglob/GlobalDataSet.h" -#include "../datapoolglob/GlobalPoolVariable.h" +#include "tcsDefinitions.h" +#include "AbstractTemperatureSensor.h" + +#include "../datapoollocal/LocalPoolDataSetBase.h" +#include "../datapoollocal/LocalPoolVariable.h" #include "../monitoring/LimitMonitor.h" + /** * @brief This building block handles non-linear value conversion and * range checks for analog temperature sensors. @@ -57,27 +60,26 @@ public: /** * Instantiate Temperature Sensor Object. - * @param setObjectid objectId of the sensor object - * @param inputValue Input value which is converted to a temperature - * @param poolVariable Pool Variable to store the temperature value - * @param vectorIndex Vector Index for the sensor monitor - * @param parameters Calculation parameters, temperature limits, gradient limit - * @param datapoolId Datapool ID of the output temperature - * @param outputSet Output dataset for the output temperature to fetch it with read() + * @param setObjectid objectId of the sensor object + * @param inputValue Pointer to input value which is converted to a temperature + * @param variableGpid Global Pool ID of the output value + * @param inputVariable Input variable handle + * @param vectorIndex Vector Index for the sensor monitor + * @param parameters Calculation parameters, temperature limits, gradient limit + * @param outputSet Output dataset for the output temperature to fetch it with read() * @param thermalModule respective thermal module, if it has one */ TemperatureSensor(object_id_t setObjectid, - inputType *inputValue, PoolVariableIF *poolVariable, - uint8_t vectorIndex, uint32_t datapoolId, Parameters parameters = {0, 0, 0, 0, 0, 0}, - GlobDataSet *outputSet = NULL, ThermalModuleIF *thermalModule = NULL) : + inputType *inputValue, gp_id_t variableGpid, PoolVariableIF* inputVariable, + uint8_t vectorIndex, Parameters parameters = {0, 0, 0, 0, 0, 0}, + LocalPoolDataSetBase *outputSet = NULL, ThermalModuleIF *thermalModule = NULL) : AbstractTemperatureSensor(setObjectid, thermalModule), parameters(parameters), - inputValue(inputValue), poolVariable(poolVariable), - outputTemperature(datapoolId, outputSet, PoolVariableIF::VAR_WRITE), - sensorMonitor(setObjectid, DOMAIN_ID_SENSOR, - GlobalDataPool::poolIdAndPositionToPid(poolVariable->getDataPoolId(), vectorIndex), + inputValue(inputValue), poolVariable(inputVariable), + outputTemperature(variableGpid, outputSet, PoolVariableIF::VAR_WRITE), + sensorMonitor(setObjectid, DOMAIN_ID_SENSOR, poolVariable, DEFAULT_CONFIRMATION_COUNT, parameters.lowerLimit, parameters.upperLimit, TEMP_SENSOR_LOW, TEMP_SENSOR_HIGH), - oldTemperature(20), uptimeOfOldTemperature( { INVALID_TEMPERATURE, 0 }) { + oldTemperature(20), uptimeOfOldTemperature({ thermal::INVALID_TEMPERATURE, 0 }) { } @@ -98,7 +100,7 @@ protected: private: void setInvalid() { - outputTemperature = INVALID_TEMPERATURE; + outputTemperature = thermal::INVALID_TEMPERATURE; outputTemperature.setValid(false); uptimeOfOldTemperature.tv_sec = INVALID_UPTIME; sensorMonitor.setToInvalid(); @@ -108,11 +110,11 @@ protected: UsedParameters parameters; - inputType * inputValue; + inputType* inputValue; - PoolVariableIF *poolVariable; + PoolVariableIF* poolVariable; - gp_float_t outputTemperature; + lp_var_t outputTemperature; LimitMonitor sensorMonitor; @@ -120,8 +122,8 @@ protected: timeval uptimeOfOldTemperature; void doChildOperation() { - if (!poolVariable->isValid() - || !healthHelper.healthTable->isHealthy(getObjectId())) { + if ((not poolVariable->isValid()) or + (not healthHelper.healthTable->isHealthy(getObjectId()))) { setInvalid(); return; } @@ -152,13 +154,13 @@ protected: } } - //Check is done against raw limits. SHOULDDO: Why? Using �C would be more easy to handle. + //Check is done against raw limits. SHOULDDO: Why? Using C would be more easy to handle. sensorMonitor.doCheck(outputTemperature.value); if (sensorMonitor.isOutOfLimits()) { uptimeOfOldTemperature.tv_sec = INVALID_UPTIME; outputTemperature.setValid(PoolVariableIF::INVALID); - outputTemperature = INVALID_TEMPERATURE; + outputTemperature = thermal::INVALID_TEMPERATURE; } else { oldTemperature = outputTemperature; uptimeOfOldTemperature = uptime; From 80aab5f461fa0f462aff4743c95413299642ce06 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 8 Apr 2021 15:25:22 +0200 Subject: [PATCH 114/230] super evil bug --- osal/linux/MessageQueue.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index 60d15dee..b40ff29b 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -190,13 +190,14 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { return HasReturnvaluesIF::RETURN_FAILED; } return HasReturnvaluesIF::RETURN_OK; - }else if(status==0){ + } + else if(status==0) { //Success but no message received return MessageQueueIF::EMPTY; } else { //No message was received. Keep lastPartner anyway, I might send //something later. But still, delete packet content. - memset(message->getData(), 0, message->getMaximumMessageSize()); + memset(message->getBuffer(), 0, message->getMaximumMessageSize()); switch(errno){ case EAGAIN: //O_NONBLOCK or MQ_NONBLOCK was set and there are no messages From 6983ddc3e022bfcf1e78354998e4577b20e146b0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 8 Apr 2021 15:27:03 +0200 Subject: [PATCH 115/230] super evil bugfix --- osal/linux/MessageQueue.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index 60d15dee..b40ff29b 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -190,13 +190,14 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { return HasReturnvaluesIF::RETURN_FAILED; } return HasReturnvaluesIF::RETURN_OK; - }else if(status==0){ + } + else if(status==0) { //Success but no message received return MessageQueueIF::EMPTY; } else { //No message was received. Keep lastPartner anyway, I might send //something later. But still, delete packet content. - memset(message->getData(), 0, message->getMaximumMessageSize()); + memset(message->getBuffer(), 0, message->getMaximumMessageSize()); switch(errno){ case EAGAIN: //O_NONBLOCK or MQ_NONBLOCK was set and there are no messages From 9ee1bd15c4f82e10edc8aba250686ed70f1699ae Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 8 Apr 2021 15:38:36 +0200 Subject: [PATCH 116/230] now fixed properly --- ipc/MessageQueueMessage.cpp | 4 ++++ ipc/MessageQueueMessage.h | 1 + ipc/MessageQueueMessageIF.h | 1 + osal/linux/MessageQueue.cpp | 7 ++++--- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ipc/MessageQueueMessage.cpp b/ipc/MessageQueueMessage.cpp index e97778c3..1958af54 100644 --- a/ipc/MessageQueueMessage.cpp +++ b/ipc/MessageQueueMessage.cpp @@ -86,3 +86,7 @@ size_t MessageQueueMessage::getMaximumMessageSize() const { return this->MAX_MESSAGE_SIZE; } +size_t MessageQueueMessage::getMaximumDataSize() const { + return this->MAX_DATA_SIZE; +} + diff --git a/ipc/MessageQueueMessage.h b/ipc/MessageQueueMessage.h index 5234f64f..111056ca 100644 --- a/ipc/MessageQueueMessage.h +++ b/ipc/MessageQueueMessage.h @@ -139,6 +139,7 @@ public: virtual void setMessageSize(size_t messageSize) override; virtual size_t getMinimumMessageSize() const override; virtual size_t getMaximumMessageSize() const override; + virtual size_t getMaximumDataSize() const override; /** * @brief This is a debug method that prints the content. diff --git a/ipc/MessageQueueMessageIF.h b/ipc/MessageQueueMessageIF.h index 33e01e7d..893c30b5 100644 --- a/ipc/MessageQueueMessageIF.h +++ b/ipc/MessageQueueMessageIF.h @@ -72,6 +72,7 @@ public: virtual void setMessageSize(size_t messageSize) = 0; virtual size_t getMinimumMessageSize() const = 0; virtual size_t getMaximumMessageSize() const = 0; + virtual size_t getMaximumDataSize() const = 0; }; diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index b40ff29b..8004c045 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -191,13 +191,14 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { } return HasReturnvaluesIF::RETURN_OK; } - else if(status==0) { + else if (status==0) { //Success but no message received return MessageQueueIF::EMPTY; - } else { + } + else { //No message was received. Keep lastPartner anyway, I might send //something later. But still, delete packet content. - memset(message->getBuffer(), 0, message->getMaximumMessageSize()); + memset(message->getData(), 0, message->getMaximumDataSize()); switch(errno){ case EAGAIN: //O_NONBLOCK or MQ_NONBLOCK was set and there are no messages From 23e3f2f34f1b68998a8aad6c01691d2e9c97ed65 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 8 Apr 2021 15:39:23 +0200 Subject: [PATCH 117/230] now fixed properly --- ipc/MessageQueueMessage.cpp | 4 ++++ ipc/MessageQueueMessage.h | 1 + ipc/MessageQueueMessageIF.h | 1 + osal/linux/MessageQueue.cpp | 7 ++++--- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ipc/MessageQueueMessage.cpp b/ipc/MessageQueueMessage.cpp index e97778c3..1958af54 100644 --- a/ipc/MessageQueueMessage.cpp +++ b/ipc/MessageQueueMessage.cpp @@ -86,3 +86,7 @@ size_t MessageQueueMessage::getMaximumMessageSize() const { return this->MAX_MESSAGE_SIZE; } +size_t MessageQueueMessage::getMaximumDataSize() const { + return this->MAX_DATA_SIZE; +} + diff --git a/ipc/MessageQueueMessage.h b/ipc/MessageQueueMessage.h index 5234f64f..111056ca 100644 --- a/ipc/MessageQueueMessage.h +++ b/ipc/MessageQueueMessage.h @@ -139,6 +139,7 @@ public: virtual void setMessageSize(size_t messageSize) override; virtual size_t getMinimumMessageSize() const override; virtual size_t getMaximumMessageSize() const override; + virtual size_t getMaximumDataSize() const override; /** * @brief This is a debug method that prints the content. diff --git a/ipc/MessageQueueMessageIF.h b/ipc/MessageQueueMessageIF.h index 33e01e7d..893c30b5 100644 --- a/ipc/MessageQueueMessageIF.h +++ b/ipc/MessageQueueMessageIF.h @@ -72,6 +72,7 @@ public: virtual void setMessageSize(size_t messageSize) = 0; virtual size_t getMinimumMessageSize() const = 0; virtual size_t getMaximumMessageSize() const = 0; + virtual size_t getMaximumDataSize() const = 0; }; diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index b40ff29b..8004c045 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -191,13 +191,14 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { } return HasReturnvaluesIF::RETURN_OK; } - else if(status==0) { + else if (status==0) { //Success but no message received return MessageQueueIF::EMPTY; - } else { + } + else { //No message was received. Keep lastPartner anyway, I might send //something later. But still, delete packet content. - memset(message->getBuffer(), 0, message->getMaximumMessageSize()); + memset(message->getData(), 0, message->getMaximumDataSize()); switch(errno){ case EAGAIN: //O_NONBLOCK or MQ_NONBLOCK was set and there are no messages From e799e45198c19793d99a530e0d496f89d08107b3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 8 Apr 2021 16:20:24 +0200 Subject: [PATCH 118/230] bugfix for RTEMS --- osal/rtems/MessageQueue.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osal/rtems/MessageQueue.cpp b/osal/rtems/MessageQueue.cpp index bfaf3569..717b80dd 100644 --- a/osal/rtems/MessageQueue.cpp +++ b/osal/rtems/MessageQueue.cpp @@ -61,7 +61,7 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { } else { //No message was received. Keep lastPartner anyway, I might send something later. //But still, delete packet content. - memset(message->getData(), 0, message->getMaximumMessageSize()); + memset(message->getData(), 0, message->getMaximumDataSize()); } return convertReturnCode(status); } From 10c3483fe51bfaac7f385332fb0fbc3d9ff1f57e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 8 Apr 2021 16:20:59 +0200 Subject: [PATCH 119/230] bugfix for RTEMS --- osal/rtems/MessageQueue.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osal/rtems/MessageQueue.cpp b/osal/rtems/MessageQueue.cpp index bfaf3569..717b80dd 100644 --- a/osal/rtems/MessageQueue.cpp +++ b/osal/rtems/MessageQueue.cpp @@ -61,7 +61,7 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { } else { //No message was received. Keep lastPartner anyway, I might send something later. //But still, delete packet content. - memset(message->getData(), 0, message->getMaximumMessageSize()); + memset(message->getData(), 0, message->getMaximumDataSize()); } return convertReturnCode(status); } From 38d929c2a8df4451129bad3b464f3119fffe96ab Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 8 Apr 2021 18:48:44 +0200 Subject: [PATCH 120/230] coverity fixes --- osal/common/TcpTmTcServer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/osal/common/TcpTmTcServer.cpp b/osal/common/TcpTmTcServer.cpp index 296afad8..2bfd4876 100644 --- a/osal/common/TcpTmTcServer.cpp +++ b/osal/common/TcpTmTcServer.cpp @@ -70,6 +70,7 @@ ReturnValue_t TcpTmTcServer::initialize() { #endif freeaddrinfo(addrResult); handleError(Protocol::TCP, ErrorSources::BIND_CALL); + return HasReturnvaluesIF::RETURN_FAILED; } freeaddrinfo(addrResult); From f988271be4dbae63963755871451dc95d3085efd Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 8 Apr 2021 18:53:22 +0200 Subject: [PATCH 121/230] coverity fixes --- container/SharedRingBuffer.cpp | 3 +++ container/SharedRingBuffer.h | 23 +++++++++++++---------- osal/common/TcpTmTcServer.cpp | 6 ++++-- osal/common/UdpTmTcBridge.cpp | 1 + 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/container/SharedRingBuffer.cpp b/container/SharedRingBuffer.cpp index 5e20bb6f..fe36341d 100644 --- a/container/SharedRingBuffer.cpp +++ b/container/SharedRingBuffer.cpp @@ -17,6 +17,9 @@ SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t *buffer, mutex = MutexFactory::instance()->createMutex(); } +SharedRingBuffer::~SharedRingBuffer() { + MutexFactory::instance()->deleteMutex(mutex); +} void SharedRingBuffer::setToUseReceiveSizeFIFO(size_t fifoDepth) { this->fifoDepth = fifoDepth; diff --git a/container/SharedRingBuffer.h b/container/SharedRingBuffer.h index 66a119ab..9d6ea56c 100644 --- a/container/SharedRingBuffer.h +++ b/container/SharedRingBuffer.h @@ -26,6 +26,18 @@ public: */ SharedRingBuffer(object_id_t objectId, const size_t size, bool overwriteOld, size_t maxExcessBytes); + /** + * This constructor takes an external buffer with the specified size. + * @param buffer + * @param size + * @param overwriteOld + * If the ring buffer is overflowing at a write operartion, the oldest data + * will be overwritten. + */ + SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const size_t size, + bool overwriteOld, size_t maxExcessBytes); + + virtual~ SharedRingBuffer(); /** * @brief This function can be used to add an optional FIFO to the class @@ -37,16 +49,7 @@ public: */ void setToUseReceiveSizeFIFO(size_t fifoDepth); - /** - * This constructor takes an external buffer with the specified size. - * @param buffer - * @param size - * @param overwriteOld - * If the ring buffer is overflowing at a write operartion, the oldest data - * will be overwritten. - */ - SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const size_t size, - bool overwriteOld, size_t maxExcessBytes); + /** * Unless a read-only constant value is read, all operations on the diff --git a/osal/common/TcpTmTcServer.cpp b/osal/common/TcpTmTcServer.cpp index 2bfd4876..08a62ffb 100644 --- a/osal/common/TcpTmTcServer.cpp +++ b/osal/common/TcpTmTcServer.cpp @@ -85,8 +85,8 @@ TcpTmTcServer::~TcpTmTcServer() { 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_t clientSocket; - sockaddr clientSockAddr; + socket_t clientSocket = 0; + sockaddr clientSockAddr = {}; socklen_t connectorSockAddrLen = 0; int retval = 0; @@ -102,6 +102,7 @@ ReturnValue_t TcpTmTcServer::performOperation(uint8_t opCode) { if(clientSocket == INVALID_SOCKET) { handleError(Protocol::TCP, ErrorSources::ACCEPT_CALL, 500); + closeSocket(clientSocket); continue; }; @@ -123,6 +124,7 @@ ReturnValue_t TcpTmTcServer::performOperation(uint8_t opCode) { /* Done, shut down connection */ retval = shutdown(clientSocket, SHUT_SEND); + closeSocket(clientSocket); } return HasReturnvaluesIF::RETURN_OK; } diff --git a/osal/common/UdpTmTcBridge.cpp b/osal/common/UdpTmTcBridge.cpp index 7f3dc929..798be6f5 100644 --- a/osal/common/UdpTmTcBridge.cpp +++ b/osal/common/UdpTmTcBridge.cpp @@ -103,6 +103,7 @@ ReturnValue_t UdpTmTcBridge::initialize() { #endif freeaddrinfo(addrResult); tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::BIND_CALL); + return HasReturnvaluesIF::RETURN_FAILED; } freeaddrinfo(addrResult); return HasReturnvaluesIF::RETURN_OK; From 00d9a4f3ed44b1bc929271f93f126105aa866616 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 8 Apr 2021 18:57:24 +0200 Subject: [PATCH 122/230] more coverity fixes --- osal/host/FixedTimeslotTask.cpp | 1 - osal/host/PeriodicTask.cpp | 1 - osal/host/QueueMapManager.cpp | 4 ++++ osal/host/QueueMapManager.h | 2 ++ 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/osal/host/FixedTimeslotTask.cpp b/osal/host/FixedTimeslotTask.cpp index 3b169b5a..ee149922 100644 --- a/osal/host/FixedTimeslotTask.cpp +++ b/osal/host/FixedTimeslotTask.cpp @@ -38,7 +38,6 @@ FixedTimeslotTask::~FixedTimeslotTask(void) { if(mainThread.joinable()) { mainThread.join(); } - delete this; } void FixedTimeslotTask::taskEntryPoint(void* argument) { diff --git a/osal/host/PeriodicTask.cpp b/osal/host/PeriodicTask.cpp index d7abf9d0..631264b7 100644 --- a/osal/host/PeriodicTask.cpp +++ b/osal/host/PeriodicTask.cpp @@ -38,7 +38,6 @@ PeriodicTask::~PeriodicTask(void) { if(mainThread.joinable()) { mainThread.join(); } - delete this; } void PeriodicTask::taskEntryPoint(void* argument) { diff --git a/osal/host/QueueMapManager.cpp b/osal/host/QueueMapManager.cpp index b50d62dc..c9100fe9 100644 --- a/osal/host/QueueMapManager.cpp +++ b/osal/host/QueueMapManager.cpp @@ -10,6 +10,10 @@ QueueMapManager::QueueMapManager() { mapLock = MutexFactory::instance()->createMutex(); } +QueueMapManager::~QueueMapManager() { + MutexFactory::instance()->deleteMutex(mapLock); +} + QueueMapManager* QueueMapManager::instance() { if (mqManagerInstance == nullptr){ mqManagerInstance = new QueueMapManager(); diff --git a/osal/host/QueueMapManager.h b/osal/host/QueueMapManager.h index 3610ca63..90c39c2f 100644 --- a/osal/host/QueueMapManager.h +++ b/osal/host/QueueMapManager.h @@ -36,6 +36,8 @@ public: private: //! External instantiation is forbidden. QueueMapManager(); + ~QueueMapManager(); + uint32_t queueCounter = 0; MutexIF* mapLock; QueueMap queueMap; From bddd8720b2898d785f6647d9d383ff65c3d2c4e0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 8 Apr 2021 18:59:48 +0200 Subject: [PATCH 123/230] another coverity fix --- osal/host/FixedTimeslotTask.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osal/host/FixedTimeslotTask.cpp b/osal/host/FixedTimeslotTask.cpp index ee149922..016b1404 100644 --- a/osal/host/FixedTimeslotTask.cpp +++ b/osal/host/FixedTimeslotTask.cpp @@ -118,8 +118,11 @@ ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, } #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "Component " << std::hex << componentId << - " not found, not adding it to pst" << std::endl; + sif::error << "Component " << std::hex << "0x" << componentId << "not found, " + "not adding it to PST.." << std::dec << std::endl; +#else + sif::printError("Component 0x%08x not found, not adding it to PST..\n", + static_cast(componentId)); #endif return HasReturnvaluesIF::RETURN_FAILED; } From efb7c8760a864e45e5686ce450fb8f7b06dc7500 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 8 Apr 2021 19:01:06 +0200 Subject: [PATCH 124/230] coverity action helper fix --- action/ActionHelper.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/action/ActionHelper.cpp b/action/ActionHelper.cpp index 4b64a40c..b2374ed6 100644 --- a/action/ActionHelper.cpp +++ b/action/ActionHelper.cpp @@ -147,11 +147,6 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, return result; } - if (result != HasReturnvaluesIF::RETURN_OK) { - ipcStore->deleteData(storeAddress); - return result; - } - /* We don't need to report the objectId, as we receive REQUESTED data before the completion success message. True aperiodic replies need to be reported with another dedicated message. */ ActionMessage::setDataReply(&reply, replyId, storeAddress); From b30a3aaa382c136df69329e16bae1dfac5f82aa1 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 8 Apr 2021 19:07:03 +0200 Subject: [PATCH 125/230] coverity fix --- osal/host/MessageQueue.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/osal/host/MessageQueue.cpp b/osal/host/MessageQueue.cpp index 18272a68..359ce8ec 100644 --- a/osal/host/MessageQueue.cpp +++ b/osal/host/MessageQueue.cpp @@ -106,6 +106,9 @@ bool MessageQueue::isDefaultDestinationSet() const { ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault) { + if(message == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } message->setSender(sentFrom); if(message->getMessageSize() > message->getMaximumMessageSize()) { // Actually, this should never happen or an error will be emitted @@ -128,12 +131,12 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, return HasReturnvaluesIF::RETURN_FAILED; } if(targetQueue->messageQueue.size() < targetQueue->messageDepth) { - MutexGuard mutexLock(targetQueue->queueLock, - MutexIF::TimeoutType::WAITING, 20); - // not ideal, works for now though. - MessageQueueMessage* mqmMessage = - dynamic_cast(message); - if(message != nullptr) { + MutexGuard mutexLock(targetQueue->queueLock, MutexIF::TimeoutType::WAITING, 20); + // TODO: Would be nice to support other message types, but this would require + // create the message on the heap from an upper layer and simply storing + // MessageQueueMessageIF pointers in the queue. + MessageQueueMessage* mqmMessage = dynamic_cast(message); + if(mqmMessage != nullptr) { targetQueue->messageQueue.push(*mqmMessage); } else { From 8f4ab6d7edd963166e9f4f0845ff85c9882aeb5a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 8 Apr 2021 19:07:51 +0200 Subject: [PATCH 126/230] coverity: initialize member --- serialize/SerializeElement.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serialize/SerializeElement.h b/serialize/SerializeElement.h index 47080292..d41098d8 100644 --- a/serialize/SerializeElement.h +++ b/serialize/SerializeElement.h @@ -57,7 +57,7 @@ public: return &entry; } - T entry; + T entry = 0; }; #endif /* FSFW_SERIALIZE_SERIALIZEELEMENT_H_ */ From dd367bf083422f24f0a2e9aea4ea8b9f213499ce Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 8 Apr 2021 19:09:00 +0200 Subject: [PATCH 127/230] coverity: initialize entry --- serialize/SerializeElement.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/serialize/SerializeElement.h b/serialize/SerializeElement.h index d41098d8..ba34393d 100644 --- a/serialize/SerializeElement.h +++ b/serialize/SerializeElement.h @@ -25,7 +25,7 @@ public: } SerializeElement() : - LinkedElement(this) { + LinkedElement(this), entry(0) { } ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize, @@ -57,7 +57,7 @@ public: return &entry; } - T entry = 0; + T entry; }; #endif /* FSFW_SERIALIZE_SERIALIZEELEMENT_H_ */ From e6a1a7cc2d5d5f17f02c70e8bb677d75cde5712e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 8 Apr 2021 19:10:49 +0200 Subject: [PATCH 128/230] coverity fix for event message --- events/EventMessage.cpp | 2 +- events/EventMessage.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/events/EventMessage.cpp b/events/EventMessage.cpp index bbc41e10..548b4f0f 100644 --- a/events/EventMessage.cpp +++ b/events/EventMessage.cpp @@ -109,6 +109,6 @@ bool EventMessage::isClearedEventMessage() { return getEvent() == INVALID_EVENT; } -size_t EventMessage::getMinimumMessageSize() { +size_t EventMessage::getMinimumMessageSize() const { return EVENT_MESSAGE_SIZE; } diff --git a/events/EventMessage.h b/events/EventMessage.h index 4d003bd7..f2f5ffb5 100644 --- a/events/EventMessage.h +++ b/events/EventMessage.h @@ -45,7 +45,7 @@ public: protected: static const Event INVALID_EVENT = 0; - virtual size_t getMinimumMessageSize(); + virtual size_t getMinimumMessageSize() const override; }; From 905d525aa27069e9948861879a5e104a35e40a4b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 8 Apr 2021 19:12:21 +0200 Subject: [PATCH 129/230] small fix DHB --- devicehandlers/DeviceHandlerBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 15eac11f..4a0b3582 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -1483,7 +1483,7 @@ void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType, if(errorCode == ObjectManagerIF::CHILD_INIT_FAILED) { errorPrint = "Initialization error"; } - if(errorCode == HasReturnvaluesIF::RETURN_FAILED) { + else if(errorCode == HasReturnvaluesIF::RETURN_FAILED) { if(errorType == sif::OutputTypes::OUT_WARNING) { errorPrint = "Generic Warning"; } From 2b84ab018c03774e6a8caff9bb87e9844498ec71 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 8 Apr 2021 20:53:54 +0200 Subject: [PATCH 130/230] implemented mq properly --- osal/host/MessageQueue.cpp | 24 ++++++------------------ osal/host/MessageQueue.h | 2 +- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/osal/host/MessageQueue.cpp b/osal/host/MessageQueue.cpp index 359ce8ec..41c55a3d 100644 --- a/osal/host/MessageQueue.cpp +++ b/osal/host/MessageQueue.cpp @@ -64,9 +64,8 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { return MessageQueueIF::EMPTY; } MutexGuard mutexLock(queueLock, MutexIF::TimeoutType::WAITING, 20); - MessageQueueMessage* currentMessage = &messageQueue.front(); - std::copy(currentMessage->getBuffer(), - currentMessage->getBuffer() + messageSize, message->getBuffer()); + std::copy(messageQueue.front().data(), messageQueue.front().data() + messageSize, + message->getBuffer()); messageQueue.pop(); // The last partner is the first uint32_t field in the message this->lastPartner = message->getSender(); @@ -80,7 +79,7 @@ MessageQueueId_t MessageQueue::getLastPartner() const { ReturnValue_t MessageQueue::flush(uint32_t* count) { *count = messageQueue.size(); // Clears the queue. - messageQueue = std::queue(); + messageQueue = std::queue>(); return HasReturnvaluesIF::RETURN_OK; } @@ -132,20 +131,9 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, } if(targetQueue->messageQueue.size() < targetQueue->messageDepth) { MutexGuard mutexLock(targetQueue->queueLock, MutexIF::TimeoutType::WAITING, 20); - // TODO: Would be nice to support other message types, but this would require - // create the message on the heap from an upper layer and simply storing - // MessageQueueMessageIF pointers in the queue. - MessageQueueMessage* mqmMessage = dynamic_cast(message); - if(mqmMessage != nullptr) { - targetQueue->messageQueue.push(*mqmMessage); - } - else { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "MessageQueue::sendMessageFromMessageQueue: Message" - "is not MessageQueueMessage!" << std::endl; -#endif - } - + targetQueue->messageQueue.push(std::vector(message->getMaximumMessageSize())); + memcpy(targetQueue->messageQueue.back().data(), message->getBuffer(), + message->getMaximumMessageSize()); } else { return MessageQueueIF::FULL; diff --git a/osal/host/MessageQueue.h b/osal/host/MessageQueue.h index 97a9e491..e965123d 100644 --- a/osal/host/MessageQueue.h +++ b/osal/host/MessageQueue.h @@ -212,7 +212,7 @@ protected: //static ReturnValue_t handleSendResult(BaseType_t result, bool ignoreFault); private: - std::queue messageQueue; + std::queue> messageQueue; /** * @brief The class stores the queue id it got assigned. * If initialization fails, the queue id is set to zero. From c1f4ae08fb4e1c76592735b1dd0741fda14a772d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 8 Apr 2021 22:28:44 +0200 Subject: [PATCH 131/230] typo fix --- ipc/MessageQueueIF.h | 2 +- osal/FreeRTOS/MessageQueue.cpp | 2 +- osal/linux/MessageQueue.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ipc/MessageQueueIF.h b/ipc/MessageQueueIF.h index 1c06521c..74ccb29a 100644 --- a/ipc/MessageQueueIF.h +++ b/ipc/MessageQueueIF.h @@ -27,7 +27,7 @@ public: //! Returned if a reply method was called without partner static const ReturnValue_t NO_REPLY_PARTNER = MAKE_RETURN_CODE(3); //! Returned if the target destination is invalid. - static constexpr ReturnValue_t DESTINVATION_INVALID = MAKE_RETURN_CODE(4); + static constexpr ReturnValue_t DESTINATION_INVALID = MAKE_RETURN_CODE(4); virtual ~MessageQueueIF() {} /** diff --git a/osal/FreeRTOS/MessageQueue.cpp b/osal/FreeRTOS/MessageQueue.cpp index c0c82cf1..3a0f654e 100644 --- a/osal/FreeRTOS/MessageQueue.cpp +++ b/osal/FreeRTOS/MessageQueue.cpp @@ -135,7 +135,7 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, QueueHandle_t destination = nullptr; if(sendTo == MessageQueueIF::NO_QUEUE or sendTo == 0x00) { - return MessageQueueIF::DESTINVATION_INVALID; + return MessageQueueIF::DESTINATION_INVALID; } else { destination = reinterpret_cast(sendTo); diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index 8004c045..12774a58 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -373,7 +373,7 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, <<"mq_send to: " << sendTo << " sent from " << sentFrom << std::endl; #endif - return DESTINVATION_INVALID; + return DESTINATION_INVALID; } case EINTR: //The call was interrupted by a signal. From d92a20a669d5918422833aaf09b9934a59d8d789 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 8 Apr 2021 22:49:36 +0200 Subject: [PATCH 132/230] coverity --- datapool/HkSwitchHelper.cpp | 2 +- globalfunctions/arrayprinter.cpp | 4 ++-- osal/FreeRTOS/Clock.cpp | 2 +- pus/Service5EventReporting.cpp | 4 +++- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/datapool/HkSwitchHelper.cpp b/datapool/HkSwitchHelper.cpp index 1a2a25eb..21e37f59 100644 --- a/datapool/HkSwitchHelper.cpp +++ b/datapool/HkSwitchHelper.cpp @@ -7,7 +7,7 @@ HkSwitchHelper::HkSwitchHelper(EventReportingProxyIF* eventProxy) : } HkSwitchHelper::~HkSwitchHelper() { - // TODO Auto-generated destructor stub + QueueFactory::instance()->deleteMessageQueue(actionQueue); } ReturnValue_t HkSwitchHelper::initialize() { diff --git a/globalfunctions/arrayprinter.cpp b/globalfunctions/arrayprinter.cpp index 20a64f5b..0423360b 100644 --- a/globalfunctions/arrayprinter.cpp +++ b/globalfunctions/arrayprinter.cpp @@ -51,7 +51,7 @@ void arrayprinter::printHex(const uint8_t *data, size_t size, #else // General format: 0x01, 0x02, 0x03 so it is number of chars times 6 // plus line break plus small safety margin. - char printBuffer[(size + 1) * 7 + 1]; + char printBuffer[(size + 1) * 7 + 1] = {}; size_t currentPos = 0; for(size_t i = 0; i < size; i++) { // To avoid buffer overflows. @@ -94,7 +94,7 @@ void arrayprinter::printDec(const uint8_t *data, size_t size, #else // General format: 32, 243, -12 so it is number of chars times 5 // plus line break plus small safety margin. - char printBuffer[(size + 1) * 5 + 1]; + char printBuffer[(size + 1) * 5 + 1] = {}; size_t currentPos = 0; for(size_t i = 0; i < size; i++) { // To avoid buffer overflows. diff --git a/osal/FreeRTOS/Clock.cpp b/osal/FreeRTOS/Clock.cpp index 806edcc7..c15971fe 100644 --- a/osal/FreeRTOS/Clock.cpp +++ b/osal/FreeRTOS/Clock.cpp @@ -111,7 +111,7 @@ ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) { ReturnValue_t Clock::convertTimeOfDayToTimeval(const TimeOfDay_t* from, timeval* to) { - struct tm time_tm; + struct tm time_tm = {}; time_tm.tm_year = from->year - 1900; time_tm.tm_mon = from->month - 1; diff --git a/pus/Service5EventReporting.cpp b/pus/Service5EventReporting.cpp index 29eb7f20..965a27ad 100644 --- a/pus/Service5EventReporting.cpp +++ b/pus/Service5EventReporting.cpp @@ -15,7 +15,9 @@ Service5EventReporting::Service5EventReporting(object_id_t objectId, eventQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth); } -Service5EventReporting::~Service5EventReporting(){} +Service5EventReporting::~Service5EventReporting() { + QueueFactory::instance()->deleteMessageQueue(eventQueue); +} ReturnValue_t Service5EventReporting::performService() { EventMessage message; From 40cc3c383bca725d162638fa9885ec3f4d83f8fb Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 9 Apr 2021 00:45:04 +0200 Subject: [PATCH 133/230] this should work --- serialize/SerializeElement.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serialize/SerializeElement.h b/serialize/SerializeElement.h index ba34393d..db66f9cc 100644 --- a/serialize/SerializeElement.h +++ b/serialize/SerializeElement.h @@ -25,7 +25,7 @@ public: } SerializeElement() : - LinkedElement(this), entry(0) { + LinkedElement(this), entry() { } ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize, From d3c3a9147a875f34a4fe95358b5e41cecfa4093f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 9 Apr 2021 08:29:56 +0200 Subject: [PATCH 134/230] bumped version number --- FSFWVersion.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/FSFWVersion.h b/FSFWVersion.h index 11a60891..df2d49a5 100644 --- a/FSFWVersion.h +++ b/FSFWVersion.h @@ -3,9 +3,9 @@ const char* const FSFW_VERSION_NAME = "ASTP"; -#define FSFW_VERSION 0 -#define FSFW_SUBVERSION 0 -#define FSFW_REVISION 1 +#define FSFW_VERSION 1 +#define FSFW_SUBVERSION 0 +#define FSFW_REVISION 0 From b8c7a6570915df561df260ec6e83b03521b9114e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 9 Apr 2021 08:59:32 +0200 Subject: [PATCH 135/230] coverity fix --- datapoollocal/LocalDataPoolManager.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index 94ee9c26..dbe68ff1 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -909,27 +909,29 @@ void LocalDataPoolManager::printWarningOrError(sif::OutputTypes outputType, errorPrint = "Unknown error"; } } + object_id_t objectId = 0xffffffff; + if(owner != nullptr) { + objectId = owner->getObjectId(); + } if(outputType == sif::OutputTypes::OUT_WARNING) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "LocalDataPoolManager::" << functionName - << ": Object ID 0x" << std::setw(8) << std::setfill('0') - << std::hex << owner->getObjectId() << " | " << errorPrint - << std::dec << std::setfill(' ') << std::endl; + sif::warning << "LocalDataPoolManager::" << functionName << ": Object ID 0x" << + std::setw(8) << std::setfill('0') << std::hex << objectId << " | " << errorPrint << + std::dec << std::setfill(' ') << std::endl; #else sif::printWarning("LocalDataPoolManager::%s: Object ID 0x%08x | %s\n", - functionName, owner->getObjectId(), errorPrint); + functionName, objectId, errorPrint); #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ } else if(outputType == sif::OutputTypes::OUT_ERROR) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "LocalDataPoolManager::" << functionName - << ": Object ID 0x" << std::setw(8) << std::setfill('0') - << std::hex << owner->getObjectId() << " | " << errorPrint - << std::dec << std::setfill(' ') << std::endl; + sif::error << "LocalDataPoolManager::" << functionName << ": Object ID 0x" << + std::setw(8) << std::setfill('0') << std::hex << objectId << " | " << errorPrint << + std::dec << std::setfill(' ') << std::endl; #else sif::printError("LocalDataPoolManager::%s: Object ID 0x%08x | %s\n", - functionName, owner->getObjectId(), errorPrint); + functionName, objectId, errorPrint); #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ } #endif /* #if FSFW_VERBOSE_LEVEL >= 1 */ From d9a0a4f2ea75f62035287c3e75f2272b995d77b5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 9 Apr 2021 09:14:42 +0200 Subject: [PATCH 136/230] coverity --- pus/Service1TelecommandVerification.cpp | 4 +++- tmtcservices/TmTcBridge.cpp | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pus/Service1TelecommandVerification.cpp b/pus/Service1TelecommandVerification.cpp index 9e86c752..7ce75478 100644 --- a/pus/Service1TelecommandVerification.cpp +++ b/pus/Service1TelecommandVerification.cpp @@ -15,7 +15,9 @@ Service1TelecommandVerification::Service1TelecommandVerification( tmQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth); } -Service1TelecommandVerification::~Service1TelecommandVerification() {} +Service1TelecommandVerification::~Service1TelecommandVerification() { + QueueFactory::instance()->deleteMessageQueue(tmQueue); +} MessageQueueId_t Service1TelecommandVerification::getVerificationQueue(){ return tmQueue->getId(); diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index f99b9051..dcffac41 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -16,7 +16,9 @@ TmTcBridge::TmTcBridge(object_id_t objectId, object_id_t tcDestination, createMessageQueue(TMTC_RECEPTION_QUEUE_DEPTH); } -TmTcBridge::~TmTcBridge() {} +TmTcBridge::~TmTcBridge() { + QueueFactory::instance()->deleteMessageQueue(tmTcReceptionQueue); +} ReturnValue_t TmTcBridge::setNumberOfSentPacketsPerCycle( uint8_t sentPacketsPerCycle) { From e0d39b1feb04aafdb3fbe9e57a2f84ed9923300a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 9 Apr 2021 09:17:11 +0200 Subject: [PATCH 137/230] coverity --- pus/Service8FunctionManagement.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pus/Service8FunctionManagement.cpp b/pus/Service8FunctionManagement.cpp index a2202abc..54187a82 100644 --- a/pus/Service8FunctionManagement.cpp +++ b/pus/Service8FunctionManagement.cpp @@ -53,12 +53,14 @@ ReturnValue_t Service8FunctionManagement::checkInterfaceAndAcquireMessageQueue( ReturnValue_t Service8FunctionManagement::prepareCommand( CommandMessage* message, uint8_t subservice, const uint8_t* tcData, size_t tcDataLen, uint32_t* state, object_id_t objectId) { - return prepareDirectCommand(dynamic_cast(message), - tcData, tcDataLen); + return prepareDirectCommand(message, tcData, tcDataLen); } ReturnValue_t Service8FunctionManagement::prepareDirectCommand( CommandMessage *message, const uint8_t *tcData, size_t tcDataLen) { + if(message == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } if(tcDataLen < sizeof(object_id_t) + sizeof(ActionId_t)) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::debug << "Service8FunctionManagement::prepareDirectCommand:" From 6db0725aa4293cfafdf9cdea87d701a3892cd2eb Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 9 Apr 2021 15:39:48 +0200 Subject: [PATCH 138/230] coverity fix --- health/HealthTable.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/health/HealthTable.cpp b/health/HealthTable.cpp index 5d720b19..8b19d8e3 100644 --- a/health/HealthTable.cpp +++ b/health/HealthTable.cpp @@ -68,8 +68,18 @@ void HealthTable::printAll(uint8_t* pointer, size_t maxSize) { MutexGuard(mutex, timeoutType, mutexTimeoutMs); size_t size = 0; uint16_t count = healthMap.size(); - SerializeAdapter::serialize(&count, + ReturnValue_t result = SerializeAdapter::serialize(&count, &pointer, &size, maxSize, SerializeIF::Endianness::BIG); + if(result != HasReturnvaluesIF::RETURN_OK) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "HealthTable::printAll: Serialization of health table failed" << std::endl; +#else + sif::printWarning("HealthTable::printAll: Serialization of health table failed\n"); +#endif +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + return; + } for (const auto& health: healthMap) { SerializeAdapter::serialize(&health.first, &pointer, &size, maxSize, SerializeIF::Endianness::BIG); From 316310e99301790d9674d69e3c17e9ff782a34e9 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 9 Apr 2021 15:49:33 +0200 Subject: [PATCH 139/230] coverity --- devicehandlers/DeviceHandlerBase.cpp | 2 +- pus/CService200ModeCommanding.cpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 4a0b3582..8c8919ce 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -1515,7 +1515,7 @@ void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType, << std::setfill(' ') << std::endl; #else sif::printError("DeviceHandlerBase::%s: Object ID 0x%08x | %s\n", - this->getObjectId(), errorPrint); + functionName, this->getObjectId(), errorPrint); #endif } diff --git a/pus/CService200ModeCommanding.cpp b/pus/CService200ModeCommanding.cpp index c4e99359..70caadd1 100644 --- a/pus/CService200ModeCommanding.cpp +++ b/pus/CService200ModeCommanding.cpp @@ -61,8 +61,7 @@ ReturnValue_t CService200ModeCommanding::prepareCommand( return result; } - ModeMessage::setModeMessage(dynamic_cast(message), - ModeMessage::CMD_MODE_COMMAND, modeCommandPacket.getMode(), + ModeMessage::setModeMessage(message, ModeMessage::CMD_MODE_COMMAND, modeCommandPacket.getMode(), modeCommandPacket.getSubmode()); return result; } From 2e417c787d8fa38f9ff0bc9a73b44f900f796c75 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 9 Apr 2021 16:14:14 +0200 Subject: [PATCH 140/230] coverity --- devicehandlers/DeviceHandlerBase.cpp | 5 ++++- pus/Service20ParameterManagement.cpp | 5 ++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 8c8919ce..531a0642 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -1495,6 +1495,9 @@ void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType, errorPrint = "Unknown error"; } } + if(functionName == nullptr) { + functionName = "unknown function"; + } if(errorType == sif::OutputTypes::OUT_WARNING) { #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -1504,7 +1507,7 @@ void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType, << std::setfill(' ') << std::endl; #else sif::printWarning("DeviceHandlerBase::%s: Object ID 0x%08x | %s\n", - this->getObjectId(), errorPrint); + functionName, this->getObjectId(), errorPrint); #endif } else if(errorType == sif::OutputTypes::OUT_ERROR) { diff --git a/pus/Service20ParameterManagement.cpp b/pus/Service20ParameterManagement.cpp index bc3a9119..90e96650 100644 --- a/pus/Service20ParameterManagement.cpp +++ b/pus/Service20ParameterManagement.cpp @@ -75,9 +75,8 @@ ReturnValue_t Service20ParameterManagement::checkInterfaceAndAcquireMessageQueue #else sif::printError("Service20ParameterManagement::checkInterfaceAndAcquire" "MessageQueue: Can't access object\n"); - sif::printError("Object ID: 0x%08x\n", objectId); - sif::printError("Make sure it implements " - "ReceivesParameterMessagesIF!\n"); + sif::printError("Object ID: 0x%08x\n", *objectId); + sif::printError("Make sure it implements ReceivesParameterMessagesIF!\n"); #endif return CommandingServiceBase::INVALID_OBJECT; From 83e7dbb1f0ab91fa7068e628d66d70633afd5238 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 9 Apr 2021 16:17:21 +0200 Subject: [PATCH 141/230] Coveritx fixes --- pus/servicepackets/Service8Packets.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pus/servicepackets/Service8Packets.h b/pus/servicepackets/Service8Packets.h index b026edf5..a27cf8bb 100644 --- a/pus/servicepackets/Service8Packets.h +++ b/pus/servicepackets/Service8Packets.h @@ -43,8 +43,8 @@ public: private: DirectCommand(const DirectCommand &command); - object_id_t objectId; - ActionId_t actionId; + object_id_t objectId = 0; + ActionId_t actionId = 0; uint32_t parametersSize; //!< [EXPORT] : [IGNORE] const uint8_t * parameterBuffer; //!< [EXPORT] : [MAXSIZE] 65535 Bytes From f1ffa88e07718e14581e71e9e53f74f471a54946 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 10 Apr 2021 14:29:00 +0200 Subject: [PATCH 142/230] small bugfix --- osal/host/FixedTimeslotTask.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osal/host/FixedTimeslotTask.cpp b/osal/host/FixedTimeslotTask.cpp index 016b1404..89daa278 100644 --- a/osal/host/FixedTimeslotTask.cpp +++ b/osal/host/FixedTimeslotTask.cpp @@ -3,7 +3,7 @@ #include "../../ipc/MutexFactory.h" #include "../../osal/host/Mutex.h" #include "../../osal/host/FixedTimeslotTask.h" -#include "../../serviceinterface/ServiceInterfaceStream.h" +#include "../../serviceinterface/ServiceInterface.h" #include "../../tasks/ExecutableObjectIF.h" #include From 5144cbd789f2fe30cf02891d29301204dcdf7818 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 11 Apr 2021 02:26:11 +0200 Subject: [PATCH 143/230] additional inc path now in IF --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ff060d7b..8ba6a187 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -184,6 +184,7 @@ endif() target_include_directories(${LIB_FSFW_NAME} INTERFACE ${CMAKE_SOURCE_DIR} ${FSFW_CONFIG_PATH_ABSOLUTE} + ${FSFW_ADD_INC_PATHS_ABS} ) # Includes path required to compile FSFW itself as well From fbe860c6a51247104a84fdc9f94064810ca2e2f8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 11 Apr 2021 14:54:02 +0200 Subject: [PATCH 144/230] refactored addr print, using AI_PASSIVE now --- osal/common/UdpTcPollingTask.cpp | 9 +++++--- osal/common/UdpTmTcBridge.cpp | 21 ++++++++++--------- osal/common/tcpipCommon.cpp | 35 ++++++++++++++++++++++++++++++++ osal/common/tcpipCommon.h | 11 ++++++++-- 4 files changed, 61 insertions(+), 15 deletions(-) diff --git a/osal/common/UdpTcPollingTask.cpp b/osal/common/UdpTcPollingTask.cpp index 759cee05..47f67b29 100644 --- a/osal/common/UdpTcPollingTask.cpp +++ b/osal/common/UdpTcPollingTask.cpp @@ -15,7 +15,7 @@ #endif //! Debugging preprocessor define. -#define FSFW_UDP_RCV_WIRETAPPING_ENABLED 0 +#define FSFW_UDP_RECV_WIRETAPPING_ENABLED 0 UdpTcPollingTask::UdpTcPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge, size_t maxRecvSize, @@ -66,10 +66,13 @@ ReturnValue_t UdpTcPollingTask::performOperation(uint8_t opCode) { tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::RECVFROM_CALL, 1000); continue; } -#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1 +#if FSFW_UDP_RECV_WIRETAPPING_ENABLED == 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 sif::debug << "UdpTcPollingTask::performOperation: " << bytesReceived << " bytes received" << std::endl; +#else #endif +#endif /* FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1 */ ReturnValue_t result = handleSuccessfullTcRead(bytesReceived); if(result != HasReturnvaluesIF::RETURN_FAILED) { @@ -84,7 +87,7 @@ ReturnValue_t UdpTcPollingTask::performOperation(uint8_t opCode) { ReturnValue_t UdpTcPollingTask::handleSuccessfullTcRead(size_t bytesRead) { store_address_t storeId; -#if FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1 +#if FSFW_UDP_RECV_WIRETAPPING_ENABLED == 1 arrayprinter::print(receptionBuffer.data(), bytesRead); #endif diff --git a/osal/common/UdpTmTcBridge.cpp b/osal/common/UdpTmTcBridge.cpp index 798be6f5..ba23f521 100644 --- a/osal/common/UdpTmTcBridge.cpp +++ b/osal/common/UdpTmTcBridge.cpp @@ -70,6 +70,7 @@ ReturnValue_t UdpTmTcBridge::initialize() { 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://en.wikipedia.org/wiki/Getaddrinfo @@ -95,6 +96,10 @@ ReturnValue_t UdpTmTcBridge::initialize() { return HasReturnvaluesIF::RETURN_FAILED; } +#if FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1 + tcpip::printAddress(addrResult->ai_addr); +#endif + retval = bind(serverSocket, addrResult->ai_addr, static_cast(addrResult->ai_addrlen)); if(retval != 0) { #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -121,10 +126,8 @@ ReturnValue_t UdpTmTcBridge::sendTm(const uint8_t *data, size_t dataLen) { /* 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]; - sif::debug << "IP Address Sender: "<< inet_ntop(AF_INET, - &clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; +#if FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1 + tcpip::printAddress(&clientAddress); #endif int bytesSent = sendto( @@ -152,13 +155,11 @@ 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); -#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_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; +#if FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1 + tcpip::printAddress(&newAddress); + tcpip::printAddress(&clientAddress); #endif + registerCommConnect(); /* Set new IP address to reply to */ diff --git a/osal/common/tcpipCommon.cpp b/osal/common/tcpipCommon.cpp index 9a5e4647..ab4eda29 100644 --- a/osal/common/tcpipCommon.cpp +++ b/osal/common/tcpipCommon.cpp @@ -1,4 +1,5 @@ #include "tcpipCommon.h" +#include void tcpip::determineErrorStrings(Protocol protocol, ErrorSources errorSrc, std::string &protStr, std::string &srcString) { @@ -34,3 +35,37 @@ void tcpip::determineErrorStrings(Protocol protocol, ErrorSources errorSrc, std: srcString = "unknown call"; } } + +void tcpip::printAddress(struct sockaddr* addr) { + char ipAddress[INET6_ADDRSTRLEN] = {}; + const char* stringPtr = NULL; + switch(addr->sa_family) { + case AF_INET: { + struct sockaddr_in *addrIn = reinterpret_cast(addr); + stringPtr = inet_ntop(AF_INET, &(addrIn->sin_addr), ipAddress, INET_ADDRSTRLEN); + break; + } + case AF_INET6: { + struct sockaddr_in6 *addrIn = reinterpret_cast(addr); + stringPtr = inet_ntop(AF_INET6, &(addrIn->sin6_addr), ipAddress, INET6_ADDRSTRLEN); + break; + } + } +#if FSFW_CPP_OSTREAM_ENABLED == 1 + if(stringPtr == NULL) { + sif::debug << "Could not convert IP address to text representation, error code " + << errno << std::endl; + } + else { + sif::debug << "IP Address Sender: " << ipAddress << std::endl; + } +#else + if(stringPtr == NULL) { + sif::printDebug("Could not convert IP address to text representation, error code %d\n", + errno); + } + else { + sif::printDebug("IP Address Sender: %s\n", ipAddress); + } +#endif +} diff --git a/osal/common/tcpipCommon.h b/osal/common/tcpipCommon.h index dc5ada52..22b914dc 100644 --- a/osal/common/tcpipCommon.h +++ b/osal/common/tcpipCommon.h @@ -4,6 +4,13 @@ #include "../../timemanager/clockDefinitions.h" #include +#ifdef _WIN32 +#include +#else +#include +#include +#endif + namespace tcpip { const char* const DEFAULT_SERVER_PORT = "7301"; @@ -28,8 +35,8 @@ enum class ErrorSources { void determineErrorStrings(Protocol protocol, ErrorSources errorSrc, std::string& protStr, std::string& srcString); +void printAddress(struct sockaddr* addr); + } - - #endif /* FSFW_OSAL_COMMON_TCPIPCOMMON_H_ */ From 924ea420a9f72d188000dc73bfe2500635e2ddad Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 11 Apr 2021 14:58:53 +0200 Subject: [PATCH 145/230] missing include for windows --- osal/common/tcpipCommon.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osal/common/tcpipCommon.cpp b/osal/common/tcpipCommon.cpp index ab4eda29..551e2a42 100644 --- a/osal/common/tcpipCommon.cpp +++ b/osal/common/tcpipCommon.cpp @@ -1,6 +1,10 @@ #include "tcpipCommon.h" #include +#ifdef _WIN32 +#include +#endif + void tcpip::determineErrorStrings(Protocol protocol, ErrorSources errorSrc, std::string &protStr, std::string &srcString) { if(protocol == Protocol::TCP) { From 6e6fb62b3cb66561b76fc86b320e05d5559c2be9 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 11 Apr 2021 18:36:24 +0200 Subject: [PATCH 146/230] last coverity fixes --- devicehandlers/HealthDevice.cpp | 4 ++-- health/HealthTable.cpp | 2 +- timemanager/TimeMessage.cpp | 2 +- timemanager/TimeMessage.h | 2 +- tmtcservices/TmTcMessage.cpp | 2 +- tmtcservices/TmTcMessage.h | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/devicehandlers/HealthDevice.cpp b/devicehandlers/HealthDevice.cpp index 418ed257..e23dd5b6 100644 --- a/devicehandlers/HealthDevice.cpp +++ b/devicehandlers/HealthDevice.cpp @@ -16,9 +16,9 @@ ReturnValue_t HealthDevice::performOperation(uint8_t opCode) { CommandMessage command; ReturnValue_t result = commandQueue->receiveMessage(&command); if (result == HasReturnvaluesIF::RETURN_OK) { - healthHelper.handleHealthCommand(&command); + result = healthHelper.handleHealthCommand(&command); } - return HasReturnvaluesIF::RETURN_OK; + return result; } ReturnValue_t HealthDevice::initialize() { diff --git a/health/HealthTable.cpp b/health/HealthTable.cpp index 8b19d8e3..5717fe9f 100644 --- a/health/HealthTable.cpp +++ b/health/HealthTable.cpp @@ -96,7 +96,7 @@ ReturnValue_t HealthTable::iterate(HealthEntry *value, bool reset) { mapIterator = healthMap.begin(); } if (mapIterator == healthMap.end()) { - result = HasReturnvaluesIF::RETURN_FAILED; + return HasReturnvaluesIF::RETURN_FAILED; } *value = *mapIterator; mapIterator++; diff --git a/timemanager/TimeMessage.cpp b/timemanager/TimeMessage.cpp index a1042efe..66aea0f4 100644 --- a/timemanager/TimeMessage.cpp +++ b/timemanager/TimeMessage.cpp @@ -25,6 +25,6 @@ uint32_t TimeMessage::getCounterValue() { return temp; } -size_t TimeMessage::getMinimumMessageSize() { +size_t TimeMessage::getMinimumMessageSize() const { return this->MAX_SIZE; } diff --git a/timemanager/TimeMessage.h b/timemanager/TimeMessage.h index f5ac3e14..00778fb7 100644 --- a/timemanager/TimeMessage.h +++ b/timemanager/TimeMessage.h @@ -11,7 +11,7 @@ protected: * @brief This call always returns the same fixed size of the message. * @return Returns HEADER_SIZE + \c sizeof(timeval) + sizeof(uint32_t). */ - size_t getMinimumMessageSize(); + size_t getMinimumMessageSize() const override; public: /** diff --git a/tmtcservices/TmTcMessage.cpp b/tmtcservices/TmTcMessage.cpp index ae028315..c0f32aaa 100644 --- a/tmtcservices/TmTcMessage.cpp +++ b/tmtcservices/TmTcMessage.cpp @@ -21,7 +21,7 @@ TmTcMessage::TmTcMessage(store_address_t storeId) { this->setStorageId(storeId); } -size_t TmTcMessage::getMinimumMessageSize() { +size_t TmTcMessage::getMinimumMessageSize() const { return this->HEADER_SIZE + sizeof(store_address_t); } diff --git a/tmtcservices/TmTcMessage.h b/tmtcservices/TmTcMessage.h index 41fe198a..7d2a7bdb 100644 --- a/tmtcservices/TmTcMessage.h +++ b/tmtcservices/TmTcMessage.h @@ -18,7 +18,7 @@ protected: * @brief This call always returns the same fixed size of the message. * @return Returns HEADER_SIZE + @c sizeof(store_address_t). */ - size_t getMinimumMessageSize(); + size_t getMinimumMessageSize() const override; public: /** * @brief In the default constructor, only the message_size is set. From 438049bb803eb1ecb770bdd8ad941538ec7f179a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 11 Apr 2021 18:50:48 +0200 Subject: [PATCH 147/230] another coverity fix --- thermal/Heater.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/thermal/Heater.cpp b/thermal/Heater.cpp index 782ce296..d148c871 100644 --- a/thermal/Heater.cpp +++ b/thermal/Heater.cpp @@ -286,7 +286,10 @@ void Heater::handleQueue() { if (result == HasReturnvaluesIF::RETURN_OK) { return; } - parameterHelper.handleParameterMessage(&command); + result = parameterHelper.handleParameterMessage(&command); + if (result == HasReturnvaluesIF::RETURN_OK) { + return; + } } } From 5d93cf12f771506d75a99df015f4d892d84765c5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 11 Apr 2021 18:55:10 +0200 Subject: [PATCH 148/230] another coverity fix --- health/HealthTable.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/health/HealthTable.cpp b/health/HealthTable.cpp index 5717fe9f..3fed1deb 100644 --- a/health/HealthTable.cpp +++ b/health/HealthTable.cpp @@ -81,11 +81,17 @@ void HealthTable::printAll(uint8_t* pointer, size_t maxSize) { return; } for (const auto& health: healthMap) { - SerializeAdapter::serialize(&health.first, + result = SerializeAdapter::serialize(&health.first, &pointer, &size, maxSize, SerializeIF::Endianness::BIG); + if(result != HasReturnvaluesIF::RETURN_OK) { + return; + } uint8_t healthValue = health.second; - SerializeAdapter::serialize(&healthValue, &pointer, &size, + result = SerializeAdapter::serialize(&healthValue, &pointer, &size, maxSize, SerializeIF::Endianness::BIG); + if(result != HasReturnvaluesIF::RETURN_OK) { + return; + } } } From 5676969fe368187507d7a3bf90b153719931fdf3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 11 Apr 2021 21:13:43 +0200 Subject: [PATCH 149/230] typo fix --- ipc/MessageQueueIF.h | 2 +- osal/FreeRTOS/MessageQueue.cpp | 2 +- osal/linux/MessageQueue.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ipc/MessageQueueIF.h b/ipc/MessageQueueIF.h index 1c06521c..74ccb29a 100644 --- a/ipc/MessageQueueIF.h +++ b/ipc/MessageQueueIF.h @@ -27,7 +27,7 @@ public: //! Returned if a reply method was called without partner static const ReturnValue_t NO_REPLY_PARTNER = MAKE_RETURN_CODE(3); //! Returned if the target destination is invalid. - static constexpr ReturnValue_t DESTINVATION_INVALID = MAKE_RETURN_CODE(4); + static constexpr ReturnValue_t DESTINATION_INVALID = MAKE_RETURN_CODE(4); virtual ~MessageQueueIF() {} /** diff --git a/osal/FreeRTOS/MessageQueue.cpp b/osal/FreeRTOS/MessageQueue.cpp index c0c82cf1..3a0f654e 100644 --- a/osal/FreeRTOS/MessageQueue.cpp +++ b/osal/FreeRTOS/MessageQueue.cpp @@ -135,7 +135,7 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, QueueHandle_t destination = nullptr; if(sendTo == MessageQueueIF::NO_QUEUE or sendTo == 0x00) { - return MessageQueueIF::DESTINVATION_INVALID; + return MessageQueueIF::DESTINATION_INVALID; } else { destination = reinterpret_cast(sendTo); diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index 8004c045..12774a58 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -373,7 +373,7 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, <<"mq_send to: " << sendTo << " sent from " << sentFrom << std::endl; #endif - return DESTINVATION_INVALID; + return DESTINATION_INVALID; } case EINTR: //The call was interrupted by a signal. From 01d0bd6c64c68d3a351573203945a35044e341f8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 11 Apr 2021 21:20:45 +0200 Subject: [PATCH 150/230] Small patch for CMakeLists file This adds the additional includes to the interface as well so libraries linking again fsfw get the additional includes as well. --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ff060d7b..8ba6a187 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -184,6 +184,7 @@ endif() target_include_directories(${LIB_FSFW_NAME} INTERFACE ${CMAKE_SOURCE_DIR} ${FSFW_CONFIG_PATH_ABSOLUTE} + ${FSFW_ADD_INC_PATHS_ABS} ) # Includes path required to compile FSFW itself as well From e50d0738ab08f75f7284a5788b8d3174d1e2dac7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 11 Apr 2021 21:22:58 +0200 Subject: [PATCH 151/230] bumped version to 1.0.0 --- FSFWVersion.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/FSFWVersion.h b/FSFWVersion.h index 11a60891..df2d49a5 100644 --- a/FSFWVersion.h +++ b/FSFWVersion.h @@ -3,9 +3,9 @@ const char* const FSFW_VERSION_NAME = "ASTP"; -#define FSFW_VERSION 0 -#define FSFW_SUBVERSION 0 -#define FSFW_REVISION 1 +#define FSFW_VERSION 1 +#define FSFW_SUBVERSION 0 +#define FSFW_REVISION 0 From b786b53c35dc64fe0743aec68cb8ef9bcfe2fcfb Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 11 Apr 2021 21:54:48 +0200 Subject: [PATCH 152/230] added all coverity fixes --- action/ActionHelper.cpp | 5 ----- container/SharedRingBuffer.cpp | 3 +++ container/SharedRingBuffer.h | 23 +++++++++++++---------- datapool/HkSwitchHelper.cpp | 2 +- datapoollocal/LocalDataPoolManager.cpp | 22 ++++++++++++---------- devicehandlers/DeviceHandlerBase.cpp | 9 ++++++--- events/EventMessage.cpp | 2 +- events/EventMessage.h | 2 +- globalfunctions/arrayprinter.cpp | 4 ++-- health/HealthTable.cpp | 24 ++++++++++++++++++++---- osal/FreeRTOS/Clock.cpp | 2 +- osal/common/TcpTmTcServer.cpp | 7 +++++-- osal/host/FixedTimeslotTask.cpp | 10 ++++++---- osal/host/PeriodicTask.cpp | 1 - osal/host/QueueMapManager.cpp | 4 ++++ osal/host/QueueMapManager.h | 2 ++ pus/CService200ModeCommanding.cpp | 3 +-- pus/Service1TelecommandVerification.cpp | 4 +++- pus/Service20ParameterManagement.cpp | 5 ++--- pus/Service5EventReporting.cpp | 4 +++- pus/Service8FunctionManagement.cpp | 6 ++++-- pus/servicepackets/Service8Packets.h | 4 ++-- tmtcservices/TmTcBridge.cpp | 4 +++- 23 files changed, 95 insertions(+), 57 deletions(-) diff --git a/action/ActionHelper.cpp b/action/ActionHelper.cpp index 4b64a40c..b2374ed6 100644 --- a/action/ActionHelper.cpp +++ b/action/ActionHelper.cpp @@ -147,11 +147,6 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, return result; } - if (result != HasReturnvaluesIF::RETURN_OK) { - ipcStore->deleteData(storeAddress); - return result; - } - /* We don't need to report the objectId, as we receive REQUESTED data before the completion success message. True aperiodic replies need to be reported with another dedicated message. */ ActionMessage::setDataReply(&reply, replyId, storeAddress); diff --git a/container/SharedRingBuffer.cpp b/container/SharedRingBuffer.cpp index 5e20bb6f..fe36341d 100644 --- a/container/SharedRingBuffer.cpp +++ b/container/SharedRingBuffer.cpp @@ -17,6 +17,9 @@ SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t *buffer, mutex = MutexFactory::instance()->createMutex(); } +SharedRingBuffer::~SharedRingBuffer() { + MutexFactory::instance()->deleteMutex(mutex); +} void SharedRingBuffer::setToUseReceiveSizeFIFO(size_t fifoDepth) { this->fifoDepth = fifoDepth; diff --git a/container/SharedRingBuffer.h b/container/SharedRingBuffer.h index 66a119ab..9d6ea56c 100644 --- a/container/SharedRingBuffer.h +++ b/container/SharedRingBuffer.h @@ -26,6 +26,18 @@ public: */ SharedRingBuffer(object_id_t objectId, const size_t size, bool overwriteOld, size_t maxExcessBytes); + /** + * This constructor takes an external buffer with the specified size. + * @param buffer + * @param size + * @param overwriteOld + * If the ring buffer is overflowing at a write operartion, the oldest data + * will be overwritten. + */ + SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const size_t size, + bool overwriteOld, size_t maxExcessBytes); + + virtual~ SharedRingBuffer(); /** * @brief This function can be used to add an optional FIFO to the class @@ -37,16 +49,7 @@ public: */ void setToUseReceiveSizeFIFO(size_t fifoDepth); - /** - * This constructor takes an external buffer with the specified size. - * @param buffer - * @param size - * @param overwriteOld - * If the ring buffer is overflowing at a write operartion, the oldest data - * will be overwritten. - */ - SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const size_t size, - bool overwriteOld, size_t maxExcessBytes); + /** * Unless a read-only constant value is read, all operations on the diff --git a/datapool/HkSwitchHelper.cpp b/datapool/HkSwitchHelper.cpp index 1a2a25eb..21e37f59 100644 --- a/datapool/HkSwitchHelper.cpp +++ b/datapool/HkSwitchHelper.cpp @@ -7,7 +7,7 @@ HkSwitchHelper::HkSwitchHelper(EventReportingProxyIF* eventProxy) : } HkSwitchHelper::~HkSwitchHelper() { - // TODO Auto-generated destructor stub + QueueFactory::instance()->deleteMessageQueue(actionQueue); } ReturnValue_t HkSwitchHelper::initialize() { diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index 94ee9c26..dbe68ff1 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -909,27 +909,29 @@ void LocalDataPoolManager::printWarningOrError(sif::OutputTypes outputType, errorPrint = "Unknown error"; } } + object_id_t objectId = 0xffffffff; + if(owner != nullptr) { + objectId = owner->getObjectId(); + } if(outputType == sif::OutputTypes::OUT_WARNING) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "LocalDataPoolManager::" << functionName - << ": Object ID 0x" << std::setw(8) << std::setfill('0') - << std::hex << owner->getObjectId() << " | " << errorPrint - << std::dec << std::setfill(' ') << std::endl; + sif::warning << "LocalDataPoolManager::" << functionName << ": Object ID 0x" << + std::setw(8) << std::setfill('0') << std::hex << objectId << " | " << errorPrint << + std::dec << std::setfill(' ') << std::endl; #else sif::printWarning("LocalDataPoolManager::%s: Object ID 0x%08x | %s\n", - functionName, owner->getObjectId(), errorPrint); + functionName, objectId, errorPrint); #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ } else if(outputType == sif::OutputTypes::OUT_ERROR) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "LocalDataPoolManager::" << functionName - << ": Object ID 0x" << std::setw(8) << std::setfill('0') - << std::hex << owner->getObjectId() << " | " << errorPrint - << std::dec << std::setfill(' ') << std::endl; + sif::error << "LocalDataPoolManager::" << functionName << ": Object ID 0x" << + std::setw(8) << std::setfill('0') << std::hex << objectId << " | " << errorPrint << + std::dec << std::setfill(' ') << std::endl; #else sif::printError("LocalDataPoolManager::%s: Object ID 0x%08x | %s\n", - functionName, owner->getObjectId(), errorPrint); + functionName, objectId, errorPrint); #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ } #endif /* #if FSFW_VERBOSE_LEVEL >= 1 */ diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 15eac11f..531a0642 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -1483,7 +1483,7 @@ void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType, if(errorCode == ObjectManagerIF::CHILD_INIT_FAILED) { errorPrint = "Initialization error"; } - if(errorCode == HasReturnvaluesIF::RETURN_FAILED) { + else if(errorCode == HasReturnvaluesIF::RETURN_FAILED) { if(errorType == sif::OutputTypes::OUT_WARNING) { errorPrint = "Generic Warning"; } @@ -1495,6 +1495,9 @@ void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType, errorPrint = "Unknown error"; } } + if(functionName == nullptr) { + functionName = "unknown function"; + } if(errorType == sif::OutputTypes::OUT_WARNING) { #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -1504,7 +1507,7 @@ void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType, << std::setfill(' ') << std::endl; #else sif::printWarning("DeviceHandlerBase::%s: Object ID 0x%08x | %s\n", - this->getObjectId(), errorPrint); + functionName, this->getObjectId(), errorPrint); #endif } else if(errorType == sif::OutputTypes::OUT_ERROR) { @@ -1515,7 +1518,7 @@ void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType, << std::setfill(' ') << std::endl; #else sif::printError("DeviceHandlerBase::%s: Object ID 0x%08x | %s\n", - this->getObjectId(), errorPrint); + functionName, this->getObjectId(), errorPrint); #endif } diff --git a/events/EventMessage.cpp b/events/EventMessage.cpp index bbc41e10..548b4f0f 100644 --- a/events/EventMessage.cpp +++ b/events/EventMessage.cpp @@ -109,6 +109,6 @@ bool EventMessage::isClearedEventMessage() { return getEvent() == INVALID_EVENT; } -size_t EventMessage::getMinimumMessageSize() { +size_t EventMessage::getMinimumMessageSize() const { return EVENT_MESSAGE_SIZE; } diff --git a/events/EventMessage.h b/events/EventMessage.h index 4d003bd7..f2f5ffb5 100644 --- a/events/EventMessage.h +++ b/events/EventMessage.h @@ -45,7 +45,7 @@ public: protected: static const Event INVALID_EVENT = 0; - virtual size_t getMinimumMessageSize(); + virtual size_t getMinimumMessageSize() const override; }; diff --git a/globalfunctions/arrayprinter.cpp b/globalfunctions/arrayprinter.cpp index 20a64f5b..0423360b 100644 --- a/globalfunctions/arrayprinter.cpp +++ b/globalfunctions/arrayprinter.cpp @@ -51,7 +51,7 @@ void arrayprinter::printHex(const uint8_t *data, size_t size, #else // General format: 0x01, 0x02, 0x03 so it is number of chars times 6 // plus line break plus small safety margin. - char printBuffer[(size + 1) * 7 + 1]; + char printBuffer[(size + 1) * 7 + 1] = {}; size_t currentPos = 0; for(size_t i = 0; i < size; i++) { // To avoid buffer overflows. @@ -94,7 +94,7 @@ void arrayprinter::printDec(const uint8_t *data, size_t size, #else // General format: 32, 243, -12 so it is number of chars times 5 // plus line break plus small safety margin. - char printBuffer[(size + 1) * 5 + 1]; + char printBuffer[(size + 1) * 5 + 1] = {}; size_t currentPos = 0; for(size_t i = 0; i < size; i++) { // To avoid buffer overflows. diff --git a/health/HealthTable.cpp b/health/HealthTable.cpp index 5d720b19..3fed1deb 100644 --- a/health/HealthTable.cpp +++ b/health/HealthTable.cpp @@ -68,14 +68,30 @@ void HealthTable::printAll(uint8_t* pointer, size_t maxSize) { MutexGuard(mutex, timeoutType, mutexTimeoutMs); size_t size = 0; uint16_t count = healthMap.size(); - SerializeAdapter::serialize(&count, + ReturnValue_t result = SerializeAdapter::serialize(&count, &pointer, &size, maxSize, SerializeIF::Endianness::BIG); + if(result != HasReturnvaluesIF::RETURN_OK) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "HealthTable::printAll: Serialization of health table failed" << std::endl; +#else + sif::printWarning("HealthTable::printAll: Serialization of health table failed\n"); +#endif +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + return; + } for (const auto& health: healthMap) { - SerializeAdapter::serialize(&health.first, + result = SerializeAdapter::serialize(&health.first, &pointer, &size, maxSize, SerializeIF::Endianness::BIG); + if(result != HasReturnvaluesIF::RETURN_OK) { + return; + } uint8_t healthValue = health.second; - SerializeAdapter::serialize(&healthValue, &pointer, &size, + result = SerializeAdapter::serialize(&healthValue, &pointer, &size, maxSize, SerializeIF::Endianness::BIG); + if(result != HasReturnvaluesIF::RETURN_OK) { + return; + } } } @@ -86,7 +102,7 @@ ReturnValue_t HealthTable::iterate(HealthEntry *value, bool reset) { mapIterator = healthMap.begin(); } if (mapIterator == healthMap.end()) { - result = HasReturnvaluesIF::RETURN_FAILED; + return HasReturnvaluesIF::RETURN_FAILED; } *value = *mapIterator; mapIterator++; diff --git a/osal/FreeRTOS/Clock.cpp b/osal/FreeRTOS/Clock.cpp index 806edcc7..c15971fe 100644 --- a/osal/FreeRTOS/Clock.cpp +++ b/osal/FreeRTOS/Clock.cpp @@ -111,7 +111,7 @@ ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) { ReturnValue_t Clock::convertTimeOfDayToTimeval(const TimeOfDay_t* from, timeval* to) { - struct tm time_tm; + struct tm time_tm = {}; time_tm.tm_year = from->year - 1900; time_tm.tm_mon = from->month - 1; diff --git a/osal/common/TcpTmTcServer.cpp b/osal/common/TcpTmTcServer.cpp index 296afad8..08a62ffb 100644 --- a/osal/common/TcpTmTcServer.cpp +++ b/osal/common/TcpTmTcServer.cpp @@ -70,6 +70,7 @@ ReturnValue_t TcpTmTcServer::initialize() { #endif freeaddrinfo(addrResult); handleError(Protocol::TCP, ErrorSources::BIND_CALL); + return HasReturnvaluesIF::RETURN_FAILED; } freeaddrinfo(addrResult); @@ -84,8 +85,8 @@ TcpTmTcServer::~TcpTmTcServer() { 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_t clientSocket; - sockaddr clientSockAddr; + socket_t clientSocket = 0; + sockaddr clientSockAddr = {}; socklen_t connectorSockAddrLen = 0; int retval = 0; @@ -101,6 +102,7 @@ ReturnValue_t TcpTmTcServer::performOperation(uint8_t opCode) { if(clientSocket == INVALID_SOCKET) { handleError(Protocol::TCP, ErrorSources::ACCEPT_CALL, 500); + closeSocket(clientSocket); continue; }; @@ -122,6 +124,7 @@ ReturnValue_t TcpTmTcServer::performOperation(uint8_t opCode) { /* Done, shut down connection */ retval = shutdown(clientSocket, SHUT_SEND); + closeSocket(clientSocket); } return HasReturnvaluesIF::RETURN_OK; } diff --git a/osal/host/FixedTimeslotTask.cpp b/osal/host/FixedTimeslotTask.cpp index 3b169b5a..89daa278 100644 --- a/osal/host/FixedTimeslotTask.cpp +++ b/osal/host/FixedTimeslotTask.cpp @@ -3,7 +3,7 @@ #include "../../ipc/MutexFactory.h" #include "../../osal/host/Mutex.h" #include "../../osal/host/FixedTimeslotTask.h" -#include "../../serviceinterface/ServiceInterfaceStream.h" +#include "../../serviceinterface/ServiceInterface.h" #include "../../tasks/ExecutableObjectIF.h" #include @@ -38,7 +38,6 @@ FixedTimeslotTask::~FixedTimeslotTask(void) { if(mainThread.joinable()) { mainThread.join(); } - delete this; } void FixedTimeslotTask::taskEntryPoint(void* argument) { @@ -119,8 +118,11 @@ ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, } #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "Component " << std::hex << componentId << - " not found, not adding it to pst" << std::endl; + sif::error << "Component " << std::hex << "0x" << componentId << "not found, " + "not adding it to PST.." << std::dec << std::endl; +#else + sif::printError("Component 0x%08x not found, not adding it to PST..\n", + static_cast(componentId)); #endif return HasReturnvaluesIF::RETURN_FAILED; } diff --git a/osal/host/PeriodicTask.cpp b/osal/host/PeriodicTask.cpp index d7abf9d0..631264b7 100644 --- a/osal/host/PeriodicTask.cpp +++ b/osal/host/PeriodicTask.cpp @@ -38,7 +38,6 @@ PeriodicTask::~PeriodicTask(void) { if(mainThread.joinable()) { mainThread.join(); } - delete this; } void PeriodicTask::taskEntryPoint(void* argument) { diff --git a/osal/host/QueueMapManager.cpp b/osal/host/QueueMapManager.cpp index b50d62dc..c9100fe9 100644 --- a/osal/host/QueueMapManager.cpp +++ b/osal/host/QueueMapManager.cpp @@ -10,6 +10,10 @@ QueueMapManager::QueueMapManager() { mapLock = MutexFactory::instance()->createMutex(); } +QueueMapManager::~QueueMapManager() { + MutexFactory::instance()->deleteMutex(mapLock); +} + QueueMapManager* QueueMapManager::instance() { if (mqManagerInstance == nullptr){ mqManagerInstance = new QueueMapManager(); diff --git a/osal/host/QueueMapManager.h b/osal/host/QueueMapManager.h index 3610ca63..90c39c2f 100644 --- a/osal/host/QueueMapManager.h +++ b/osal/host/QueueMapManager.h @@ -36,6 +36,8 @@ public: private: //! External instantiation is forbidden. QueueMapManager(); + ~QueueMapManager(); + uint32_t queueCounter = 0; MutexIF* mapLock; QueueMap queueMap; diff --git a/pus/CService200ModeCommanding.cpp b/pus/CService200ModeCommanding.cpp index c4e99359..70caadd1 100644 --- a/pus/CService200ModeCommanding.cpp +++ b/pus/CService200ModeCommanding.cpp @@ -61,8 +61,7 @@ ReturnValue_t CService200ModeCommanding::prepareCommand( return result; } - ModeMessage::setModeMessage(dynamic_cast(message), - ModeMessage::CMD_MODE_COMMAND, modeCommandPacket.getMode(), + ModeMessage::setModeMessage(message, ModeMessage::CMD_MODE_COMMAND, modeCommandPacket.getMode(), modeCommandPacket.getSubmode()); return result; } diff --git a/pus/Service1TelecommandVerification.cpp b/pus/Service1TelecommandVerification.cpp index 9e86c752..7ce75478 100644 --- a/pus/Service1TelecommandVerification.cpp +++ b/pus/Service1TelecommandVerification.cpp @@ -15,7 +15,9 @@ Service1TelecommandVerification::Service1TelecommandVerification( tmQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth); } -Service1TelecommandVerification::~Service1TelecommandVerification() {} +Service1TelecommandVerification::~Service1TelecommandVerification() { + QueueFactory::instance()->deleteMessageQueue(tmQueue); +} MessageQueueId_t Service1TelecommandVerification::getVerificationQueue(){ return tmQueue->getId(); diff --git a/pus/Service20ParameterManagement.cpp b/pus/Service20ParameterManagement.cpp index bc3a9119..90e96650 100644 --- a/pus/Service20ParameterManagement.cpp +++ b/pus/Service20ParameterManagement.cpp @@ -75,9 +75,8 @@ ReturnValue_t Service20ParameterManagement::checkInterfaceAndAcquireMessageQueue #else sif::printError("Service20ParameterManagement::checkInterfaceAndAcquire" "MessageQueue: Can't access object\n"); - sif::printError("Object ID: 0x%08x\n", objectId); - sif::printError("Make sure it implements " - "ReceivesParameterMessagesIF!\n"); + sif::printError("Object ID: 0x%08x\n", *objectId); + sif::printError("Make sure it implements ReceivesParameterMessagesIF!\n"); #endif return CommandingServiceBase::INVALID_OBJECT; diff --git a/pus/Service5EventReporting.cpp b/pus/Service5EventReporting.cpp index 29eb7f20..965a27ad 100644 --- a/pus/Service5EventReporting.cpp +++ b/pus/Service5EventReporting.cpp @@ -15,7 +15,9 @@ Service5EventReporting::Service5EventReporting(object_id_t objectId, eventQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth); } -Service5EventReporting::~Service5EventReporting(){} +Service5EventReporting::~Service5EventReporting() { + QueueFactory::instance()->deleteMessageQueue(eventQueue); +} ReturnValue_t Service5EventReporting::performService() { EventMessage message; diff --git a/pus/Service8FunctionManagement.cpp b/pus/Service8FunctionManagement.cpp index a2202abc..54187a82 100644 --- a/pus/Service8FunctionManagement.cpp +++ b/pus/Service8FunctionManagement.cpp @@ -53,12 +53,14 @@ ReturnValue_t Service8FunctionManagement::checkInterfaceAndAcquireMessageQueue( ReturnValue_t Service8FunctionManagement::prepareCommand( CommandMessage* message, uint8_t subservice, const uint8_t* tcData, size_t tcDataLen, uint32_t* state, object_id_t objectId) { - return prepareDirectCommand(dynamic_cast(message), - tcData, tcDataLen); + return prepareDirectCommand(message, tcData, tcDataLen); } ReturnValue_t Service8FunctionManagement::prepareDirectCommand( CommandMessage *message, const uint8_t *tcData, size_t tcDataLen) { + if(message == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } if(tcDataLen < sizeof(object_id_t) + sizeof(ActionId_t)) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::debug << "Service8FunctionManagement::prepareDirectCommand:" diff --git a/pus/servicepackets/Service8Packets.h b/pus/servicepackets/Service8Packets.h index b026edf5..a27cf8bb 100644 --- a/pus/servicepackets/Service8Packets.h +++ b/pus/servicepackets/Service8Packets.h @@ -43,8 +43,8 @@ public: private: DirectCommand(const DirectCommand &command); - object_id_t objectId; - ActionId_t actionId; + object_id_t objectId = 0; + ActionId_t actionId = 0; uint32_t parametersSize; //!< [EXPORT] : [IGNORE] const uint8_t * parameterBuffer; //!< [EXPORT] : [MAXSIZE] 65535 Bytes diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index f99b9051..dcffac41 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -16,7 +16,9 @@ TmTcBridge::TmTcBridge(object_id_t objectId, object_id_t tcDestination, createMessageQueue(TMTC_RECEPTION_QUEUE_DEPTH); } -TmTcBridge::~TmTcBridge() {} +TmTcBridge::~TmTcBridge() { + QueueFactory::instance()->deleteMessageQueue(tmTcReceptionQueue); +} ReturnValue_t TmTcBridge::setNumberOfSentPacketsPerCycle( uint8_t sentPacketsPerCycle) { From 06d34efa749dab1e3b76b47a0fa28d7f52cfd0fb Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 12 Apr 2021 12:33:45 +0200 Subject: [PATCH 153/230] UDP and TCPIP smaller tweaks Using AI_PASSIVE now so the UDP server listens to all addresses (0.0.0.0) instead of just localhost. Also implemented address print function properly --- osal/common/TcpTmTcServer.cpp | 7 ++++-- osal/common/UdpTcPollingTask.cpp | 9 +++++--- osal/common/UdpTmTcBridge.cpp | 22 ++++++++++-------- osal/common/tcpipCommon.cpp | 39 ++++++++++++++++++++++++++++++++ osal/common/tcpipCommon.h | 11 +++++++-- 5 files changed, 71 insertions(+), 17 deletions(-) diff --git a/osal/common/TcpTmTcServer.cpp b/osal/common/TcpTmTcServer.cpp index 296afad8..08a62ffb 100644 --- a/osal/common/TcpTmTcServer.cpp +++ b/osal/common/TcpTmTcServer.cpp @@ -70,6 +70,7 @@ ReturnValue_t TcpTmTcServer::initialize() { #endif freeaddrinfo(addrResult); handleError(Protocol::TCP, ErrorSources::BIND_CALL); + return HasReturnvaluesIF::RETURN_FAILED; } freeaddrinfo(addrResult); @@ -84,8 +85,8 @@ TcpTmTcServer::~TcpTmTcServer() { 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_t clientSocket; - sockaddr clientSockAddr; + socket_t clientSocket = 0; + sockaddr clientSockAddr = {}; socklen_t connectorSockAddrLen = 0; int retval = 0; @@ -101,6 +102,7 @@ ReturnValue_t TcpTmTcServer::performOperation(uint8_t opCode) { if(clientSocket == INVALID_SOCKET) { handleError(Protocol::TCP, ErrorSources::ACCEPT_CALL, 500); + closeSocket(clientSocket); continue; }; @@ -122,6 +124,7 @@ ReturnValue_t TcpTmTcServer::performOperation(uint8_t opCode) { /* Done, shut down connection */ retval = shutdown(clientSocket, SHUT_SEND); + closeSocket(clientSocket); } return HasReturnvaluesIF::RETURN_OK; } diff --git a/osal/common/UdpTcPollingTask.cpp b/osal/common/UdpTcPollingTask.cpp index 759cee05..47f67b29 100644 --- a/osal/common/UdpTcPollingTask.cpp +++ b/osal/common/UdpTcPollingTask.cpp @@ -15,7 +15,7 @@ #endif //! Debugging preprocessor define. -#define FSFW_UDP_RCV_WIRETAPPING_ENABLED 0 +#define FSFW_UDP_RECV_WIRETAPPING_ENABLED 0 UdpTcPollingTask::UdpTcPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge, size_t maxRecvSize, @@ -66,10 +66,13 @@ ReturnValue_t UdpTcPollingTask::performOperation(uint8_t opCode) { tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::RECVFROM_CALL, 1000); continue; } -#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1 +#if FSFW_UDP_RECV_WIRETAPPING_ENABLED == 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 sif::debug << "UdpTcPollingTask::performOperation: " << bytesReceived << " bytes received" << std::endl; +#else #endif +#endif /* FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1 */ ReturnValue_t result = handleSuccessfullTcRead(bytesReceived); if(result != HasReturnvaluesIF::RETURN_FAILED) { @@ -84,7 +87,7 @@ ReturnValue_t UdpTcPollingTask::performOperation(uint8_t opCode) { ReturnValue_t UdpTcPollingTask::handleSuccessfullTcRead(size_t bytesRead) { store_address_t storeId; -#if FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1 +#if FSFW_UDP_RECV_WIRETAPPING_ENABLED == 1 arrayprinter::print(receptionBuffer.data(), bytesRead); #endif diff --git a/osal/common/UdpTmTcBridge.cpp b/osal/common/UdpTmTcBridge.cpp index 7f3dc929..ba23f521 100644 --- a/osal/common/UdpTmTcBridge.cpp +++ b/osal/common/UdpTmTcBridge.cpp @@ -70,6 +70,7 @@ ReturnValue_t UdpTmTcBridge::initialize() { 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://en.wikipedia.org/wiki/Getaddrinfo @@ -95,6 +96,10 @@ ReturnValue_t UdpTmTcBridge::initialize() { return HasReturnvaluesIF::RETURN_FAILED; } +#if FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1 + tcpip::printAddress(addrResult->ai_addr); +#endif + retval = bind(serverSocket, addrResult->ai_addr, static_cast(addrResult->ai_addrlen)); if(retval != 0) { #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -103,6 +108,7 @@ ReturnValue_t UdpTmTcBridge::initialize() { #endif freeaddrinfo(addrResult); tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::BIND_CALL); + return HasReturnvaluesIF::RETURN_FAILED; } freeaddrinfo(addrResult); return HasReturnvaluesIF::RETURN_OK; @@ -120,10 +126,8 @@ ReturnValue_t UdpTmTcBridge::sendTm(const uint8_t *data, size_t dataLen) { /* 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]; - sif::debug << "IP Address Sender: "<< inet_ntop(AF_INET, - &clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; +#if FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1 + tcpip::printAddress(&clientAddress); #endif int bytesSent = sendto( @@ -151,13 +155,11 @@ 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); -#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_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; +#if FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1 + tcpip::printAddress(&newAddress); + tcpip::printAddress(&clientAddress); #endif + registerCommConnect(); /* Set new IP address to reply to */ diff --git a/osal/common/tcpipCommon.cpp b/osal/common/tcpipCommon.cpp index 9a5e4647..551e2a42 100644 --- a/osal/common/tcpipCommon.cpp +++ b/osal/common/tcpipCommon.cpp @@ -1,4 +1,9 @@ #include "tcpipCommon.h" +#include + +#ifdef _WIN32 +#include +#endif void tcpip::determineErrorStrings(Protocol protocol, ErrorSources errorSrc, std::string &protStr, std::string &srcString) { @@ -34,3 +39,37 @@ void tcpip::determineErrorStrings(Protocol protocol, ErrorSources errorSrc, std: srcString = "unknown call"; } } + +void tcpip::printAddress(struct sockaddr* addr) { + char ipAddress[INET6_ADDRSTRLEN] = {}; + const char* stringPtr = NULL; + switch(addr->sa_family) { + case AF_INET: { + struct sockaddr_in *addrIn = reinterpret_cast(addr); + stringPtr = inet_ntop(AF_INET, &(addrIn->sin_addr), ipAddress, INET_ADDRSTRLEN); + break; + } + case AF_INET6: { + struct sockaddr_in6 *addrIn = reinterpret_cast(addr); + stringPtr = inet_ntop(AF_INET6, &(addrIn->sin6_addr), ipAddress, INET6_ADDRSTRLEN); + break; + } + } +#if FSFW_CPP_OSTREAM_ENABLED == 1 + if(stringPtr == NULL) { + sif::debug << "Could not convert IP address to text representation, error code " + << errno << std::endl; + } + else { + sif::debug << "IP Address Sender: " << ipAddress << std::endl; + } +#else + if(stringPtr == NULL) { + sif::printDebug("Could not convert IP address to text representation, error code %d\n", + errno); + } + else { + sif::printDebug("IP Address Sender: %s\n", ipAddress); + } +#endif +} diff --git a/osal/common/tcpipCommon.h b/osal/common/tcpipCommon.h index dc5ada52..22b914dc 100644 --- a/osal/common/tcpipCommon.h +++ b/osal/common/tcpipCommon.h @@ -4,6 +4,13 @@ #include "../../timemanager/clockDefinitions.h" #include +#ifdef _WIN32 +#include +#else +#include +#include +#endif + namespace tcpip { const char* const DEFAULT_SERVER_PORT = "7301"; @@ -28,8 +35,8 @@ enum class ErrorSources { void determineErrorStrings(Protocol protocol, ErrorSources errorSrc, std::string& protStr, std::string& srcString); +void printAddress(struct sockaddr* addr); + } - - #endif /* FSFW_OSAL_COMMON_TCPIPCOMMON_H_ */ From 547538fbc5aa9b23d1128f01c100ad5a73b9a520 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 12 Apr 2021 12:38:56 +0200 Subject: [PATCH 154/230] proper MQ implementation --- osal/host/MessageQueue.cpp | 29 ++++++++++------------------- osal/host/MessageQueue.h | 2 +- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/osal/host/MessageQueue.cpp b/osal/host/MessageQueue.cpp index 18272a68..41c55a3d 100644 --- a/osal/host/MessageQueue.cpp +++ b/osal/host/MessageQueue.cpp @@ -64,9 +64,8 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { return MessageQueueIF::EMPTY; } MutexGuard mutexLock(queueLock, MutexIF::TimeoutType::WAITING, 20); - MessageQueueMessage* currentMessage = &messageQueue.front(); - std::copy(currentMessage->getBuffer(), - currentMessage->getBuffer() + messageSize, message->getBuffer()); + std::copy(messageQueue.front().data(), messageQueue.front().data() + messageSize, + message->getBuffer()); messageQueue.pop(); // The last partner is the first uint32_t field in the message this->lastPartner = message->getSender(); @@ -80,7 +79,7 @@ MessageQueueId_t MessageQueue::getLastPartner() const { ReturnValue_t MessageQueue::flush(uint32_t* count) { *count = messageQueue.size(); // Clears the queue. - messageQueue = std::queue(); + messageQueue = std::queue>(); return HasReturnvaluesIF::RETURN_OK; } @@ -106,6 +105,9 @@ bool MessageQueue::isDefaultDestinationSet() const { ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault) { + if(message == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } message->setSender(sentFrom); if(message->getMessageSize() > message->getMaximumMessageSize()) { // Actually, this should never happen or an error will be emitted @@ -128,21 +130,10 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, return HasReturnvaluesIF::RETURN_FAILED; } if(targetQueue->messageQueue.size() < targetQueue->messageDepth) { - MutexGuard mutexLock(targetQueue->queueLock, - MutexIF::TimeoutType::WAITING, 20); - // not ideal, works for now though. - MessageQueueMessage* mqmMessage = - dynamic_cast(message); - if(message != nullptr) { - targetQueue->messageQueue.push(*mqmMessage); - } - else { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "MessageQueue::sendMessageFromMessageQueue: Message" - "is not MessageQueueMessage!" << std::endl; -#endif - } - + MutexGuard mutexLock(targetQueue->queueLock, MutexIF::TimeoutType::WAITING, 20); + targetQueue->messageQueue.push(std::vector(message->getMaximumMessageSize())); + memcpy(targetQueue->messageQueue.back().data(), message->getBuffer(), + message->getMaximumMessageSize()); } else { return MessageQueueIF::FULL; diff --git a/osal/host/MessageQueue.h b/osal/host/MessageQueue.h index 97a9e491..e965123d 100644 --- a/osal/host/MessageQueue.h +++ b/osal/host/MessageQueue.h @@ -212,7 +212,7 @@ protected: //static ReturnValue_t handleSendResult(BaseType_t result, bool ignoreFault); private: - std::queue messageQueue; + std::queue> messageQueue; /** * @brief The class stores the queue id it got assigned. * If initialization fails, the queue id is set to zero. From 4bb078c451ddf543e15e27073f5c8edf1642d38e Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 12 Apr 2021 12:40:59 +0200 Subject: [PATCH 155/230] thermal sensor update --- thermal/TemperatureSensor.h | 54 +++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/thermal/TemperatureSensor.h b/thermal/TemperatureSensor.h index 2b1fb1f0..ceb8a861 100644 --- a/thermal/TemperatureSensor.h +++ b/thermal/TemperatureSensor.h @@ -1,11 +1,14 @@ #ifndef TEMPERATURESENSOR_H_ #define TEMPERATURESENSOR_H_ -#include "../thermal/AbstractTemperatureSensor.h" -#include "../datapoolglob/GlobalDataSet.h" -#include "../datapoolglob/GlobalPoolVariable.h" +#include "tcsDefinitions.h" +#include "AbstractTemperatureSensor.h" + +#include "../datapoollocal/LocalPoolDataSetBase.h" +#include "../datapoollocal/LocalPoolVariable.h" #include "../monitoring/LimitMonitor.h" + /** * @brief This building block handles non-linear value conversion and * range checks for analog temperature sensors. @@ -57,27 +60,26 @@ public: /** * Instantiate Temperature Sensor Object. - * @param setObjectid objectId of the sensor object - * @param inputValue Input value which is converted to a temperature - * @param poolVariable Pool Variable to store the temperature value - * @param vectorIndex Vector Index for the sensor monitor - * @param parameters Calculation parameters, temperature limits, gradient limit - * @param datapoolId Datapool ID of the output temperature - * @param outputSet Output dataset for the output temperature to fetch it with read() + * @param setObjectid objectId of the sensor object + * @param inputValue Pointer to input value which is converted to a temperature + * @param variableGpid Global Pool ID of the output value + * @param inputVariable Input variable handle + * @param vectorIndex Vector Index for the sensor monitor + * @param parameters Calculation parameters, temperature limits, gradient limit + * @param outputSet Output dataset for the output temperature to fetch it with read() * @param thermalModule respective thermal module, if it has one */ TemperatureSensor(object_id_t setObjectid, - inputType *inputValue, PoolVariableIF *poolVariable, - uint8_t vectorIndex, uint32_t datapoolId, Parameters parameters = {0, 0, 0, 0, 0, 0}, - GlobDataSet *outputSet = NULL, ThermalModuleIF *thermalModule = NULL) : + inputType *inputValue, gp_id_t variableGpid, PoolVariableIF* inputVariable, + uint8_t vectorIndex, Parameters parameters = {0, 0, 0, 0, 0, 0}, + LocalPoolDataSetBase *outputSet = NULL, ThermalModuleIF *thermalModule = NULL) : AbstractTemperatureSensor(setObjectid, thermalModule), parameters(parameters), - inputValue(inputValue), poolVariable(poolVariable), - outputTemperature(datapoolId, outputSet, PoolVariableIF::VAR_WRITE), - sensorMonitor(setObjectid, DOMAIN_ID_SENSOR, - GlobalDataPool::poolIdAndPositionToPid(poolVariable->getDataPoolId(), vectorIndex), + inputValue(inputValue), poolVariable(inputVariable), + outputTemperature(variableGpid, outputSet, PoolVariableIF::VAR_WRITE), + sensorMonitor(setObjectid, DOMAIN_ID_SENSOR, poolVariable, DEFAULT_CONFIRMATION_COUNT, parameters.lowerLimit, parameters.upperLimit, TEMP_SENSOR_LOW, TEMP_SENSOR_HIGH), - oldTemperature(20), uptimeOfOldTemperature( { INVALID_TEMPERATURE, 0 }) { + oldTemperature(20), uptimeOfOldTemperature({ thermal::INVALID_TEMPERATURE, 0 }) { } @@ -98,7 +100,7 @@ protected: private: void setInvalid() { - outputTemperature = INVALID_TEMPERATURE; + outputTemperature = thermal::INVALID_TEMPERATURE; outputTemperature.setValid(false); uptimeOfOldTemperature.tv_sec = INVALID_UPTIME; sensorMonitor.setToInvalid(); @@ -108,11 +110,11 @@ protected: UsedParameters parameters; - inputType * inputValue; + inputType* inputValue; - PoolVariableIF *poolVariable; + PoolVariableIF* poolVariable; - gp_float_t outputTemperature; + lp_var_t outputTemperature; LimitMonitor sensorMonitor; @@ -120,8 +122,8 @@ protected: timeval uptimeOfOldTemperature; void doChildOperation() { - if (!poolVariable->isValid() - || !healthHelper.healthTable->isHealthy(getObjectId())) { + if ((not poolVariable->isValid()) or + (not healthHelper.healthTable->isHealthy(getObjectId()))) { setInvalid(); return; } @@ -152,13 +154,13 @@ protected: } } - //Check is done against raw limits. SHOULDDO: Why? Using �C would be more easy to handle. + //Check is done against raw limits. SHOULDDO: Why? Using C would be more easy to handle. sensorMonitor.doCheck(outputTemperature.value); if (sensorMonitor.isOutOfLimits()) { uptimeOfOldTemperature.tv_sec = INVALID_UPTIME; outputTemperature.setValid(PoolVariableIF::INVALID); - outputTemperature = INVALID_TEMPERATURE; + outputTemperature = thermal::INVALID_TEMPERATURE; } else { oldTemperature = outputTemperature; uptimeOfOldTemperature = uptime; From 5124f314f497bcfa8758c7124f63c68fb24eb88c Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 12 Apr 2021 12:50:23 +0200 Subject: [PATCH 156/230] updated distributor modules --- tcdistribution/CCSDSDistributor.cpp | 31 +++++-- tcdistribution/PUSDistributor.cpp | 121 ++++++++++++++++------------ 2 files changed, 92 insertions(+), 60 deletions(-) diff --git a/tcdistribution/CCSDSDistributor.cpp b/tcdistribution/CCSDSDistributor.cpp index b795854f..62cbfbf2 100644 --- a/tcdistribution/CCSDSDistributor.cpp +++ b/tcdistribution/CCSDSDistributor.cpp @@ -1,8 +1,10 @@ #include "CCSDSDistributor.h" -#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../serviceinterface/ServiceInterface.h" #include "../tmtcpacket/SpacePacketBase.h" +#define CCSDS_DISTRIBUTOR_DEBUGGING 0 + CCSDSDistributor::CCSDSDistributor(uint16_t setDefaultApid, object_id_t setObjectId): TcDistributor(setObjectId), defaultApid( setDefaultApid ) { @@ -11,26 +13,36 @@ CCSDSDistributor::CCSDSDistributor(uint16_t setDefaultApid, CCSDSDistributor::~CCSDSDistributor() {} TcDistributor::TcMqMapIter CCSDSDistributor::selectDestination() { +#if CCSDS_DISTRIBUTOR_DEBUGGING == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 -// sif::debug << "CCSDSDistributor::selectDestination received: " << -// this->currentMessage.getStorageId().pool_index << ", " << -// this->currentMessage.getStorageId().packet_index << std::endl; + sif::debug << "CCSDSDistributor::selectDestination received: " << + this->currentMessage.getStorageId().poolIndex << ", " << + this->currentMessage.getStorageId().packetIndex << std::endl; +#else + sif::printDebug("CCSDSDistributor::selectDestination received: %d, %d\n", + currentMessage.getStorageId().poolIndex, currentMessage.getStorageId().packetIndex); +#endif #endif const uint8_t* packet = nullptr; size_t size = 0; ReturnValue_t result = this->tcStore->getData(currentMessage.getStorageId(), &packet, &size ); if(result != HasReturnvaluesIF::RETURN_OK) { +#if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "CCSDSDistributor::selectDestination: Getting data from" " store failed!" << std::endl; +#else + sif::printError("CCSDSDistributor::selectDestination: Getting data from" + " store failed!\n"); +#endif #endif } SpacePacketBase currentPacket(packet); -#if FSFW_CPP_OSTREAM_ENABLED == 1 -// sif:: info << "CCSDSDistributor::selectDestination has packet with APID " -// << std::hex << currentPacket.getAPID() << std::dec << std::endl; +#if FSFW_CPP_OSTREAM_ENABLED == 1 && CCSDS_DISTRIBUTOR_DEBUGGING == 1 + sif::info << "CCSDSDistributor::selectDestination has packet with APID " << std::hex << + currentPacket.getAPID() << std::dec << std::endl; #endif TcMqMapIter position = this->queueMap.find(currentPacket.getAPID()); if ( position != this->queueMap.end() ) { @@ -76,9 +88,14 @@ ReturnValue_t CCSDSDistributor::initialize() { ReturnValue_t status = this->TcDistributor::initialize(); this->tcStore = objectManager->get( objects::TC_STORE ); if (this->tcStore == nullptr) { +#if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "CCSDSDistributor::initialize: Could not initialize" " TC store!" << std::endl; +#else + sif::printError("CCSDSDistributor::initialize: Could not initialize" + " TC store!\n"); +#endif #endif status = RETURN_FAILED; } diff --git a/tcdistribution/PUSDistributor.cpp b/tcdistribution/PUSDistributor.cpp index 00fd9029..abdd1f8d 100644 --- a/tcdistribution/PUSDistributor.cpp +++ b/tcdistribution/PUSDistributor.cpp @@ -1,22 +1,24 @@ #include "CCSDSDistributorIF.h" #include "PUSDistributor.h" -#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../serviceinterface/ServiceInterface.h" #include "../tmtcpacket/pus/TcPacketStored.h" #include "../tmtcservices/PusVerificationReport.h" +#define PUS_DISTRIBUTOR_DEBUGGING 0 + PUSDistributor::PUSDistributor(uint16_t setApid, object_id_t setObjectId, - object_id_t setPacketSource) : - TcDistributor(setObjectId), checker(setApid), verifyChannel(), - tcStatus(RETURN_FAILED), packetSource(setPacketSource) {} + object_id_t setPacketSource) : + TcDistributor(setObjectId), checker(setApid), verifyChannel(), + tcStatus(RETURN_FAILED), packetSource(setPacketSource) {} PUSDistributor::~PUSDistributor() {} PUSDistributor::TcMqMapIter PUSDistributor::selectDestination() { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - // sif:: debug << "PUSDistributor::handlePacket received: " - // << this->current_packet_id.store_index << ", " - // << this->current_packet_id.packet_index << std::endl; +#if FSFW_CPP_OSTREAM_ENABLED == 1 && PUS_DISTRIBUTOR_DEBUGGING == 1 + store_address_t storeId = this->currentMessage.getStorageId()); + sif:: debug << "PUSDistributor::handlePacket received: " << storeId.poolIndex << ", " << + storeId.packetIndex << std::endl; #endif TcMqMapIter queueMapIt = this->queueMap.end(); if(this->currentPacket == nullptr) { @@ -25,15 +27,17 @@ PUSDistributor::TcMqMapIter PUSDistributor::selectDestination() { this->currentPacket->setStoreAddress(this->currentMessage.getStorageId()); if (currentPacket->getWholeData() != nullptr) { tcStatus = checker.checkPacket(currentPacket); -#ifdef DEBUG if(tcStatus != HasReturnvaluesIF::RETURN_OK) { +#if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::debug << "PUSDistributor::handlePacket: Packet format " - << "invalid, code "<< static_cast(tcStatus) - << std::endl; + sif::debug << "PUSDistributor::handlePacket: Packet format invalid, code " << + static_cast(tcStatus) << std::endl; +#else + sif::printDebug("PUSDistributor::handlePacket: Packet format invalid, code %d\n", + static_cast(tcStatus)); +#endif #endif } -#endif uint32_t queue_id = currentPacket->getService(); queueMapIt = this->queueMap.find(queue_id); } @@ -43,11 +47,12 @@ PUSDistributor::TcMqMapIter PUSDistributor::selectDestination() { if (queueMapIt == this->queueMap.end()) { tcStatus = DESTINATION_NOT_FOUND; -#ifdef DEBUG +#if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::debug << "PUSDistributor::handlePacket: Destination not found, " - << "code "<< static_cast(tcStatus) << std::endl; -#endif + sif::debug << "PUSDistributor::handlePacket: Destination not found" << std::endl; +#else + sif::printDebug("PUSDistributor::handlePacket: Destination not found\n"); +#endif /* !FSFW_CPP_OSTREAM_ENABLED == 1 */ #endif } @@ -62,46 +67,54 @@ PUSDistributor::TcMqMapIter PUSDistributor::selectDestination() { ReturnValue_t PUSDistributor::registerService(AcceptsTelecommandsIF* service) { - uint16_t serviceId = service->getIdentifier(); + uint16_t serviceId = service->getIdentifier(); +#if PUS_DISTRIBUTOR_DEBUGGING == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - // sif::info << "Service ID: " << (int)serviceId << std::endl; + sif::info << "Service ID: " << static_cast(serviceId) << std::endl; +#else + sif::printInfo("Service ID: %d\n", static_cast(serviceId)); #endif - MessageQueueId_t queue = service->getRequestQueue(); - auto returnPair = queueMap.emplace(serviceId, queue); - if (not returnPair.second) { +#endif + MessageQueueId_t queue = service->getRequestQueue(); + auto returnPair = queueMap.emplace(serviceId, queue); + if (not returnPair.second) { +#if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PUSDistributor::registerService: Service ID already" - " exists in map." << std::endl; + sif::error << "PUSDistributor::registerService: Service ID already" + " exists in map" << std::endl; +#else + sif::printError("PUSDistributor::registerService: Service ID already exists in map\n"); #endif - return SERVICE_ID_ALREADY_EXISTS; - } - return HasReturnvaluesIF::RETURN_OK; +#endif + return SERVICE_ID_ALREADY_EXISTS; + } + return HasReturnvaluesIF::RETURN_OK; } MessageQueueId_t PUSDistributor::getRequestQueue() { - return tcQueue->getId(); + return tcQueue->getId(); } ReturnValue_t PUSDistributor::callbackAfterSending(ReturnValue_t queueStatus) { - if (queueStatus != RETURN_OK) { - tcStatus = queueStatus; - } - if (tcStatus != RETURN_OK) { - this->verifyChannel.sendFailureReport(tc_verification::ACCEPTANCE_FAILURE, - currentPacket, tcStatus); - // A failed packet is deleted immediately after reporting, - // otherwise it will block memory. - currentPacket->deletePacket(); - return RETURN_FAILED; - } else { - this->verifyChannel.sendSuccessReport(tc_verification::ACCEPTANCE_SUCCESS, - currentPacket); - return RETURN_OK; - } + if (queueStatus != RETURN_OK) { + tcStatus = queueStatus; + } + if (tcStatus != RETURN_OK) { + this->verifyChannel.sendFailureReport(tc_verification::ACCEPTANCE_FAILURE, + currentPacket, tcStatus); + // A failed packet is deleted immediately after reporting, + // otherwise it will block memory. + currentPacket->deletePacket(); + return RETURN_FAILED; + } else { + this->verifyChannel.sendSuccessReport(tc_verification::ACCEPTANCE_SUCCESS, + currentPacket); + return RETURN_OK; + } } uint16_t PUSDistributor::getIdentifier() { - return checker.getApid(); + return checker.getApid(); } ReturnValue_t PUSDistributor::initialize() { @@ -111,15 +124,17 @@ ReturnValue_t PUSDistributor::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } - CCSDSDistributorIF* ccsdsDistributor = - objectManager->get(packetSource); - if (ccsdsDistributor == nullptr) { + CCSDSDistributorIF* ccsdsDistributor = + objectManager->get(packetSource); + if (ccsdsDistributor == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PUSDistributor::initialize: Packet source invalid." - << " Make sure it exists and implements CCSDSDistributorIF!" - << std::endl; + sif::error << "PUSDistributor::initialize: Packet source invalid" << std::endl; + sif::error << " Make sure it exists and implements CCSDSDistributorIF!" << std::endl; +#else + sif::printError("PUSDistributor::initialize: Packet source invalid\n"); + sif::printError("Make sure it exists and implements CCSDSDistributorIF\n"); #endif - return RETURN_FAILED; - } - return ccsdsDistributor->registerApplication(this); + return RETURN_FAILED; + } + return ccsdsDistributor->registerApplication(this); } From d7d52439d76a114bebaa3a67e4a59385eac91540 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Apr 2021 20:40:41 +0200 Subject: [PATCH 157/230] added new option --- defaultcfg/fsfwconfig/FSFWConfig.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/defaultcfg/fsfwconfig/FSFWConfig.h b/defaultcfg/fsfwconfig/FSFWConfig.h index ed86e6e1..9a07b4ea 100644 --- a/defaultcfg/fsfwconfig/FSFWConfig.h +++ b/defaultcfg/fsfwconfig/FSFWConfig.h @@ -17,6 +17,8 @@ #define FSFW_DISABLE_PRINTOUT 0 #endif +#define FSFW_USE_PUS_C_TELEMETRY 1 + //! Can be used to disable the ANSI color sequences for C stdio. #define FSFW_COLORED_OUTPUT 1 From 9a5f717169069f23330b47ed73c62cfd8139e96e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Apr 2021 21:17:53 +0200 Subject: [PATCH 158/230] refactoring to allow PUS c implementation --- tmtcpacket/pus/CMakeLists.txt | 2 + tmtcpacket/pus/TmPacketBase.cpp | 106 +++----------- tmtcpacket/pus/TmPacketBase.h | 234 +++++++++++------------------- tmtcpacket/pus/TmPacketIF.h | 8 + tmtcpacket/pus/TmPacketPusA.cpp | 121 +++++++++++++++ tmtcpacket/pus/TmPacketPusA.h | 137 +++++++++++++++++ tmtcpacket/pus/TmPacketPusC.cpp | 2 + tmtcpacket/pus/TmPacketPusC.h | 8 + tmtcpacket/pus/TmPacketStored.cpp | 10 +- tmtcpacket/pus/TmPacketStored.h | 4 +- 10 files changed, 398 insertions(+), 234 deletions(-) create mode 100644 tmtcpacket/pus/TmPacketIF.h create mode 100644 tmtcpacket/pus/TmPacketPusA.cpp create mode 100644 tmtcpacket/pus/TmPacketPusA.h create mode 100644 tmtcpacket/pus/TmPacketPusC.cpp create mode 100644 tmtcpacket/pus/TmPacketPusC.h diff --git a/tmtcpacket/pus/CMakeLists.txt b/tmtcpacket/pus/CMakeLists.txt index fcfc82d2..1fdd9dd8 100644 --- a/tmtcpacket/pus/CMakeLists.txt +++ b/tmtcpacket/pus/CMakeLists.txt @@ -5,4 +5,6 @@ target_sources(${LIB_FSFW_NAME} TmPacketBase.cpp TmPacketMinimal.cpp TmPacketStored.cpp + TmPacketPusA.cpp + TmPacketPusC.cpp ) diff --git a/tmtcpacket/pus/TmPacketBase.cpp b/tmtcpacket/pus/TmPacketBase.cpp index c8e4b430..10f37b00 100644 --- a/tmtcpacket/pus/TmPacketBase.cpp +++ b/tmtcpacket/pus/TmPacketBase.cpp @@ -11,111 +11,53 @@ TimeStamperIF* TmPacketBase::timeStamper = nullptr; object_id_t TmPacketBase::timeStamperId = 0; -TmPacketBase::TmPacketBase(uint8_t* setData) : - SpacePacketBase(setData) { - tmData = reinterpret_cast(setData); +TmPacketBase::TmPacketBase(uint8_t* setData): + SpacePacketBase(setData) { } TmPacketBase::~TmPacketBase() { - //Nothing to do. + //Nothing to do. } -uint8_t TmPacketBase::getService() { - return tmData->data_field.service_type; -} - -uint8_t TmPacketBase::getSubService() { - return tmData->data_field.service_subtype; -} - -uint8_t* TmPacketBase::getSourceData() { - return &tmData->data; -} uint16_t TmPacketBase::getSourceDataSize() { - return getPacketDataLength() - sizeof(tmData->data_field) - - CRC_SIZE + 1; + return getPacketDataLength() - getDataFieldSize() - CRC_SIZE + 1; } uint16_t TmPacketBase::getErrorControl() { - uint32_t size = getSourceDataSize() + CRC_SIZE; - uint8_t* p_to_buffer = &tmData->data; - return (p_to_buffer[size - 2] << 8) + p_to_buffer[size - 1]; + uint32_t size = getSourceDataSize() + CRC_SIZE; + uint8_t* p_to_buffer = getSourceData(); + return (p_to_buffer[size - 2] << 8) + p_to_buffer[size - 1]; } void TmPacketBase::setErrorControl() { - uint32_t full_size = getFullSize(); - uint16_t crc = CRC::crc16ccitt(getWholeData(), full_size - CRC_SIZE); - uint32_t size = getSourceDataSize(); - getSourceData()[size] = (crc & 0XFF00) >> 8; // CRCH - getSourceData()[size + 1] = (crc) & 0X00FF; // CRCL + uint32_t full_size = getFullSize(); + uint16_t crc = CRC::crc16ccitt(getWholeData(), full_size - CRC_SIZE); + uint32_t size = getSourceDataSize(); + getSourceData()[size] = (crc & 0XFF00) >> 8; // CRCH + getSourceData()[size + 1] = (crc) & 0X00FF; // CRCL } -void TmPacketBase::setData(const uint8_t* p_Data) { - SpacePacketBase::setData(p_Data); - tmData = (TmPacketPointer*) p_Data; -} + void TmPacketBase::print() { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::debug << "TmPacketBase::print: " << std::endl; + sif::debug << "TmPacketBase::print: " << std::endl; #endif - arrayprinter::print(getWholeData(), getFullSize()); + arrayprinter::print(getWholeData(), getFullSize()); } bool TmPacketBase::checkAndSetStamper() { - if (timeStamper == NULL) { - timeStamper = objectManager->get(timeStamperId); - if (timeStamper == NULL) { + if (timeStamper == NULL) { + timeStamper = objectManager->get(timeStamperId); + if (timeStamper == NULL) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TmPacketBase::checkAndSetStamper: Stamper not found!" - << std::endl; + sif::error << "TmPacketBase::checkAndSetStamper: Stamper not found!" + << std::endl; #endif - return false; - } - } - return true; + return false; + } + } + return true; } -ReturnValue_t TmPacketBase::getPacketTime(timeval* timestamp) const { - size_t tempSize = 0; - return CCSDSTime::convertFromCcsds(timestamp, tmData->data_field.time, - &tempSize, sizeof(tmData->data_field.time)); -} - -uint8_t* TmPacketBase::getPacketTimeRaw() const{ - return tmData->data_field.time; - -} - -void TmPacketBase::initializeTmPacket(uint16_t apid, uint8_t service, - uint8_t subservice, uint8_t packetSubcounter) { - //Set primary header: - initSpacePacketHeader(false, true, apid); - //Set data Field Header: - //First, set to zero. - memset(&tmData->data_field, 0, sizeof(tmData->data_field)); - - // NOTE: In PUS-C, the PUS Version is 2 and specified for the first 4 bits. - // The other 4 bits of the first byte are the spacecraft time reference - // status. To change to PUS-C, set 0b00100000. - // Set CCSDS_secondary header flag to 0, version number to 001 and ack - // to 0000 - tmData->data_field.version_type_ack = 0b00010000; - tmData->data_field.service_type = service; - tmData->data_field.service_subtype = subservice; - tmData->data_field.subcounter = packetSubcounter; - //Timestamp packet - if (checkAndSetStamper()) { - timeStamper->addTimeStamp(tmData->data_field.time, - sizeof(tmData->data_field.time)); - } -} - -void TmPacketBase::setSourceDataSize(uint16_t size) { - setPacketDataLength(size + sizeof(PUSTmDataFieldHeader) + CRC_SIZE - 1); -} - -size_t TmPacketBase::getTimestampSize() const { - return sizeof(tmData->data_field.time); -} diff --git a/tmtcpacket/pus/TmPacketBase.h b/tmtcpacket/pus/TmPacketBase.h index 6efc0165..72cdbb69 100644 --- a/tmtcpacket/pus/TmPacketBase.h +++ b/tmtcpacket/pus/TmPacketBase.h @@ -10,32 +10,6 @@ namespace Factory{ void setStaticFrameworkObjectIds(); } -/** - * This struct defines a byte-wise structured PUS TM Data Field Header. - * Any optional fields in the header must be added or removed here. - * Currently, no Destination field is present, but an eigth-byte representation - * for a time tag. - * @ingroup tmtcpackets - */ -struct PUSTmDataFieldHeader { - uint8_t version_type_ack; - uint8_t service_type; - uint8_t service_subtype; - uint8_t subcounter; -// uint8_t destination; - uint8_t time[TimeStamperIF::MISSION_TIMESTAMP_SIZE]; -}; - -/** - * This struct defines the data structure of a PUS Telecommand Packet when - * accessed via a pointer. - * @ingroup tmtcpackets - */ -struct TmPacketPointer { - CCSDSPrimaryHeader primary; - PUSTmDataFieldHeader data_field; - uint8_t data; -}; /** * This class is the basic data handler for any ECSS PUS Telemetry packet. @@ -49,61 +23,84 @@ struct TmPacketPointer { * @ingroup tmtcpackets */ class TmPacketBase : public SpacePacketBase { - friend void (Factory::setStaticFrameworkObjectIds)(); + friend void (Factory::setStaticFrameworkObjectIds)(); public: - /** - * This constant defines the minimum size of a valid PUS Telemetry Packet. - */ - static const uint32_t TM_PACKET_MIN_SIZE = (sizeof(CCSDSPrimaryHeader) + - sizeof(PUSTmDataFieldHeader) + 2); - //! Maximum size of a TM Packet in this mission. - //! TODO: Make this dependant on a config variable. - static const uint32_t MISSION_TM_PACKET_MAX_SIZE = 2048; - //! First byte of secondary header for PUS-A packets. - //! TODO: Maybe also support PUS-C via config? - static const uint8_t VERSION_NUMBER_BYTE_PUS_A = 0b00010000; - /** - * This is the default constructor. - * It sets its internal data pointer to the address passed and also - * forwards the data pointer to the parent SpacePacketBase class. - * @param set_address The position where the packet data lies. - */ - TmPacketBase( uint8_t* setData ); - /** - * This is the empty default destructor. - */ - virtual ~TmPacketBase(); + //! Maximum size of a TM Packet in this mission. + //! TODO: Make this dependant on a config variable. + static const uint32_t MISSION_TM_PACKET_MAX_SIZE = 2048; + //! First byte of secondary header for PUS-A packets. + //! TODO: Maybe also support PUS-C via config? + static const uint8_t VERSION_NUMBER_BYTE_PUS_A = 0b00010000; - /** - * This is a getter for the packet's PUS Service ID, which is the second - * byte of the Data Field Header. - * @return The packet's PUS Service ID. - */ - uint8_t getService(); - /** - * This is a getter for the packet's PUS Service Subtype, which is the - * third byte of the Data Field Header. - * @return The packet's PUS Service Subtype. - */ - uint8_t getSubService(); - /** - * This is a getter for a pointer to the packet's Source data. - * - * These are the bytes that follow after the Data Field Header. They form - * the packet's source data. - * @return A pointer to the PUS Source Data. - */ - uint8_t* getSourceData(); - /** - * This method calculates the size of the PUS Source data field. - * - * It takes the information stored in the CCSDS Packet Data Length field - * and subtracts the Data Field Header size and the CRC size. - * @return The size of the PUS Source Data (without Error Control field) - */ - uint16_t getSourceDataSize(); + /** + * This is the default constructor. + * It sets its internal data pointer to the address passed and also + * forwards the data pointer to the parent SpacePacketBase class. + * @param set_address The position where the packet data lies. + */ + TmPacketBase( uint8_t* setData ); + /** + * This is the empty default destructor. + */ + virtual ~TmPacketBase(); + /** + * This is a getter for the packet's PUS Service ID, which is the second + * byte of the Data Field Header. + * @return The packet's PUS Service ID. + */ + virtual uint8_t getService() = 0; + /** + * This is a getter for the packet's PUS Service Subtype, which is the + * third byte of the Data Field Header. + * @return The packet's PUS Service Subtype. + */ + virtual uint8_t getSubService() = 0; + /** + * This is a getter for a pointer to the packet's Source data. + * + * These are the bytes that follow after the Data Field Header. They form + * the packet's source data. + * @return A pointer to the PUS Source Data. + */ + virtual uint8_t* getSourceData() = 0; + /** + * This method calculates the size of the PUS Source data field. + * + * It takes the information stored in the CCSDS Packet Data Length field + * and subtracts the Data Field Header size and the CRC size. + * @return The size of the PUS Source Data (without Error Control field) + */ + virtual uint16_t getSourceDataSize() = 0; + + /** + * Get size of data field which can differ based on implementation + * @return + */ + virtual uint16_t getDataFieldSize() = 0; + + virtual size_t getPacketMinimumSize() const = 0; + + /** + * Interprets the "time"-field in the secondary header and returns it in + * timeval format. + * @return Converted timestamp of packet. + */ + virtual ReturnValue_t getPacketTime(timeval* timestamp) const = 0; + /** + * Returns a raw pointer to the beginning of the time field. + * @return Raw pointer to time field. + */ + virtual uint8_t* getPacketTimeRaw() const = 0; + + virtual size_t getTimestampSize() const = 0; + + /** + * This is a debugging helper method that prints the whole packet content + * to the screen. + */ + void print(); /** * With this method, the Error Control Field is updated to match the * current content of the packet. This method is not protected because @@ -111,79 +108,24 @@ public: * like the sequence count. */ void setErrorControl(); - - /** - * This getter returns the Error Control Field of the packet. - * - * The field is placed after any possible Source Data. If no - * Source Data is present there's still an Error Control field. It is - * supposed to be a 16bit-CRC. - * @return The PUS Error Control - */ - uint16_t getErrorControl(); - - /** - * This is a debugging helper method that prints the whole packet content - * to the screen. - */ - void print(); - /** - * Interprets the "time"-field in the secondary header and returns it in - * timeval format. - * @return Converted timestamp of packet. - */ - ReturnValue_t getPacketTime(timeval* timestamp) const; - /** - * Returns a raw pointer to the beginning of the time field. - * @return Raw pointer to time field. - */ - uint8_t* getPacketTimeRaw() const; - - size_t getTimestampSize() const; + /** + * This getter returns the Error Control Field of the packet. + * + * The field is placed after any possible Source Data. If no + * Source Data is present there's still an Error Control field. It is + * supposed to be a 16bit-CRC. + * @return The PUS Error Control + */ + uint16_t getErrorControl(); protected: - /** - * A pointer to a structure which defines the data structure of - * the packet's data. - * - * To be hardware-safe, all elements are of byte size. - */ - TmPacketPointer* tmData; - /** - * The timeStamper is responsible for adding a timestamp to the packet. - * It is initialized lazy. - */ - static TimeStamperIF* timeStamper; - //! The ID to use when looking for a time stamper. - static object_id_t timeStamperId; - /** - * Initializes the Tm Packet header. - * Does set the timestamp (to now), but not the error control field. - * @param apid APID used. - * @param service PUS Service - * @param subservice PUS Subservice - * @param packetSubcounter Additional subcounter used. + * The timeStamper is responsible for adding a timestamp to the packet. + * It is initialized lazy. */ - void initializeTmPacket(uint16_t apid, uint8_t service, uint8_t subservice, - uint8_t packetSubcounter); - - /** - * With this method, the packet data pointer can be redirected to another - * location. - * - * This call overwrites the parent's setData method to set both its - * @c tc_data pointer and the parent's @c data pointer. - * - * @param p_data A pointer to another PUS Telemetry Packet. - */ - void setData( const uint8_t* pData ); - - /** - * In case data was filled manually (almost never the case). - * @param size Size of source data (without CRC and data filed header!). - */ - void setSourceDataSize(uint16_t size); + static TimeStamperIF* timeStamper; + //! The ID to use when looking for a time stamper. + static object_id_t timeStamperId; /** * Checks if a time stamper is available and tries to set it if not. diff --git a/tmtcpacket/pus/TmPacketIF.h b/tmtcpacket/pus/TmPacketIF.h new file mode 100644 index 00000000..bd66523b --- /dev/null +++ b/tmtcpacket/pus/TmPacketIF.h @@ -0,0 +1,8 @@ +#ifndef FSFW_TMTCPACKET_PUS_TMPACKETIF_H_ +#define FSFW_TMTCPACKET_PUS_TMPACKETIF_H_ + + + + + +#endif /* FSFW_TMTCPACKET_PUS_TMPACKETIF_H_ */ diff --git a/tmtcpacket/pus/TmPacketPusA.cpp b/tmtcpacket/pus/TmPacketPusA.cpp new file mode 100644 index 00000000..630aac0f --- /dev/null +++ b/tmtcpacket/pus/TmPacketPusA.cpp @@ -0,0 +1,121 @@ +#include "TmPacketPusA.h" +#include "TmPacketBase.h" + +#include "../../globalfunctions/CRC.h" +#include "../../globalfunctions/arrayprinter.h" +#include "../../objectmanager/ObjectManagerIF.h" +#include "../../serviceinterface/ServiceInterfaceStream.h" +#include "../../timemanager/CCSDSTime.h" + +#include + + +TmPacketPusA::TmPacketPusA(uint8_t* setData) : TmPacketBase(setData) { + tmData = reinterpret_cast(setData); +} + +TmPacketPusA::~TmPacketPusA() { + //Nothing to do. +} + +uint8_t TmPacketPusA::getService() { + return tmData->data_field.service_type; +} + +uint8_t TmPacketPusA::getSubService() { + return tmData->data_field.service_subtype; +} + +uint8_t* TmPacketPusA::getSourceData() { + return &tmData->data; +} + +uint16_t TmPacketPusA::getSourceDataSize() { + return getPacketDataLength() - sizeof(tmData->data_field) + - CRC_SIZE + 1; +} + +//uint16_t TmPacketPusA::getErrorControl() { +// uint32_t size = getSourceDataSize() + CRC_SIZE; +// uint8_t* p_to_buffer = &tmData->data; +// return (p_to_buffer[size - 2] << 8) + p_to_buffer[size - 1]; +//} +// +//void TmPacketPusA::setErrorControl() { +// uint32_t full_size = getFullSize(); +// uint16_t crc = CRC::crc16ccitt(getWholeData(), full_size - CRC_SIZE); +// uint32_t size = getSourceDataSize(); +// getSourceData()[size] = (crc & 0XFF00) >> 8; // CRCH +// getSourceData()[size + 1] = (crc) & 0X00FF; // CRCL +//} + +void TmPacketPusA::setData(const uint8_t* p_Data) { + SpacePacketBase::setData(p_Data); + tmData = (TmPacketPointer*) p_Data; +} + + +size_t TmPacketPusA::getPacketMinimumSize() const { + return TM_PACKET_MIN_SIZE; +} + +uint16_t TmPacketPusA::getDataFieldSize() { + return sizeof(PUSTmDataFieldHeader); +} + +bool TmPacketPusA::checkAndSetStamper() { + if (timeStamper == NULL) { + timeStamper = objectManager->get(timeStamperId); + if (timeStamper == NULL) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "TmPacketPusA::checkAndSetStamper: Stamper not found!" + << std::endl; +#endif + return false; + } + } + return true; +} + +ReturnValue_t TmPacketPusA::getPacketTime(timeval* timestamp) const { + size_t tempSize = 0; + return CCSDSTime::convertFromCcsds(timestamp, tmData->data_field.time, + &tempSize, sizeof(tmData->data_field.time)); +} + +uint8_t* TmPacketPusA::getPacketTimeRaw() const{ + return tmData->data_field.time; + +} + +void TmPacketPusA::initializeTmPacket(uint16_t apid, uint8_t service, + uint8_t subservice, uint8_t packetSubcounter) { + //Set primary header: + initSpacePacketHeader(false, true, apid); + //Set data Field Header: + //First, set to zero. + memset(&tmData->data_field, 0, sizeof(tmData->data_field)); + + // NOTE: In PUS-C, the PUS Version is 2 and specified for the first 4 bits. + // The other 4 bits of the first byte are the spacecraft time reference + // status. To change to PUS-C, set 0b00100000. + // Set CCSDS_secondary header flag to 0, version number to 001 and ack + // to 0000 + tmData->data_field.version_type_ack = 0b00010000; + tmData->data_field.service_type = service; + tmData->data_field.service_subtype = subservice; + tmData->data_field.subcounter = packetSubcounter; + //Timestamp packet + if (checkAndSetStamper()) { + timeStamper->addTimeStamp(tmData->data_field.time, + sizeof(tmData->data_field.time)); + } +} + +void TmPacketPusA::setSourceDataSize(uint16_t size) { + setPacketDataLength(size + sizeof(PUSTmDataFieldHeader) + CRC_SIZE - 1); +} + +size_t TmPacketPusA::getTimestampSize() const { + return sizeof(tmData->data_field.time); +} diff --git a/tmtcpacket/pus/TmPacketPusA.h b/tmtcpacket/pus/TmPacketPusA.h new file mode 100644 index 00000000..4db634c2 --- /dev/null +++ b/tmtcpacket/pus/TmPacketPusA.h @@ -0,0 +1,137 @@ +#ifndef FSFW_TMTCPACKET_PUS_TMPACKETPUSA_H_ +#define FSFW_TMTCPACKET_PUS_TMPACKETPUSA_H_ + +#include "TmPacketBase.h" +#include "../SpacePacketBase.h" +#include "../../timemanager/TimeStamperIF.h" +#include "../../timemanager/Clock.h" +#include "../../objectmanager/SystemObjectIF.h" + +namespace Factory{ +void setStaticFrameworkObjectIds(); +} + +/** + * This struct defines a byte-wise structured PUS TM Data Field Header. + * Any optional fields in the header must be added or removed here. + * Currently, no Destination field is present, but an eigth-byte representation + * for a time tag. + * @ingroup tmtcpackets + */ +struct PUSTmDataFieldHeader { + uint8_t version_type_ack; + uint8_t service_type; + uint8_t service_subtype; + uint8_t subcounter; +// uint8_t destination; + uint8_t time[TimeStamperIF::MISSION_TIMESTAMP_SIZE]; +}; + +/** + * This struct defines the data structure of a PUS Telecommand Packet when + * accessed via a pointer. + * @ingroup tmtcpackets + */ +struct TmPacketPointer { + CCSDSPrimaryHeader primary; + PUSTmDataFieldHeader data_field; + uint8_t data; +}; + +/** + * PUS A packet implementation + * @ingroup tmtcpackets + */ +class TmPacketPusA: public TmPacketBase { + friend void (Factory::setStaticFrameworkObjectIds)(); +public: + /** + * This constant defines the minimum size of a valid PUS Telemetry Packet. + */ + static const uint32_t TM_PACKET_MIN_SIZE = (sizeof(CCSDSPrimaryHeader) + + sizeof(PUSTmDataFieldHeader) + 2); + //! Maximum size of a TM Packet in this mission. + //! TODO: Make this dependant on a config variable. + static const uint32_t MISSION_TM_PACKET_MAX_SIZE = 2048; + //! First byte of secondary header for PUS-A packets. + //! TODO: Maybe also support PUS-C via config? + static const uint8_t VERSION_NUMBER_BYTE_PUS_A = 0b00010000; + + /** + * This is the default constructor. + * It sets its internal data pointer to the address passed and also + * forwards the data pointer to the parent SpacePacketBase class. + * @param set_address The position where the packet data lies. + */ + TmPacketPusA( uint8_t* setData ); + /** + * This is the empty default destructor. + */ + virtual ~TmPacketPusA(); + + /* TmPacketBase implementations */ + uint8_t getService() override; + uint8_t getSubService() override; + uint8_t* getSourceData() override; + uint16_t getSourceDataSize() override; + uint16_t getDataFieldSize() override; + /** + * Interprets the "time"-field in the secondary header and returns it in + * timeval format. + * @return Converted timestamp of packet. + */ + ReturnValue_t getPacketTime(timeval* timestamp) const override; + /** + * Returns a raw pointer to the beginning of the time field. + * @return Raw pointer to time field. + */ + uint8_t* getPacketTimeRaw() const override; + + size_t getTimestampSize() const override; + size_t getPacketMinimumSize() const override; + +protected: + /** + * A pointer to a structure which defines the data structure of + * the packet's data. + * + * To be hardware-safe, all elements are of byte size. + */ + TmPacketPointer* tmData; + + /** + * Initializes the Tm Packet header. + * Does set the timestamp (to now), but not the error control field. + * @param apid APID used. + * @param service PUS Service + * @param subservice PUS Subservice + * @param packetSubcounter Additional subcounter used. + */ + void initializeTmPacket(uint16_t apid, uint8_t service, uint8_t subservice, + uint8_t packetSubcounter); + + /** + * With this method, the packet data pointer can be redirected to another + * location. + * + * This call overwrites the parent's setData method to set both its + * @c tc_data pointer and the parent's @c data pointer. + * + * @param p_data A pointer to another PUS Telemetry Packet. + */ + void setData( const uint8_t* pData ); + + /** + * In case data was filled manually (almost never the case). + * @param size Size of source data (without CRC and data filed header!). + */ + void setSourceDataSize(uint16_t size); + + /** + * Checks if a time stamper is available and tries to set it if not. + * @return Returns false if setting failed. + */ + bool checkAndSetStamper(); +}; + +#endif /* FSFW_TMTCPACKET_PUS_TMPACKETPUSA_H_ */ diff --git a/tmtcpacket/pus/TmPacketPusC.cpp b/tmtcpacket/pus/TmPacketPusC.cpp new file mode 100644 index 00000000..99f50825 --- /dev/null +++ b/tmtcpacket/pus/TmPacketPusC.cpp @@ -0,0 +1,2 @@ +#include "TmPacketPusC.h" + diff --git a/tmtcpacket/pus/TmPacketPusC.h b/tmtcpacket/pus/TmPacketPusC.h new file mode 100644 index 00000000..fec435c4 --- /dev/null +++ b/tmtcpacket/pus/TmPacketPusC.h @@ -0,0 +1,8 @@ +#ifndef FSFW_TMTCPACKET_PUS_TMPACKETPUSC_H_ +#define FSFW_TMTCPACKET_PUS_TMPACKETPUSC_H_ + + + + + +#endif /* FSFW_TMTCPACKET_PUS_TMPACKETPUSC_H_ */ diff --git a/tmtcpacket/pus/TmPacketStored.cpp b/tmtcpacket/pus/TmPacketStored.cpp index 0fd2a4a0..d69e2419 100644 --- a/tmtcpacket/pus/TmPacketStored.cpp +++ b/tmtcpacket/pus/TmPacketStored.cpp @@ -10,21 +10,21 @@ StorageManagerIF *TmPacketStored::store = nullptr; InternalErrorReporterIF *TmPacketStored::internalErrorReporter = nullptr; TmPacketStored::TmPacketStored(store_address_t setAddress) : - TmPacketBase(nullptr), storeAddress(setAddress) { + TmPacketPusA(nullptr), storeAddress(setAddress) { setStoreAddress(storeAddress); } TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service, uint8_t subservice, uint8_t packetSubcounter, const uint8_t *data, uint32_t size, const uint8_t *headerData, uint32_t headerSize) : - TmPacketBase(NULL) { + TmPacketPusA(nullptr) { storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; if (not checkAndSetStore()) { return; } uint8_t *pData = nullptr; ReturnValue_t returnValue = store->getFreeElement(&storeAddress, - (TmPacketBase::TM_PACKET_MIN_SIZE + size + headerSize), &pData); + (getPacketMinimumSize() + size + headerSize), &pData); if (returnValue != store->RETURN_OK) { checkAndReportLostTm(); @@ -41,7 +41,7 @@ TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service, TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service, uint8_t subservice, uint8_t packetSubcounter, SerializeIF *content, SerializeIF *header) : - TmPacketBase(NULL) { + TmPacketPusA(nullptr) { storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; if (not checkAndSetStore()) { return; @@ -55,7 +55,7 @@ TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service, } uint8_t *p_data = NULL; ReturnValue_t returnValue = store->getFreeElement(&storeAddress, - (TmPacketBase::TM_PACKET_MIN_SIZE + sourceDataSize), &p_data); + (getPacketMinimumSize() + sourceDataSize), &p_data); if (returnValue != store->RETURN_OK) { checkAndReportLostTm(); } diff --git a/tmtcpacket/pus/TmPacketStored.h b/tmtcpacket/pus/TmPacketStored.h index b231407d..1cc8e6ba 100644 --- a/tmtcpacket/pus/TmPacketStored.h +++ b/tmtcpacket/pus/TmPacketStored.h @@ -2,7 +2,9 @@ #define FSFW_TMTCPACKET_PUS_TMPACKETSTORED_H_ #include "TmPacketBase.h" +#include +#include "../../tmtcpacket/pus/TmPacketPusA.h" #include "../../serialize/SerializeIF.h" #include "../../storagemanager/StorageManagerIF.h" #include "../../internalError/InternalErrorReporterIF.h" @@ -18,7 +20,7 @@ * packets in a store with the help of a storeAddress. * @ingroup tmtcpackets */ -class TmPacketStored : public TmPacketBase { +class TmPacketStored : public TmPacketPusA { public: /** * This is a default constructor which does not set the data pointer. From ae1dab1fce187d18d4a37cf416dcbc0cbfcfb491 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Apr 2021 21:53:08 +0200 Subject: [PATCH 159/230] sth broke --- pus/Service17Test.cpp | 4 +- pus/Service1TelecommandVerification.cpp | 4 +- pus/Service5EventReporting.cpp | 2 +- tmtcpacket/pus/CMakeLists.txt | 1 + tmtcpacket/pus/TmPacketBase.h | 2 +- tmtcpacket/pus/TmPacketPusA.cpp | 22 +---- tmtcpacket/pus/TmPacketPusA.h | 11 ++- tmtcpacket/pus/TmPacketStored.cpp | 96 ++++---------------- tmtcpacket/pus/TmPacketStored.h | 50 +++------- tmtcpacket/pus/TmPacketStoredBase.cpp | 94 +++++++++++++++++++ tmtcpacket/pus/TmPacketStoredBase.h | 89 ++++++++++++++++++ tmtcservices/CommandingServiceBase.cpp | 6 +- unittest/user/unittest/core/CatchFactory.cpp | 2 +- 13 files changed, 233 insertions(+), 150 deletions(-) create mode 100644 tmtcpacket/pus/TmPacketStoredBase.cpp create mode 100644 tmtcpacket/pus/TmPacketStoredBase.h diff --git a/pus/Service17Test.cpp b/pus/Service17Test.cpp index 85a32e1e..28370171 100644 --- a/pus/Service17Test.cpp +++ b/pus/Service17Test.cpp @@ -17,14 +17,14 @@ Service17Test::~Service17Test() { ReturnValue_t Service17Test::handleRequest(uint8_t subservice) { switch(subservice) { case Subservice::CONNECTION_TEST: { - TmPacketStored connectionPacket(apid, serviceId, + TmPacketStoredPusA connectionPacket(apid, serviceId, Subservice::CONNECTION_TEST_REPORT, packetSubCounter++); connectionPacket.sendPacket(requestQueue->getDefaultDestination(), requestQueue->getId()); return HasReturnvaluesIF::RETURN_OK; } case Subservice::EVENT_TRIGGER_TEST: { - TmPacketStored connectionPacket(apid, serviceId, + TmPacketStoredPusA connectionPacket(apid, serviceId, Subservice::CONNECTION_TEST_REPORT, packetSubCounter++); connectionPacket.sendPacket(requestQueue->getDefaultDestination(), requestQueue->getId()); diff --git a/pus/Service1TelecommandVerification.cpp b/pus/Service1TelecommandVerification.cpp index 7ce75478..5e9d0e42 100644 --- a/pus/Service1TelecommandVerification.cpp +++ b/pus/Service1TelecommandVerification.cpp @@ -68,7 +68,7 @@ ReturnValue_t Service1TelecommandVerification::generateFailureReport( message->getTcSequenceControl(), message->getStep(), message->getErrorCode(), message->getParameter1(), message->getParameter2()); - TmPacketStored tmPacket(apid, serviceId, message->getReportId(), + TmPacketStoredPusA tmPacket(apid, serviceId, message->getReportId(), packetSubCounter++, &report); ReturnValue_t result = tmPacket.sendPacket(tmQueue->getDefaultDestination(), tmQueue->getId()); @@ -79,7 +79,7 @@ ReturnValue_t Service1TelecommandVerification::generateSuccessReport( PusVerificationMessage *message) { SuccessReport report(message->getReportId(),message->getTcPacketId(), message->getTcSequenceControl(),message->getStep()); - TmPacketStored tmPacket(apid, serviceId, message->getReportId(), + TmPacketStoredPusA tmPacket(apid, serviceId, message->getReportId(), packetSubCounter++, &report); ReturnValue_t result = tmPacket.sendPacket(tmQueue->getDefaultDestination(), tmQueue->getId()); diff --git a/pus/Service5EventReporting.cpp b/pus/Service5EventReporting.cpp index 965a27ad..8632f8d7 100644 --- a/pus/Service5EventReporting.cpp +++ b/pus/Service5EventReporting.cpp @@ -52,7 +52,7 @@ ReturnValue_t Service5EventReporting::generateEventReport( { EventReport report(message.getEventId(),message.getReporter(), message.getParameter1(),message.getParameter2()); - TmPacketStored tmPacket(PusServiceBase::apid, PusServiceBase::serviceId, + TmPacketStoredPusA tmPacket(PusServiceBase::apid, PusServiceBase::serviceId, message.getSeverity(), packetSubCounter++, &report); ReturnValue_t result = tmPacket.sendPacket( requestQueue->getDefaultDestination(),requestQueue->getId()); diff --git a/tmtcpacket/pus/CMakeLists.txt b/tmtcpacket/pus/CMakeLists.txt index 1fdd9dd8..a2ce20e2 100644 --- a/tmtcpacket/pus/CMakeLists.txt +++ b/tmtcpacket/pus/CMakeLists.txt @@ -7,4 +7,5 @@ target_sources(${LIB_FSFW_NAME} TmPacketStored.cpp TmPacketPusA.cpp TmPacketPusC.cpp + TmPacketStoredBase.cpp ) diff --git a/tmtcpacket/pus/TmPacketBase.h b/tmtcpacket/pus/TmPacketBase.h index 72cdbb69..09a6ca54 100644 --- a/tmtcpacket/pus/TmPacketBase.h +++ b/tmtcpacket/pus/TmPacketBase.h @@ -31,7 +31,7 @@ public: static const uint32_t MISSION_TM_PACKET_MAX_SIZE = 2048; //! First byte of secondary header for PUS-A packets. //! TODO: Maybe also support PUS-C via config? - static const uint8_t VERSION_NUMBER_BYTE_PUS_A = 0b00010000; + static const uint8_t VERSION_NUMBER_BYTE = 0b00010000; /** * This is the default constructor. diff --git a/tmtcpacket/pus/TmPacketPusA.cpp b/tmtcpacket/pus/TmPacketPusA.cpp index 630aac0f..841f7e40 100644 --- a/tmtcpacket/pus/TmPacketPusA.cpp +++ b/tmtcpacket/pus/TmPacketPusA.cpp @@ -11,7 +11,7 @@ TmPacketPusA::TmPacketPusA(uint8_t* setData) : TmPacketBase(setData) { - tmData = reinterpret_cast(setData); + tmData = reinterpret_cast(setData); } TmPacketPusA::~TmPacketPusA() { @@ -35,23 +35,9 @@ uint16_t TmPacketPusA::getSourceDataSize() { - CRC_SIZE + 1; } -//uint16_t TmPacketPusA::getErrorControl() { -// uint32_t size = getSourceDataSize() + CRC_SIZE; -// uint8_t* p_to_buffer = &tmData->data; -// return (p_to_buffer[size - 2] << 8) + p_to_buffer[size - 1]; -//} -// -//void TmPacketPusA::setErrorControl() { -// uint32_t full_size = getFullSize(); -// uint16_t crc = CRC::crc16ccitt(getWholeData(), full_size - CRC_SIZE); -// uint32_t size = getSourceDataSize(); -// getSourceData()[size] = (crc & 0XFF00) >> 8; // CRCH -// getSourceData()[size + 1] = (crc) & 0X00FF; // CRCL -//} - void TmPacketPusA::setData(const uint8_t* p_Data) { SpacePacketBase::setData(p_Data); - tmData = (TmPacketPointer*) p_Data; + tmData = (TmPacketPointerPusA*) p_Data; } @@ -60,7 +46,7 @@ size_t TmPacketPusA::getPacketMinimumSize() const { } uint16_t TmPacketPusA::getDataFieldSize() { - return sizeof(PUSTmDataFieldHeader); + return sizeof(PUSTmDataFieldHeaderPusA); } bool TmPacketPusA::checkAndSetStamper() { @@ -113,7 +99,7 @@ void TmPacketPusA::initializeTmPacket(uint16_t apid, uint8_t service, } void TmPacketPusA::setSourceDataSize(uint16_t size) { - setPacketDataLength(size + sizeof(PUSTmDataFieldHeader) + CRC_SIZE - 1); + setPacketDataLength(size + sizeof(PUSTmDataFieldHeaderPusA) + CRC_SIZE - 1); } size_t TmPacketPusA::getTimestampSize() const { diff --git a/tmtcpacket/pus/TmPacketPusA.h b/tmtcpacket/pus/TmPacketPusA.h index 4db634c2..21bdfd95 100644 --- a/tmtcpacket/pus/TmPacketPusA.h +++ b/tmtcpacket/pus/TmPacketPusA.h @@ -18,7 +18,7 @@ void setStaticFrameworkObjectIds(); * for a time tag. * @ingroup tmtcpackets */ -struct PUSTmDataFieldHeader { +struct PUSTmDataFieldHeaderPusA { uint8_t version_type_ack; uint8_t service_type; uint8_t service_subtype; @@ -32,9 +32,9 @@ struct PUSTmDataFieldHeader { * accessed via a pointer. * @ingroup tmtcpackets */ -struct TmPacketPointer { +struct TmPacketPointerPusA { CCSDSPrimaryHeader primary; - PUSTmDataFieldHeader data_field; + PUSTmDataFieldHeaderPusA data_field; uint8_t data; }; @@ -49,7 +49,7 @@ public: * This constant defines the minimum size of a valid PUS Telemetry Packet. */ static const uint32_t TM_PACKET_MIN_SIZE = (sizeof(CCSDSPrimaryHeader) + - sizeof(PUSTmDataFieldHeader) + 2); + sizeof(PUSTmDataFieldHeaderPusA) + 2); //! Maximum size of a TM Packet in this mission. //! TODO: Make this dependant on a config variable. static const uint32_t MISSION_TM_PACKET_MAX_SIZE = 2048; @@ -75,6 +75,7 @@ public: uint8_t* getSourceData() override; uint16_t getSourceDataSize() override; uint16_t getDataFieldSize() override; + /** * Interprets the "time"-field in the secondary header and returns it in * timeval format. @@ -97,7 +98,7 @@ protected: * * To be hardware-safe, all elements are of byte size. */ - TmPacketPointer* tmData; + TmPacketPointerPusA* tmData; /** * Initializes the Tm Packet header. diff --git a/tmtcpacket/pus/TmPacketStored.cpp b/tmtcpacket/pus/TmPacketStored.cpp index d69e2419..4a33c504 100644 --- a/tmtcpacket/pus/TmPacketStored.cpp +++ b/tmtcpacket/pus/TmPacketStored.cpp @@ -6,20 +6,19 @@ #include -StorageManagerIF *TmPacketStored::store = nullptr; -InternalErrorReporterIF *TmPacketStored::internalErrorReporter = nullptr; +StorageManagerIF *TmPacketStoredPusA::store = nullptr; +InternalErrorReporterIF *TmPacketStoredPusA::internalErrorReporter = nullptr; -TmPacketStored::TmPacketStored(store_address_t setAddress) : - TmPacketPusA(nullptr), storeAddress(setAddress) { - setStoreAddress(storeAddress); +TmPacketStoredPusA::TmPacketStoredPusA(store_address_t setAddress) : + TmPacketStoredBase(setAddress), TmPacketPusA(nullptr){ } -TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service, +TmPacketStoredPusA::TmPacketStoredPusA(uint16_t apid, uint8_t service, uint8_t subservice, uint8_t packetSubcounter, const uint8_t *data, uint32_t size, const uint8_t *headerData, uint32_t headerSize) : TmPacketPusA(nullptr) { storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; - if (not checkAndSetStore()) { + if (not TmPacketStoredBase::checkAndSetStore()) { return; } uint8_t *pData = nullptr; @@ -27,7 +26,7 @@ TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service, (getPacketMinimumSize() + size + headerSize), &pData); if (returnValue != store->RETURN_OK) { - checkAndReportLostTm(); + TmPacketStoredBase::checkAndReportLostTm(); return; } setData(pData); @@ -35,15 +34,15 @@ TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service, memcpy(getSourceData(), headerData, headerSize); memcpy(getSourceData() + headerSize, data, size); setPacketDataLength( - size + headerSize + sizeof(PUSTmDataFieldHeader) + CRC_SIZE - 1); + size + headerSize + sizeof(PUSTmDataFieldHeaderPusA) + CRC_SIZE - 1); } -TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service, +TmPacketStoredPusA::TmPacketStoredPusA(uint16_t apid, uint8_t service, uint8_t subservice, uint8_t packetSubcounter, SerializeIF *content, SerializeIF *header) : TmPacketPusA(nullptr) { storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; - if (not checkAndSetStore()) { + if (not TmPacketStoredBase::checkAndSetStore()) { return; } size_t sourceDataSize = 0; @@ -57,7 +56,7 @@ TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service, ReturnValue_t returnValue = store->getFreeElement(&storeAddress, (getPacketMinimumSize() + sourceDataSize), &p_data); if (returnValue != store->RETURN_OK) { - checkAndReportLostTm(); + TmPacketStoredBase::checkAndReportLostTm(); } setData(p_data); initializeTmPacket(apid, service, subservice, packetSubcounter); @@ -72,76 +71,13 @@ TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service, SerializeIF::Endianness::BIG); } setPacketDataLength( - sourceDataSize + sizeof(PUSTmDataFieldHeader) + CRC_SIZE - 1); + sourceDataSize + sizeof(PUSTmDataFieldHeaderPusA) + CRC_SIZE - 1); } -store_address_t TmPacketStored::getStoreAddress() { - return storeAddress; +uint8_t* TmPacketStoredPusA::getAllTmData() { + return getWholeData(); } -void TmPacketStored::deletePacket() { - store->deleteData(storeAddress); - storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; - setData(nullptr); -} - -void TmPacketStored::setStoreAddress(store_address_t setAddress) { - storeAddress = setAddress; - const uint8_t* tempData = nullptr; - size_t tempSize; - if (not checkAndSetStore()) { - return; - } - ReturnValue_t status = store->getData(storeAddress, &tempData, &tempSize); - if (status == StorageManagerIF::RETURN_OK) { - setData(tempData); - } else { - setData(nullptr); - storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; - } -} - -bool TmPacketStored::checkAndSetStore() { - if (store == nullptr) { - store = objectManager->get(objects::TM_STORE); - if (store == nullptr) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TmPacketStored::TmPacketStored: TM Store not found!" - << std::endl; -#endif - return false; - } - } - return true; -} - -ReturnValue_t TmPacketStored::sendPacket(MessageQueueId_t destination, - MessageQueueId_t sentFrom, bool doErrorReporting) { - if (getWholeData() == nullptr) { - //SHOULDDO: More decent code. - return HasReturnvaluesIF::RETURN_FAILED; - } - TmTcMessage tmMessage(getStoreAddress()); - ReturnValue_t result = MessageQueueSenderIF::sendMessage(destination, - &tmMessage, sentFrom); - if (result != HasReturnvaluesIF::RETURN_OK) { - deletePacket(); - if (doErrorReporting) { - checkAndReportLostTm(); - } - return result; - } - //SHOULDDO: In many cases, some counter is incremented for successfully sent packets. The check is often not done, but just incremented. - return HasReturnvaluesIF::RETURN_OK; - -} - -void TmPacketStored::checkAndReportLostTm() { - if (internalErrorReporter == nullptr) { - internalErrorReporter = objectManager->get( - objects::INTERNAL_ERROR_REPORTER); - } - if (internalErrorReporter != nullptr) { - internalErrorReporter->lostTm(); - } +void TmPacketStoredPusA::setDataPointer(const uint8_t *newPointer) { + setData(newPointer); } diff --git a/tmtcpacket/pus/TmPacketStored.h b/tmtcpacket/pus/TmPacketStored.h index 1cc8e6ba..17b81e9f 100644 --- a/tmtcpacket/pus/TmPacketStored.h +++ b/tmtcpacket/pus/TmPacketStored.h @@ -1,7 +1,8 @@ -#ifndef FSFW_TMTCPACKET_PUS_TMPACKETSTORED_H_ -#define FSFW_TMTCPACKET_PUS_TMPACKETSTORED_H_ +#ifndef FSFW_TMTCPACKET_PUS_TMPACKETSTORED_PUSA_H_ +#define FSFW_TMTCPACKET_PUS_TMPACKETSTORED_PUSA_H_ #include "TmPacketBase.h" +#include "TmPacketStoredBase.h" #include #include "../../tmtcpacket/pus/TmPacketPusA.h" @@ -20,13 +21,15 @@ * packets in a store with the help of a storeAddress. * @ingroup tmtcpackets */ -class TmPacketStored : public TmPacketPusA { +class TmPacketStoredPusA : + public TmPacketStoredBase, + public TmPacketPusA { public: /** * This is a default constructor which does not set the data pointer. * However, it does try to set the packet store. */ - TmPacketStored( store_address_t setAddress ); + TmPacketStoredPusA( store_address_t setAddress ); /** * With this constructor, new space is allocated in the packet store and * a new PUS Telemetry Packet is created there. @@ -47,7 +50,7 @@ public: * will be copied in front of data * @param headerSize The size of the headerDataF */ - TmPacketStored( uint16_t apid, uint8_t service, uint8_t subservice, + TmPacketStoredPusA( uint16_t apid, uint8_t service, uint8_t subservice, uint8_t packet_counter = 0, const uint8_t* data = nullptr, uint32_t size = 0, const uint8_t* headerData = nullptr, uint32_t headerSize = 0); @@ -55,30 +58,13 @@ public: * Another ctor to directly pass structured content and header data to the * packet to avoid additional buffers. */ - TmPacketStored( uint16_t apid, uint8_t service, uint8_t subservice, + TmPacketStoredPusA( uint16_t apid, uint8_t service, uint8_t subservice, uint8_t packet_counter, SerializeIF* content, SerializeIF* header = nullptr); - /** - * This is a getter for the current store address of the packet. - * @return The current store address. The (raw) value is - * @c StorageManagerIF::INVALID_ADDRESS if - * the packet is not linked. - */ - store_address_t getStoreAddress(); - /** - * With this call, the packet is deleted. - * It removes itself from the store and sets its data pointer to NULL. - */ - void deletePacket(); - /** - * With this call, a packet can be linked to another store. This is useful - * if the packet is a class member and used for more than one packet. - * @param setAddress The new packet id to link to. - */ - void setStoreAddress( store_address_t setAddress ); - ReturnValue_t sendPacket( MessageQueueId_t destination, - MessageQueueId_t sentFrom, bool doErrorReporting = true ); + uint8_t* getAllTmData() override; + void setDataPointer(const uint8_t* newPointer) override; + private: /** * This is a pointer to the store all instances of the class use. @@ -94,17 +80,7 @@ private: * The address where the packet data of the object instance is stored. */ store_address_t storeAddress; - /** - * A helper method to check if a store is assigned to the class. - * If not, the method tries to retrieve the store from the global - * ObjectManager. - * @return @li @c true if the store is linked or could be created. - * @li @c false otherwise. - */ - bool checkAndSetStore(); - - void checkAndReportLostTm(); }; -#endif /* FSFW_TMTCPACKET_PUS_TMPACKETSTORED_H_ */ +#endif /* FSFW_TMTCPACKET_PUS_TMPACKETSTORED_PUSA_H_ */ diff --git a/tmtcpacket/pus/TmPacketStoredBase.cpp b/tmtcpacket/pus/TmPacketStoredBase.cpp new file mode 100644 index 00000000..3ab31a80 --- /dev/null +++ b/tmtcpacket/pus/TmPacketStoredBase.cpp @@ -0,0 +1,94 @@ +#include "TmPacketStoredBase.h" + +#include "../../objectmanager/ObjectManagerIF.h" +#include "../../serviceinterface/ServiceInterfaceStream.h" +#include "../../tmtcservices/TmTcMessage.h" + +#include + +StorageManagerIF *TmPacketStoredBase::store = nullptr; +InternalErrorReporterIF *TmPacketStoredBase::internalErrorReporter = nullptr; + +TmPacketStoredBase::TmPacketStoredBase(store_address_t setAddress): storeAddress(setAddress) { + setStoreAddress(storeAddress); +} + +TmPacketStoredBase::TmPacketStoredBase() { +} + + +TmPacketStoredBase::~TmPacketStoredBase() { +} + +store_address_t TmPacketStoredBase::getStoreAddress() { + return storeAddress; +} + +void TmPacketStoredBase::deletePacket() { + store->deleteData(storeAddress); + storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; + setDataPointer(nullptr); +} + +void TmPacketStoredBase::setStoreAddress(store_address_t setAddress) { + storeAddress = setAddress; + const uint8_t* tempData = nullptr; + size_t tempSize; + if (not checkAndSetStore()) { + return; + } + ReturnValue_t status = store->getData(storeAddress, &tempData, &tempSize); + if (status == StorageManagerIF::RETURN_OK) { + setDataPointer(tempData); + } else { + setDataPointer(nullptr); + storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; + } +} + +bool TmPacketStoredBase::checkAndSetStore() { + if (store == nullptr) { + store = objectManager->get(objects::TM_STORE); + if (store == nullptr) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "TmPacketStored::TmPacketStored: TM Store not found!" + << std::endl; +#endif + return false; + } + } + return true; +} + +ReturnValue_t TmPacketStoredBase::sendPacket(MessageQueueId_t destination, + MessageQueueId_t sentFrom, bool doErrorReporting) { + if (getAllTmData() == nullptr) { + //SHOULDDO: More decent code. + return HasReturnvaluesIF::RETURN_FAILED; + } + TmTcMessage tmMessage(getStoreAddress()); + ReturnValue_t result = MessageQueueSenderIF::sendMessage(destination, + &tmMessage, sentFrom); + if (result != HasReturnvaluesIF::RETURN_OK) { + deletePacket(); + if (doErrorReporting) { + checkAndReportLostTm(); + } + return result; + } + //SHOULDDO: In many cases, some counter is incremented for successfully sent packets. The check is often not done, but just incremented. + return HasReturnvaluesIF::RETURN_OK; + +} + +void TmPacketStoredBase::checkAndReportLostTm() { + if (internalErrorReporter == nullptr) { + internalErrorReporter = objectManager->get( + objects::INTERNAL_ERROR_REPORTER); + } + if (internalErrorReporter != nullptr) { + internalErrorReporter->lostTm(); + } +} + + diff --git a/tmtcpacket/pus/TmPacketStoredBase.h b/tmtcpacket/pus/TmPacketStoredBase.h new file mode 100644 index 00000000..58a231a5 --- /dev/null +++ b/tmtcpacket/pus/TmPacketStoredBase.h @@ -0,0 +1,89 @@ +#ifndef FSFW_TMTCPACKET_PUS_TMPACKETSTOREDBASE_H_ +#define FSFW_TMTCPACKET_PUS_TMPACKETSTOREDBASE_H_ + +#include "TmPacketBase.h" +#include "TmPacketStoredBase.h" +#include + +#include "../../tmtcpacket/pus/TmPacketPusA.h" +#include "../../serialize/SerializeIF.h" +#include "../../storagemanager/StorageManagerIF.h" +#include "../../internalError/InternalErrorReporterIF.h" +#include "../../ipc/MessageQueueSenderIF.h" + +/** + * This class generates a ECSS PUS Telemetry packet within a given + * intermediate storage. + * As most packets are passed between tasks with the help of a storage + * anyway, it seems logical to create a Packet-In-Storage access class + * which saves the user almost all storage handling operation. + * Packets can both be newly created with the class and be "linked" to + * packets in a store with the help of a storeAddress. + * @ingroup tmtcpackets + */ +class TmPacketStoredBase { +public: + /** + * This is a default constructor which does not set the data pointer. + * However, it does try to set the packet store. + */ + TmPacketStoredBase( store_address_t setAddress ); + TmPacketStoredBase(); + + virtual ~TmPacketStoredBase(); + + virtual uint8_t* getAllTmData() = 0; + virtual void setDataPointer(const uint8_t* newPointer) = 0; + + /** + * This is a getter for the current store address of the packet. + * @return The current store address. The (raw) value is + * @c StorageManagerIF::INVALID_ADDRESS if + * the packet is not linked. + */ + store_address_t getStoreAddress(); + /** + * With this call, the packet is deleted. + * It removes itself from the store and sets its data pointer to NULL. + */ + void deletePacket(); + /** + * With this call, a packet can be linked to another store. This is useful + * if the packet is a class member and used for more than one packet. + * @param setAddress The new packet id to link to. + */ + void setStoreAddress( store_address_t setAddress ); + + ReturnValue_t sendPacket( MessageQueueId_t destination, + MessageQueueId_t sentFrom, bool doErrorReporting = true ); + +protected: + /** + * This is a pointer to the store all instances of the class use. + * If the store is not yet set (i.e. @c store is NULL), every constructor + * call tries to set it and throws an error message in case of failures. + * The default store is objects::TM_STORE. + */ + static StorageManagerIF* store; + + static InternalErrorReporterIF *internalErrorReporter; + + /** + * The address where the packet data of the object instance is stored. + */ + store_address_t storeAddress; + /** + * A helper method to check if a store is assigned to the class. + * If not, the method tries to retrieve the store from the global + * ObjectManager. + * @return @li @c true if the store is linked or could be created. + * @li @c false otherwise. + */ + bool checkAndSetStore(); + + void checkAndReportLostTm(); +}; + + +#endif /* FSFW_TMTCPACKET_PUS_TMPACKETSTOREDBASE_H_ */ + diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index 8b6f7a09..bbcdcc80 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -293,7 +293,7 @@ void CommandingServiceBase::handleRequestQueue() { ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice, const uint8_t* data, size_t dataLen, const uint8_t* headerData, size_t headerSize) { - TmPacketStored tmPacketStored(this->apid, this->service, subservice, + TmPacketStoredPusA tmPacketStored(this->apid, this->service, subservice, this->tmPacketCounter, data, dataLen, headerData, headerSize); ReturnValue_t result = tmPacketStored.sendPacket( requestQueue->getDefaultDestination(), requestQueue->getId()); @@ -311,7 +311,7 @@ ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice, size_t size = 0; SerializeAdapter::serialize(&objectId, &pBuffer, &size, sizeof(object_id_t), SerializeIF::Endianness::BIG); - TmPacketStored tmPacketStored(this->apid, this->service, subservice, + TmPacketStoredPusA tmPacketStored(this->apid, this->service, subservice, this->tmPacketCounter, data, dataLen, buffer, size); ReturnValue_t result = tmPacketStored.sendPacket( requestQueue->getDefaultDestination(), requestQueue->getId()); @@ -324,7 +324,7 @@ ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice, ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice, SerializeIF* content, SerializeIF* header) { - TmPacketStored tmPacketStored(this->apid, this->service, subservice, + TmPacketStoredPusA tmPacketStored(this->apid, this->service, subservice, this->tmPacketCounter, content, header); ReturnValue_t result = tmPacketStored.sendPacket( requestQueue->getDefaultDestination(), requestQueue->getId()); diff --git a/unittest/user/unittest/core/CatchFactory.cpp b/unittest/user/unittest/core/CatchFactory.cpp index eabaa21d..2c4eaf24 100644 --- a/unittest/user/unittest/core/CatchFactory.cpp +++ b/unittest/user/unittest/core/CatchFactory.cpp @@ -74,7 +74,7 @@ void Factory::setStaticFrameworkObjectIds() { DeviceHandlerFailureIsolation::powerConfirmationId = objects::NO_OBJECT; - TmPacketStored::timeStamperId = objects::NO_OBJECT; + TmPacketStoredPusA::timeStamperId = objects::NO_OBJECT; } From 4faa5b0685fc894b643979d54bdf5d8736257e75 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Apr 2021 22:02:16 +0200 Subject: [PATCH 160/230] fixes --- tmtcpacket/pus/TmPacketStored.cpp | 5 +---- tmtcpacket/pus/TmPacketStored.h | 9 --------- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/tmtcpacket/pus/TmPacketStored.cpp b/tmtcpacket/pus/TmPacketStored.cpp index 4a33c504..b09f505d 100644 --- a/tmtcpacket/pus/TmPacketStored.cpp +++ b/tmtcpacket/pus/TmPacketStored.cpp @@ -6,9 +6,6 @@ #include -StorageManagerIF *TmPacketStoredPusA::store = nullptr; -InternalErrorReporterIF *TmPacketStoredPusA::internalErrorReporter = nullptr; - TmPacketStoredPusA::TmPacketStoredPusA(store_address_t setAddress) : TmPacketStoredBase(setAddress), TmPacketPusA(nullptr){ } @@ -42,7 +39,7 @@ TmPacketStoredPusA::TmPacketStoredPusA(uint16_t apid, uint8_t service, SerializeIF *header) : TmPacketPusA(nullptr) { storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; - if (not TmPacketStoredBase::checkAndSetStore()) { + if (not TmPacketStoredBase::checkAndSetStore()) { return; } size_t sourceDataSize = 0; diff --git a/tmtcpacket/pus/TmPacketStored.h b/tmtcpacket/pus/TmPacketStored.h index 17b81e9f..f1722f4e 100644 --- a/tmtcpacket/pus/TmPacketStored.h +++ b/tmtcpacket/pus/TmPacketStored.h @@ -66,15 +66,6 @@ public: void setDataPointer(const uint8_t* newPointer) override; private: - /** - * This is a pointer to the store all instances of the class use. - * If the store is not yet set (i.e. @c store is NULL), every constructor - * call tries to set it and throws an error message in case of failures. - * The default store is objects::TM_STORE. - */ - static StorageManagerIF* store; - - static InternalErrorReporterIF *internalErrorReporter; /** * The address where the packet data of the object instance is stored. From 07f121631609209a828b6f1df5bdc602bec72b68 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Apr 2021 22:12:18 +0200 Subject: [PATCH 161/230] error found --- tmtcpacket/pus/TmPacketStored.h | 6 ------ tmtcpacket/pus/TmPacketStoredBase.h | 6 +++--- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/tmtcpacket/pus/TmPacketStored.h b/tmtcpacket/pus/TmPacketStored.h index f1722f4e..aeeba275 100644 --- a/tmtcpacket/pus/TmPacketStored.h +++ b/tmtcpacket/pus/TmPacketStored.h @@ -65,12 +65,6 @@ public: uint8_t* getAllTmData() override; void setDataPointer(const uint8_t* newPointer) override; -private: - - /** - * The address where the packet data of the object instance is stored. - */ - store_address_t storeAddress; }; diff --git a/tmtcpacket/pus/TmPacketStoredBase.h b/tmtcpacket/pus/TmPacketStoredBase.h index 58a231a5..dd7e31eb 100644 --- a/tmtcpacket/pus/TmPacketStoredBase.h +++ b/tmtcpacket/pus/TmPacketStoredBase.h @@ -52,10 +52,10 @@ public: * if the packet is a class member and used for more than one packet. * @param setAddress The new packet id to link to. */ - void setStoreAddress( store_address_t setAddress ); + void setStoreAddress(store_address_t setAddress); - ReturnValue_t sendPacket( MessageQueueId_t destination, - MessageQueueId_t sentFrom, bool doErrorReporting = true ); + ReturnValue_t sendPacket(MessageQueueId_t destination, MessageQueueId_t sentFrom, + bool doErrorReporting = true); protected: /** From 9a2fbefc9ff5c9fbdd64fa4dbe7eaef293704b05 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Apr 2021 22:24:11 +0200 Subject: [PATCH 162/230] refactoring continued --- pus/Service17Test.cpp | 2 +- pus/Service1TelecommandVerification.cpp | 2 +- pus/Service5EventReporting.cpp | 2 +- tmtcpacket/pus/CMakeLists.txt | 2 +- tmtcpacket/pus/TmPacketBase.cpp | 8 +- tmtcpacket/pus/TmPacketStored.h | 73 ++----------------- ...acketStored.cpp => TmPacketStoredPusA.cpp} | 2 +- tmtcpacket/pus/TmPacketStoredPusA.h | 71 ++++++++++++++++++ tmtcservices/CommandingServiceBase.cpp | 2 +- 9 files changed, 89 insertions(+), 75 deletions(-) rename tmtcpacket/pus/{TmPacketStored.cpp => TmPacketStoredPusA.cpp} (98%) create mode 100644 tmtcpacket/pus/TmPacketStoredPusA.h diff --git a/pus/Service17Test.cpp b/pus/Service17Test.cpp index 28370171..cdd8817c 100644 --- a/pus/Service17Test.cpp +++ b/pus/Service17Test.cpp @@ -2,7 +2,7 @@ #include "../serviceinterface/ServiceInterfaceStream.h" #include "../objectmanager/SystemObject.h" -#include "../tmtcpacket/pus/TmPacketStored.h" +#include "../tmtcpacket/pus/TmPacketStoredPusA.h" Service17Test::Service17Test(object_id_t objectId, diff --git a/pus/Service1TelecommandVerification.cpp b/pus/Service1TelecommandVerification.cpp index 5e9d0e42..358d1faa 100644 --- a/pus/Service1TelecommandVerification.cpp +++ b/pus/Service1TelecommandVerification.cpp @@ -3,7 +3,7 @@ #include "../ipc/QueueFactory.h" #include "../tmtcservices/PusVerificationReport.h" -#include "../tmtcpacket/pus/TmPacketStored.h" +#include "../tmtcpacket/pus/TmPacketStoredPusA.h" #include "../serviceinterface/ServiceInterfaceStream.h" #include "../tmtcservices/AcceptsTelemetryIF.h" diff --git a/pus/Service5EventReporting.cpp b/pus/Service5EventReporting.cpp index 8632f8d7..f6281fe9 100644 --- a/pus/Service5EventReporting.cpp +++ b/pus/Service5EventReporting.cpp @@ -4,7 +4,7 @@ #include "../serviceinterface/ServiceInterfaceStream.h" #include "../events/EventManagerIF.h" #include "../ipc/QueueFactory.h" -#include "../tmtcpacket/pus/TmPacketStored.h" +#include "../tmtcpacket/pus/TmPacketStoredPusA.h" Service5EventReporting::Service5EventReporting(object_id_t objectId, diff --git a/tmtcpacket/pus/CMakeLists.txt b/tmtcpacket/pus/CMakeLists.txt index a2ce20e2..747ed070 100644 --- a/tmtcpacket/pus/CMakeLists.txt +++ b/tmtcpacket/pus/CMakeLists.txt @@ -4,7 +4,7 @@ target_sources(${LIB_FSFW_NAME} TcPacketStored.cpp TmPacketBase.cpp TmPacketMinimal.cpp - TmPacketStored.cpp + TmPacketStoredPusA.cpp TmPacketPusA.cpp TmPacketPusC.cpp TmPacketStoredBase.cpp diff --git a/tmtcpacket/pus/TmPacketBase.cpp b/tmtcpacket/pus/TmPacketBase.cpp index 10f37b00..2dfef258 100644 --- a/tmtcpacket/pus/TmPacketBase.cpp +++ b/tmtcpacket/pus/TmPacketBase.cpp @@ -3,13 +3,13 @@ #include "../../globalfunctions/CRC.h" #include "../../globalfunctions/arrayprinter.h" #include "../../objectmanager/ObjectManagerIF.h" -#include "../../serviceinterface/ServiceInterfaceStream.h" +#include "../../serviceinterface/ServiceInterface.h" #include "../../timemanager/CCSDSTime.h" #include TimeStamperIF* TmPacketBase::timeStamper = nullptr; -object_id_t TmPacketBase::timeStamperId = 0; +object_id_t TmPacketBase::timeStamperId = objects::NO_OBJECT; TmPacketBase::TmPacketBase(uint8_t* setData): SpacePacketBase(setData) { @@ -52,8 +52,10 @@ bool TmPacketBase::checkAndSetStamper() { timeStamper = objectManager->get(timeStamperId); if (timeStamper == NULL) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TmPacketBase::checkAndSetStamper: Stamper not found!" + sif::Warning << "TmPacketBase::checkAndSetStamper: Stamper not found!" << std::endl; +#else + sif::printWarning("TmPacketBase::checkAndSetStamper: Stamper not found!\n"); #endif return false; } diff --git a/tmtcpacket/pus/TmPacketStored.h b/tmtcpacket/pus/TmPacketStored.h index aeeba275..53ef3f4d 100644 --- a/tmtcpacket/pus/TmPacketStored.h +++ b/tmtcpacket/pus/TmPacketStored.h @@ -1,71 +1,12 @@ -#ifndef FSFW_TMTCPACKET_PUS_TMPACKETSTORED_PUSA_H_ -#define FSFW_TMTCPACKET_PUS_TMPACKETSTORED_PUSA_H_ +#ifndef FSFW_TMTCPACKET_PUS_TMPACKETSTORED_H_ +#define FSFW_TMTCPACKET_PUS_TMPACKETSTORED_H_ -#include "TmPacketBase.h" -#include "TmPacketStoredBase.h" #include -#include "../../tmtcpacket/pus/TmPacketPusA.h" -#include "../../serialize/SerializeIF.h" -#include "../../storagemanager/StorageManagerIF.h" -#include "../../internalError/InternalErrorReporterIF.h" -#include "../../ipc/MessageQueueSenderIF.h" - -/** - * This class generates a ECSS PUS Telemetry packet within a given - * intermediate storage. - * As most packets are passed between tasks with the help of a storage - * anyway, it seems logical to create a Packet-In-Storage access class - * which saves the user almost all storage handling operation. - * Packets can both be newly created with the class and be "linked" to - * packets in a store with the help of a storeAddress. - * @ingroup tmtcpackets - */ -class TmPacketStoredPusA : - public TmPacketStoredBase, - public TmPacketPusA { -public: - /** - * This is a default constructor which does not set the data pointer. - * However, it does try to set the packet store. - */ - TmPacketStoredPusA( store_address_t setAddress ); - /** - * With this constructor, new space is allocated in the packet store and - * a new PUS Telemetry Packet is created there. - * Packet Application Data passed in data is copied into the packet. - * The Application data is passed in two parts, first a header, then a - * data field. This allows building a Telemetry Packet from two separate - * data sources. - * @param apid Sets the packet's APID field. - * @param service Sets the packet's Service ID field. - * This specifies the source service. - * @param subservice Sets the packet's Service Subtype field. - * This specifies the source sub-service. - * @param packet_counter Sets the Packet counter field of this packet - * @param data The payload data to be copied to the - * Application Data Field - * @param size The amount of data to be copied. - * @param headerData The header Data of the Application field, - * will be copied in front of data - * @param headerSize The size of the headerDataF - */ - TmPacketStoredPusA( uint16_t apid, uint8_t service, uint8_t subservice, - uint8_t packet_counter = 0, const uint8_t* data = nullptr, - uint32_t size = 0, const uint8_t* headerData = nullptr, - uint32_t headerSize = 0); - /** - * Another ctor to directly pass structured content and header data to the - * packet to avoid additional buffers. - */ - TmPacketStoredPusA( uint16_t apid, uint8_t service, uint8_t subservice, - uint8_t packet_counter, SerializeIF* content, - SerializeIF* header = nullptr); - - uint8_t* getAllTmData() override; - void setDataPointer(const uint8_t* newPointer) override; - -}; +#if FSFW_USE_PUS_C_TELEMETRY == 1 +#else +#include "TmPacketStoredPusA.h" +#endif -#endif /* FSFW_TMTCPACKET_PUS_TMPACKETSTORED_PUSA_H_ */ +#endif /* FSFW_TMTCPACKET_PUS_TMPACKETSTORED_H_ */ diff --git a/tmtcpacket/pus/TmPacketStored.cpp b/tmtcpacket/pus/TmPacketStoredPusA.cpp similarity index 98% rename from tmtcpacket/pus/TmPacketStored.cpp rename to tmtcpacket/pus/TmPacketStoredPusA.cpp index b09f505d..4931f8d9 100644 --- a/tmtcpacket/pus/TmPacketStored.cpp +++ b/tmtcpacket/pus/TmPacketStoredPusA.cpp @@ -1,4 +1,4 @@ -#include "TmPacketStored.h" +#include "TmPacketStoredPusA.h" #include "../../objectmanager/ObjectManagerIF.h" #include "../../serviceinterface/ServiceInterfaceStream.h" diff --git a/tmtcpacket/pus/TmPacketStoredPusA.h b/tmtcpacket/pus/TmPacketStoredPusA.h new file mode 100644 index 00000000..aeeba275 --- /dev/null +++ b/tmtcpacket/pus/TmPacketStoredPusA.h @@ -0,0 +1,71 @@ +#ifndef FSFW_TMTCPACKET_PUS_TMPACKETSTORED_PUSA_H_ +#define FSFW_TMTCPACKET_PUS_TMPACKETSTORED_PUSA_H_ + +#include "TmPacketBase.h" +#include "TmPacketStoredBase.h" +#include + +#include "../../tmtcpacket/pus/TmPacketPusA.h" +#include "../../serialize/SerializeIF.h" +#include "../../storagemanager/StorageManagerIF.h" +#include "../../internalError/InternalErrorReporterIF.h" +#include "../../ipc/MessageQueueSenderIF.h" + +/** + * This class generates a ECSS PUS Telemetry packet within a given + * intermediate storage. + * As most packets are passed between tasks with the help of a storage + * anyway, it seems logical to create a Packet-In-Storage access class + * which saves the user almost all storage handling operation. + * Packets can both be newly created with the class and be "linked" to + * packets in a store with the help of a storeAddress. + * @ingroup tmtcpackets + */ +class TmPacketStoredPusA : + public TmPacketStoredBase, + public TmPacketPusA { +public: + /** + * This is a default constructor which does not set the data pointer. + * However, it does try to set the packet store. + */ + TmPacketStoredPusA( store_address_t setAddress ); + /** + * With this constructor, new space is allocated in the packet store and + * a new PUS Telemetry Packet is created there. + * Packet Application Data passed in data is copied into the packet. + * The Application data is passed in two parts, first a header, then a + * data field. This allows building a Telemetry Packet from two separate + * data sources. + * @param apid Sets the packet's APID field. + * @param service Sets the packet's Service ID field. + * This specifies the source service. + * @param subservice Sets the packet's Service Subtype field. + * This specifies the source sub-service. + * @param packet_counter Sets the Packet counter field of this packet + * @param data The payload data to be copied to the + * Application Data Field + * @param size The amount of data to be copied. + * @param headerData The header Data of the Application field, + * will be copied in front of data + * @param headerSize The size of the headerDataF + */ + TmPacketStoredPusA( uint16_t apid, uint8_t service, uint8_t subservice, + uint8_t packet_counter = 0, const uint8_t* data = nullptr, + uint32_t size = 0, const uint8_t* headerData = nullptr, + uint32_t headerSize = 0); + /** + * Another ctor to directly pass structured content and header data to the + * packet to avoid additional buffers. + */ + TmPacketStoredPusA( uint16_t apid, uint8_t service, uint8_t subservice, + uint8_t packet_counter, SerializeIF* content, + SerializeIF* header = nullptr); + + uint8_t* getAllTmData() override; + void setDataPointer(const uint8_t* newPointer) override; + +}; + + +#endif /* FSFW_TMTCPACKET_PUS_TMPACKETSTORED_PUSA_H_ */ diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index bbcdcc80..147c8796 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -6,7 +6,7 @@ #include "../objectmanager/ObjectManagerIF.h" #include "../ipc/QueueFactory.h" #include "../tmtcpacket/pus/TcPacketStored.h" -#include "../tmtcpacket/pus/TmPacketStored.h" +#include "../tmtcpacket/pus/TmPacketStoredPusA.h" #include "../serviceinterface/ServiceInterface.h" object_id_t CommandingServiceBase::defaultPacketSource = objects::NO_OBJECT; From f906605097465daa0f3d300de5bfa7ade1a11384 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Apr 2021 23:55:33 +0200 Subject: [PATCH 163/230] addes pus packet c implementation --- timemanager/TimeStamperIF.h | 5 +- tmtcpacket/pus/TmPacketBase.cpp | 9 +- tmtcpacket/pus/TmPacketBase.h | 5 +- tmtcpacket/pus/TmPacketPusA.cpp | 24 +---- tmtcpacket/pus/TmPacketPusA.h | 11 +-- tmtcpacket/pus/TmPacketPusC.cpp | 86 +++++++++++++++++ tmtcpacket/pus/TmPacketPusC.h | 127 ++++++++++++++++++++++++++ tmtcpacket/pus/TmPacketStoredPusC.cpp | 2 + tmtcpacket/pus/TmPacketStoredPusC.h | 8 ++ 9 files changed, 237 insertions(+), 40 deletions(-) create mode 100644 tmtcpacket/pus/TmPacketStoredPusC.cpp create mode 100644 tmtcpacket/pus/TmPacketStoredPusC.h diff --git a/timemanager/TimeStamperIF.h b/timemanager/TimeStamperIF.h index 57b7f014..1c4ada60 100644 --- a/timemanager/TimeStamperIF.h +++ b/timemanager/TimeStamperIF.h @@ -1,6 +1,7 @@ #ifndef FSFW_TIMEMANAGER_TIMESTAMPERIF_H_ #define FSFW_TIMEMANAGER_TIMESTAMPERIF_H_ +#include #include "../returnvalues/HasReturnvaluesIF.h" /** @@ -16,8 +17,8 @@ public: //! This is a mission-specific constant and determines the total //! size reserved for timestamps. - //! TODO: Default define in FSFWConfig ? - static const uint8_t MISSION_TIMESTAMP_SIZE = 8; + static const uint8_t MISSION_TIMESTAMP_SIZE = fsfwconfig::FSFW_MISSION_TIMESTAMP_SIZE; + virtual ReturnValue_t addTimeStamp(uint8_t* buffer, const uint8_t maxSize) = 0; virtual ~TimeStamperIF() {} diff --git a/tmtcpacket/pus/TmPacketBase.cpp b/tmtcpacket/pus/TmPacketBase.cpp index 2dfef258..25193c92 100644 --- a/tmtcpacket/pus/TmPacketBase.cpp +++ b/tmtcpacket/pus/TmPacketBase.cpp @@ -38,7 +38,11 @@ void TmPacketBase::setErrorControl() { getSourceData()[size + 1] = (crc) & 0X00FF; // CRCL } - +ReturnValue_t TmPacketBase::getPacketTime(timeval* timestamp) const { + size_t tempSize = 0; + return CCSDSTime::convertFromCcsds(timestamp, getPacketTimeRaw(), + &tempSize, getTimestampSize()); +} void TmPacketBase::print() { #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -52,8 +56,7 @@ bool TmPacketBase::checkAndSetStamper() { timeStamper = objectManager->get(timeStamperId); if (timeStamper == NULL) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::Warning << "TmPacketBase::checkAndSetStamper: Stamper not found!" - << std::endl; + sif::warning << "TmPacketBase::checkAndSetStamper: Stamper not found!" << std::endl; #else sif::printWarning("TmPacketBase::checkAndSetStamper: Stamper not found!\n"); #endif diff --git a/tmtcpacket/pus/TmPacketBase.h b/tmtcpacket/pus/TmPacketBase.h index 09a6ca54..6925e99b 100644 --- a/tmtcpacket/pus/TmPacketBase.h +++ b/tmtcpacket/pus/TmPacketBase.h @@ -29,8 +29,7 @@ public: //! Maximum size of a TM Packet in this mission. //! TODO: Make this dependant on a config variable. static const uint32_t MISSION_TM_PACKET_MAX_SIZE = 2048; - //! First byte of secondary header for PUS-A packets. - //! TODO: Maybe also support PUS-C via config? + //! First four bits of first byte of secondary header static const uint8_t VERSION_NUMBER_BYTE = 0b00010000; /** @@ -87,7 +86,7 @@ public: * timeval format. * @return Converted timestamp of packet. */ - virtual ReturnValue_t getPacketTime(timeval* timestamp) const = 0; + virtual ReturnValue_t getPacketTime(timeval* timestamp) const; /** * Returns a raw pointer to the beginning of the time field. * @return Raw pointer to time field. diff --git a/tmtcpacket/pus/TmPacketPusA.cpp b/tmtcpacket/pus/TmPacketPusA.cpp index 841f7e40..d96f6aa7 100644 --- a/tmtcpacket/pus/TmPacketPusA.cpp +++ b/tmtcpacket/pus/TmPacketPusA.cpp @@ -49,27 +49,7 @@ uint16_t TmPacketPusA::getDataFieldSize() { return sizeof(PUSTmDataFieldHeaderPusA); } -bool TmPacketPusA::checkAndSetStamper() { - if (timeStamper == NULL) { - timeStamper = objectManager->get(timeStamperId); - if (timeStamper == NULL) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TmPacketPusA::checkAndSetStamper: Stamper not found!" - << std::endl; -#endif - return false; - } - } - return true; -} - -ReturnValue_t TmPacketPusA::getPacketTime(timeval* timestamp) const { - size_t tempSize = 0; - return CCSDSTime::convertFromCcsds(timestamp, tmData->data_field.time, - &tempSize, sizeof(tmData->data_field.time)); -} - -uint8_t* TmPacketPusA::getPacketTimeRaw() const{ +uint8_t* TmPacketPusA::getPacketTimeRaw() const { return tmData->data_field.time; } @@ -92,7 +72,7 @@ void TmPacketPusA::initializeTmPacket(uint16_t apid, uint8_t service, tmData->data_field.service_subtype = subservice; tmData->data_field.subcounter = packetSubcounter; //Timestamp packet - if (checkAndSetStamper()) { + if (TmPacketBase::checkAndSetStamper()) { timeStamper->addTimeStamp(tmData->data_field.time, sizeof(tmData->data_field.time)); } diff --git a/tmtcpacket/pus/TmPacketPusA.h b/tmtcpacket/pus/TmPacketPusA.h index 21bdfd95..dd9a5d09 100644 --- a/tmtcpacket/pus/TmPacketPusA.h +++ b/tmtcpacket/pus/TmPacketPusA.h @@ -53,9 +53,6 @@ public: //! Maximum size of a TM Packet in this mission. //! TODO: Make this dependant on a config variable. static const uint32_t MISSION_TM_PACKET_MAX_SIZE = 2048; - //! First byte of secondary header for PUS-A packets. - //! TODO: Maybe also support PUS-C via config? - static const uint8_t VERSION_NUMBER_BYTE_PUS_A = 0b00010000; /** * This is the default constructor. @@ -76,19 +73,13 @@ public: uint16_t getSourceDataSize() override; uint16_t getDataFieldSize() override; - /** - * Interprets the "time"-field in the secondary header and returns it in - * timeval format. - * @return Converted timestamp of packet. - */ - ReturnValue_t getPacketTime(timeval* timestamp) const override; /** * Returns a raw pointer to the beginning of the time field. * @return Raw pointer to time field. */ uint8_t* getPacketTimeRaw() const override; - size_t getTimestampSize() const override; + size_t getPacketMinimumSize() const override; protected: diff --git a/tmtcpacket/pus/TmPacketPusC.cpp b/tmtcpacket/pus/TmPacketPusC.cpp index 99f50825..e6aa50dd 100644 --- a/tmtcpacket/pus/TmPacketPusC.cpp +++ b/tmtcpacket/pus/TmPacketPusC.cpp @@ -1,2 +1,88 @@ #include "TmPacketPusC.h" +#include "TmPacketBase.h" +#include "../../globalfunctions/CRC.h" +#include "../../globalfunctions/arrayprinter.h" +#include "../../objectmanager/ObjectManagerIF.h" +#include "../../serviceinterface/ServiceInterfaceStream.h" +#include "../../timemanager/CCSDSTime.h" + +#include + + +TmPacketPusC::TmPacketPusC(uint8_t* setData) : TmPacketBase(setData) { + tmData = reinterpret_cast(setData); +} + +TmPacketPusC::~TmPacketPusC() { + //Nothing to do. +} + +uint8_t TmPacketPusC::getService() { + return tmData->dataField.serviceType; +} + +uint8_t TmPacketPusC::getSubService() { + return tmData->dataField.serviceSubtype; +} + +uint8_t* TmPacketPusC::getSourceData() { + return &tmData->data; +} + +uint16_t TmPacketPusC::getSourceDataSize() { + return getPacketDataLength() - sizeof(tmData->dataField) - CRC_SIZE + 1; +} + +void TmPacketPusC::setData(const uint8_t* p_Data) { + SpacePacketBase::setData(p_Data); + tmData = (TmPacketPointerPusC*) p_Data; +} + + +size_t TmPacketPusC::getPacketMinimumSize() const { + return TM_PACKET_MIN_SIZE; +} + +uint16_t TmPacketPusC::getDataFieldSize() { + return sizeof(PUSTmDataFieldHeaderPusC); +} + +uint8_t* TmPacketPusC::getPacketTimeRaw() const{ + return tmData->dataField.time; + +} + +void TmPacketPusC::initializeTmPacket(uint16_t apid, uint8_t service, + uint8_t subservice, uint16_t packetSubcounter, uint16_t destinationId = 0, + uint8_t timeRefField = 0) { + //Set primary header: + initSpacePacketHeader(false, true, apid); + //Set data Field Header: + //First, set to zero. + memset(&tmData->dataField, 0, sizeof(tmData->dataField)); + + // NOTE: In PUS-C, the PUS Version is 2 and specified for the first 4 bits. + // The other 4 bits of the first byte are the spacecraft time reference + // status. To change to PUS-C, set 0b00100000. + // Set CCSDS_secondary header flag to 0, version number to 001 and ack + // to 0000 + tmData->dataField.versionTimeReferenceField = VERSION_NUMBER_BYTE | timeRefField; + tmData->dataField.serviceType = service; + tmData->dataField.serviceSubtype = subservice; + tmData->dataField.subcounter = packetSubcounter; + tmData->dataField.destinationId = destinationId; + //Timestamp packet + if (checkAndSetStamper()) { + timeStamper->addTimeStamp(tmData->dataField.time, + sizeof(tmData->dataField.time)); + } +} + +void TmPacketPusC::setSourceDataSize(uint16_t size) { + setPacketDataLength(size + sizeof(PUSTmDataFieldHeaderPusC) + CRC_SIZE - 1); +} + +size_t TmPacketPusC::getTimestampSize() const { + return sizeof(tmData->dataField.time); +} diff --git a/tmtcpacket/pus/TmPacketPusC.h b/tmtcpacket/pus/TmPacketPusC.h index fec435c4..975d134f 100644 --- a/tmtcpacket/pus/TmPacketPusC.h +++ b/tmtcpacket/pus/TmPacketPusC.h @@ -1,8 +1,135 @@ #ifndef FSFW_TMTCPACKET_PUS_TMPACKETPUSC_H_ #define FSFW_TMTCPACKET_PUS_TMPACKETPUSC_H_ +#include "TmPacketBase.h" +#include "../SpacePacketBase.h" +#include "../../timemanager/TimeStamperIF.h" +#include "../../timemanager/Clock.h" +#include "../../objectmanager/SystemObjectIF.h" +namespace Factory{ +void setStaticFrameworkObjectIds(); +} +/** + * This struct defines a byte-wise structured PUS TM Data Field Header. + * Any optional fields in the header must be added or removed here. + * Currently, no Destination field is present, but an eigth-byte representation + * for a time tag. + * @ingroup tmtcpackets + */ +struct PUSTmDataFieldHeaderPusC { + uint8_t versionTimeReferenceField; + uint8_t serviceType; + uint8_t serviceSubtype; + uint16_t subcounter; + uint16_t destinationId; + uint8_t time[TimeStamperIF::MISSION_TIMESTAMP_SIZE]; +}; +/** + * This struct defines the data structure of a PUS Telecommand Packet when + * accessed via a pointer. + * @ingroup tmtcpackets + */ +struct TmPacketPointerPusC { + CCSDSPrimaryHeader primary; + PUSTmDataFieldHeaderPusC dataField; + uint8_t data; +}; + +/** + * PUS A packet implementation + * @ingroup tmtcpackets + */ +class TmPacketPusC: public TmPacketBase { + friend void (Factory::setStaticFrameworkObjectIds)(); +public: + /** + * This constant defines the minimum size of a valid PUS Telemetry Packet. + */ + static const uint32_t TM_PACKET_MIN_SIZE = (sizeof(CCSDSPrimaryHeader) + + sizeof(PUSTmDataFieldHeaderPusC) + 2); + //! Maximum size of a TM Packet in this mission. + //! TODO: Make this dependant on a config variable. + static const uint32_t MISSION_TM_PACKET_MAX_SIZE = 2048; + + /** + * This is the default constructor. + * It sets its internal data pointer to the address passed and also + * forwards the data pointer to the parent SpacePacketBase class. + * @param set_address The position where the packet data lies. + */ + TmPacketPusC( uint8_t* setData ); + /** + * This is the empty default destructor. + */ + virtual ~TmPacketPusC(); + + /* TmPacketBase implementations */ + uint8_t getService() override; + uint8_t getSubService() override; + uint8_t* getSourceData() override; + uint16_t getSourceDataSize() override; + uint16_t getDataFieldSize() override; + + /** + * Interprets the "time"-field in the secondary header and returns it in + * timeval format. + * @return Converted timestamp of packet. + */ + ReturnValue_t getPacketTime(timeval* timestamp) const override; + /** + * Returns a raw pointer to the beginning of the time field. + * @return Raw pointer to time field. + */ + uint8_t* getPacketTimeRaw() const override; + + size_t getTimestampSize() const override; + size_t getPacketMinimumSize() const override; + +protected: + /** + * A pointer to a structure which defines the data structure of + * the packet's data. + * + * To be hardware-safe, all elements are of byte size. + */ + TmPacketPointerPusC* tmData; + + /** + * Initializes the Tm Packet header. + * Does set the timestamp (to now), but not the error control field. + * @param apid APID used. + * @param service PUS Service + * @param subservice PUS Subservice + * @param packetSubcounter Additional subcounter used. + */ + void initializeTmPacket(uint16_t apid, uint8_t service, uint8_t subservice, + uint16_t packetSubcounter, uint16_t destinationId, uint8_t timeRefField); + + /** + * With this method, the packet data pointer can be redirected to another + * location. + * + * This call overwrites the parent's setData method to set both its + * @c tc_data pointer and the parent's @c data pointer. + * + * @param p_data A pointer to another PUS Telemetry Packet. + */ + void setData( const uint8_t* pData ); + + /** + * In case data was filled manually (almost never the case). + * @param size Size of source data (without CRC and data filed header!). + */ + void setSourceDataSize(uint16_t size); + + /** + * Checks if a time stamper is available and tries to set it if not. + * @return Returns false if setting failed. + */ + bool checkAndSetStamper(); +}; #endif /* FSFW_TMTCPACKET_PUS_TMPACKETPUSC_H_ */ diff --git a/tmtcpacket/pus/TmPacketStoredPusC.cpp b/tmtcpacket/pus/TmPacketStoredPusC.cpp new file mode 100644 index 00000000..bb27b80f --- /dev/null +++ b/tmtcpacket/pus/TmPacketStoredPusC.cpp @@ -0,0 +1,2 @@ +#include "TmPacketStoredPusC.h" + diff --git a/tmtcpacket/pus/TmPacketStoredPusC.h b/tmtcpacket/pus/TmPacketStoredPusC.h new file mode 100644 index 00000000..53b39414 --- /dev/null +++ b/tmtcpacket/pus/TmPacketStoredPusC.h @@ -0,0 +1,8 @@ +#ifndef FSFW_TMTCPACKET_PUS_TMPACKETSTOREDPUSC_H_ +#define FSFW_TMTCPACKET_PUS_TMPACKETSTOREDPUSC_H_ + + + + + +#endif /* FSFW_TMTCPACKET_PUS_TMPACKETSTOREDPUSC_H_ */ From ed186b04dfdfb41f5574fac1d01fddd3a9162511 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 13 Apr 2021 00:19:09 +0200 Subject: [PATCH 164/230] finalized PUS C TM support --- pus/Service17Test.cpp | 15 +++- pus/Service1TelecommandVerification.cpp | 12 ++- pus/Service5EventReporting.cpp | 7 +- tmtcpacket/pus/CMakeLists.txt | 1 + tmtcpacket/pus/TmPacketPusC.cpp | 8 +- tmtcpacket/pus/TmPacketPusC.h | 15 +--- tmtcpacket/pus/TmPacketStored.h | 1 + tmtcpacket/pus/TmPacketStoredPusA.cpp | 3 +- tmtcpacket/pus/TmPacketStoredPusA.h | 10 +-- tmtcpacket/pus/TmPacketStoredPusC.cpp | 78 ++++++++++++++++++++ tmtcpacket/pus/TmPacketStoredPusC.h | 57 ++++++++++++++ tmtcservices/CommandingServiceBase.cpp | 18 ++++- unittest/user/unittest/core/CatchFactory.cpp | 4 +- 13 files changed, 196 insertions(+), 33 deletions(-) diff --git a/pus/Service17Test.cpp b/pus/Service17Test.cpp index cdd8817c..daed987a 100644 --- a/pus/Service17Test.cpp +++ b/pus/Service17Test.cpp @@ -1,8 +1,9 @@ #include "Service17Test.h" +#include -#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../serviceinterface/ServiceInterface.h" #include "../objectmanager/SystemObject.h" -#include "../tmtcpacket/pus/TmPacketStoredPusA.h" +#include "../tmtcpacket/pus/TmPacketStored.h" Service17Test::Service17Test(object_id_t objectId, @@ -17,15 +18,25 @@ Service17Test::~Service17Test() { ReturnValue_t Service17Test::handleRequest(uint8_t subservice) { switch(subservice) { case Subservice::CONNECTION_TEST: { +#if FSFW_USE_PUS_C_TELEMETRY == 0 TmPacketStoredPusA connectionPacket(apid, serviceId, Subservice::CONNECTION_TEST_REPORT, packetSubCounter++); +#else + TmPacketStoredPusC connectionPacket(apid, serviceId, + Subservice::CONNECTION_TEST_REPORT, packetSubCounter++); +#endif connectionPacket.sendPacket(requestQueue->getDefaultDestination(), requestQueue->getId()); return HasReturnvaluesIF::RETURN_OK; } case Subservice::EVENT_TRIGGER_TEST: { +#if FSFW_USE_PUS_C_TELEMETRY == 0 TmPacketStoredPusA connectionPacket(apid, serviceId, Subservice::CONNECTION_TEST_REPORT, packetSubCounter++); +#else + TmPacketStoredPusC connectionPacket(apid, serviceId, + Subservice::CONNECTION_TEST_REPORT, packetSubCounter++); +#endif connectionPacket.sendPacket(requestQueue->getDefaultDestination(), requestQueue->getId()); triggerEvent(TEST, 1234, 5678); diff --git a/pus/Service1TelecommandVerification.cpp b/pus/Service1TelecommandVerification.cpp index 358d1faa..7ef08de7 100644 --- a/pus/Service1TelecommandVerification.cpp +++ b/pus/Service1TelecommandVerification.cpp @@ -3,7 +3,7 @@ #include "../ipc/QueueFactory.h" #include "../tmtcservices/PusVerificationReport.h" -#include "../tmtcpacket/pus/TmPacketStoredPusA.h" +#include "../tmtcpacket/pus/TmPacketStored.h" #include "../serviceinterface/ServiceInterfaceStream.h" #include "../tmtcservices/AcceptsTelemetryIF.h" @@ -68,8 +68,13 @@ ReturnValue_t Service1TelecommandVerification::generateFailureReport( message->getTcSequenceControl(), message->getStep(), message->getErrorCode(), message->getParameter1(), message->getParameter2()); +#if FSFW_USE_PUS_C_TELEMETRY == 0 TmPacketStoredPusA tmPacket(apid, serviceId, message->getReportId(), packetSubCounter++, &report); +#else + TmPacketStoredPusC tmPacket(apid, serviceId, message->getReportId(), + packetSubCounter++, &report); +#endif ReturnValue_t result = tmPacket.sendPacket(tmQueue->getDefaultDestination(), tmQueue->getId()); return result; @@ -79,8 +84,13 @@ ReturnValue_t Service1TelecommandVerification::generateSuccessReport( PusVerificationMessage *message) { SuccessReport report(message->getReportId(),message->getTcPacketId(), message->getTcSequenceControl(),message->getStep()); +#if FSFW_USE_PUS_C_TELEMETRY == 0 TmPacketStoredPusA tmPacket(apid, serviceId, message->getReportId(), packetSubCounter++, &report); +#else + TmPacketStoredPusC tmPacket(apid, serviceId, message->getReportId(), + packetSubCounter++, &report); +#endif ReturnValue_t result = tmPacket.sendPacket(tmQueue->getDefaultDestination(), tmQueue->getId()); return result; diff --git a/pus/Service5EventReporting.cpp b/pus/Service5EventReporting.cpp index f6281fe9..62eefcb3 100644 --- a/pus/Service5EventReporting.cpp +++ b/pus/Service5EventReporting.cpp @@ -4,7 +4,7 @@ #include "../serviceinterface/ServiceInterfaceStream.h" #include "../events/EventManagerIF.h" #include "../ipc/QueueFactory.h" -#include "../tmtcpacket/pus/TmPacketStoredPusA.h" +#include "../tmtcpacket/pus/TmPacketStored.h" Service5EventReporting::Service5EventReporting(object_id_t objectId, @@ -52,8 +52,13 @@ ReturnValue_t Service5EventReporting::generateEventReport( { EventReport report(message.getEventId(),message.getReporter(), message.getParameter1(),message.getParameter2()); +#if FSFW_USE_PUS_C_TELEMETRY == 0 TmPacketStoredPusA tmPacket(PusServiceBase::apid, PusServiceBase::serviceId, message.getSeverity(), packetSubCounter++, &report); +#else + TmPacketStoredPusC tmPacket(PusServiceBase::apid, PusServiceBase::serviceId, + message.getSeverity(), packetSubCounter++, &report); +#endif ReturnValue_t result = tmPacket.sendPacket( requestQueue->getDefaultDestination(),requestQueue->getId()); if(result != HasReturnvaluesIF::RETURN_OK) { diff --git a/tmtcpacket/pus/CMakeLists.txt b/tmtcpacket/pus/CMakeLists.txt index 747ed070..cd4f49f1 100644 --- a/tmtcpacket/pus/CMakeLists.txt +++ b/tmtcpacket/pus/CMakeLists.txt @@ -5,6 +5,7 @@ target_sources(${LIB_FSFW_NAME} TmPacketBase.cpp TmPacketMinimal.cpp TmPacketStoredPusA.cpp + TmPacketStoredPusC.cpp TmPacketPusA.cpp TmPacketPusC.cpp TmPacketStoredBase.cpp diff --git a/tmtcpacket/pus/TmPacketPusC.cpp b/tmtcpacket/pus/TmPacketPusC.cpp index e6aa50dd..a6b4c428 100644 --- a/tmtcpacket/pus/TmPacketPusC.cpp +++ b/tmtcpacket/pus/TmPacketPusC.cpp @@ -54,8 +54,8 @@ uint8_t* TmPacketPusC::getPacketTimeRaw() const{ } void TmPacketPusC::initializeTmPacket(uint16_t apid, uint8_t service, - uint8_t subservice, uint16_t packetSubcounter, uint16_t destinationId = 0, - uint8_t timeRefField = 0) { + uint8_t subservice, uint16_t packetSubcounter, uint16_t destinationId, + uint8_t timeRefField) { //Set primary header: initSpacePacketHeader(false, true, apid); //Set data Field Header: @@ -67,13 +67,15 @@ void TmPacketPusC::initializeTmPacket(uint16_t apid, uint8_t service, // status. To change to PUS-C, set 0b00100000. // Set CCSDS_secondary header flag to 0, version number to 001 and ack // to 0000 + /* Only account for last 4 bytes */ + timeRefField &= 0b1111; tmData->dataField.versionTimeReferenceField = VERSION_NUMBER_BYTE | timeRefField; tmData->dataField.serviceType = service; tmData->dataField.serviceSubtype = subservice; tmData->dataField.subcounter = packetSubcounter; tmData->dataField.destinationId = destinationId; //Timestamp packet - if (checkAndSetStamper()) { + if (TmPacketBase::checkAndSetStamper()) { timeStamper->addTimeStamp(tmData->dataField.time, sizeof(tmData->dataField.time)); } diff --git a/tmtcpacket/pus/TmPacketPusC.h b/tmtcpacket/pus/TmPacketPusC.h index 975d134f..d072d5b9 100644 --- a/tmtcpacket/pus/TmPacketPusC.h +++ b/tmtcpacket/pus/TmPacketPusC.h @@ -73,19 +73,13 @@ public: uint16_t getSourceDataSize() override; uint16_t getDataFieldSize() override; - /** - * Interprets the "time"-field in the secondary header and returns it in - * timeval format. - * @return Converted timestamp of packet. - */ - ReturnValue_t getPacketTime(timeval* timestamp) const override; /** * Returns a raw pointer to the beginning of the time field. * @return Raw pointer to time field. */ uint8_t* getPacketTimeRaw() const override; - size_t getTimestampSize() const override; + size_t getPacketMinimumSize() const override; protected: @@ -106,7 +100,7 @@ protected: * @param packetSubcounter Additional subcounter used. */ void initializeTmPacket(uint16_t apid, uint8_t service, uint8_t subservice, - uint16_t packetSubcounter, uint16_t destinationId, uint8_t timeRefField); + uint16_t packetSubcounter, uint16_t destinationId = 0, uint8_t timeRefField = 0); /** * With this method, the packet data pointer can be redirected to another @@ -125,11 +119,6 @@ protected: */ void setSourceDataSize(uint16_t size); - /** - * Checks if a time stamper is available and tries to set it if not. - * @return Returns false if setting failed. - */ - bool checkAndSetStamper(); }; #endif /* FSFW_TMTCPACKET_PUS_TMPACKETPUSC_H_ */ diff --git a/tmtcpacket/pus/TmPacketStored.h b/tmtcpacket/pus/TmPacketStored.h index 53ef3f4d..fadda561 100644 --- a/tmtcpacket/pus/TmPacketStored.h +++ b/tmtcpacket/pus/TmPacketStored.h @@ -4,6 +4,7 @@ #include #if FSFW_USE_PUS_C_TELEMETRY == 1 +#include "TmPacketStoredPusC.h" #else #include "TmPacketStoredPusA.h" #endif diff --git a/tmtcpacket/pus/TmPacketStoredPusA.cpp b/tmtcpacket/pus/TmPacketStoredPusA.cpp index 4931f8d9..68102b62 100644 --- a/tmtcpacket/pus/TmPacketStoredPusA.cpp +++ b/tmtcpacket/pus/TmPacketStoredPusA.cpp @@ -1,7 +1,6 @@ #include "TmPacketStoredPusA.h" -#include "../../objectmanager/ObjectManagerIF.h" -#include "../../serviceinterface/ServiceInterfaceStream.h" +#include "../../serviceinterface/ServiceInterface.h" #include "../../tmtcservices/TmTcMessage.h" #include diff --git a/tmtcpacket/pus/TmPacketStoredPusA.h b/tmtcpacket/pus/TmPacketStoredPusA.h index aeeba275..0cfcf0b8 100644 --- a/tmtcpacket/pus/TmPacketStoredPusA.h +++ b/tmtcpacket/pus/TmPacketStoredPusA.h @@ -1,18 +1,12 @@ #ifndef FSFW_TMTCPACKET_PUS_TMPACKETSTORED_PUSA_H_ #define FSFW_TMTCPACKET_PUS_TMPACKETSTORED_PUSA_H_ -#include "TmPacketBase.h" #include "TmPacketStoredBase.h" +#include "TmPacketPusA.h" #include -#include "../../tmtcpacket/pus/TmPacketPusA.h" -#include "../../serialize/SerializeIF.h" -#include "../../storagemanager/StorageManagerIF.h" -#include "../../internalError/InternalErrorReporterIF.h" -#include "../../ipc/MessageQueueSenderIF.h" - /** - * This class generates a ECSS PUS Telemetry packet within a given + * This class generates a ECSS PUS A Telemetry packet within a given * intermediate storage. * As most packets are passed between tasks with the help of a storage * anyway, it seems logical to create a Packet-In-Storage access class diff --git a/tmtcpacket/pus/TmPacketStoredPusC.cpp b/tmtcpacket/pus/TmPacketStoredPusC.cpp index bb27b80f..f006412e 100644 --- a/tmtcpacket/pus/TmPacketStoredPusC.cpp +++ b/tmtcpacket/pus/TmPacketStoredPusC.cpp @@ -1,2 +1,80 @@ #include "TmPacketStoredPusC.h" +#include "../../serviceinterface/ServiceInterface.h" +#include "../../tmtcservices/TmTcMessage.h" + +#include + +TmPacketStoredPusC::TmPacketStoredPusC(store_address_t setAddress) : + TmPacketStoredBase(setAddress), TmPacketPusC(nullptr){ +} + +TmPacketStoredPusC::TmPacketStoredPusC(uint16_t apid, uint8_t service, + uint8_t subservice, uint16_t packetSubcounter, const uint8_t *data, + uint32_t size, const uint8_t *headerData, uint32_t headerSize, uint16_t destinationId, + uint8_t timeRefField) : + TmPacketPusC(nullptr) { + storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; + if (not TmPacketStoredBase::checkAndSetStore()) { + return; + } + uint8_t *pData = nullptr; + ReturnValue_t returnValue = store->getFreeElement(&storeAddress, + (getPacketMinimumSize() + size + headerSize), &pData); + + if (returnValue != store->RETURN_OK) { + TmPacketStoredBase::checkAndReportLostTm(); + return; + } + setData(pData); + initializeTmPacket(apid, service, subservice, packetSubcounter, destinationId, timeRefField); + memcpy(getSourceData(), headerData, headerSize); + memcpy(getSourceData() + headerSize, data, size); + setPacketDataLength( + size + headerSize + sizeof(PUSTmDataFieldHeaderPusC) + CRC_SIZE - 1); +} + +TmPacketStoredPusC::TmPacketStoredPusC(uint16_t apid, uint8_t service, + uint8_t subservice, uint16_t packetSubcounter, SerializeIF *content, + SerializeIF *header, uint16_t destinationId, uint8_t timeRefField) : + TmPacketPusC(nullptr) { + storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; + if (not TmPacketStoredBase::checkAndSetStore()) { + return; + } + size_t sourceDataSize = 0; + if (content != NULL) { + sourceDataSize += content->getSerializedSize(); + } + if (header != NULL) { + sourceDataSize += header->getSerializedSize(); + } + uint8_t *p_data = NULL; + ReturnValue_t returnValue = store->getFreeElement(&storeAddress, + (getPacketMinimumSize() + sourceDataSize), &p_data); + if (returnValue != store->RETURN_OK) { + TmPacketStoredBase::checkAndReportLostTm(); + } + setData(p_data); + initializeTmPacket(apid, service, subservice, packetSubcounter); + uint8_t *putDataHere = getSourceData(); + size_t size = 0; + if (header != NULL) { + header->serialize(&putDataHere, &size, sourceDataSize, + SerializeIF::Endianness::BIG); + } + if (content != NULL) { + content->serialize(&putDataHere, &size, sourceDataSize, + SerializeIF::Endianness::BIG); + } + setPacketDataLength( + sourceDataSize + sizeof(PUSTmDataFieldHeaderPusC) + CRC_SIZE - 1); +} + +uint8_t* TmPacketStoredPusC::getAllTmData() { + return getWholeData(); +} + +void TmPacketStoredPusC::setDataPointer(const uint8_t *newPointer) { + setData(newPointer); +} diff --git a/tmtcpacket/pus/TmPacketStoredPusC.h b/tmtcpacket/pus/TmPacketStoredPusC.h index 53b39414..83478a94 100644 --- a/tmtcpacket/pus/TmPacketStoredPusC.h +++ b/tmtcpacket/pus/TmPacketStoredPusC.h @@ -1,7 +1,64 @@ #ifndef FSFW_TMTCPACKET_PUS_TMPACKETSTOREDPUSC_H_ #define FSFW_TMTCPACKET_PUS_TMPACKETSTOREDPUSC_H_ +#include +#include +/** + * This class generates a ECSS PUS A Telemetry packet within a given + * intermediate storage. + * As most packets are passed between tasks with the help of a storage + * anyway, it seems logical to create a Packet-In-Storage access class + * which saves the user almost all storage handling operation. + * Packets can both be newly created with the class and be "linked" to + * packets in a store with the help of a storeAddress. + * @ingroup tmtcpackets + */ +class TmPacketStoredPusC: + public TmPacketStoredBase, + public TmPacketPusC { +public: + /** + * This is a default constructor which does not set the data pointer. + * However, it does try to set the packet store. + */ + TmPacketStoredPusC( store_address_t setAddress ); + /** + * With this constructor, new space is allocated in the packet store and + * a new PUS Telemetry Packet is created there. + * Packet Application Data passed in data is copied into the packet. + * The Application data is passed in two parts, first a header, then a + * data field. This allows building a Telemetry Packet from two separate + * data sources. + * @param apid Sets the packet's APID field. + * @param service Sets the packet's Service ID field. + * This specifies the source service. + * @param subservice Sets the packet's Service Subtype field. + * This specifies the source sub-service. + * @param packet_counter Sets the Packet counter field of this packet + * @param data The payload data to be copied to the + * Application Data Field + * @param size The amount of data to be copied. + * @param headerData The header Data of the Application field, + * will be copied in front of data + * @param headerSize The size of the headerDataF + */ + TmPacketStoredPusC( uint16_t apid, uint8_t service, uint8_t subservice, + uint16_t packetCounter = 0, const uint8_t* data = nullptr, + uint32_t size = 0, const uint8_t* headerData = nullptr, + uint32_t headerSize = 0, uint16_t destinationId = 0, uint8_t timeRefField = 0); + /** + * Another ctor to directly pass structured content and header data to the + * packet to avoid additional buffers. + */ + TmPacketStoredPusC( uint16_t apid, uint8_t service, uint8_t subservice, + uint16_t packetCounter, SerializeIF* content, + SerializeIF* header = nullptr, uint16_t destinationId = 0, uint8_t timeRefField = 0); + + uint8_t* getAllTmData() override; + void setDataPointer(const uint8_t* newPointer) override; + +}; diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index 147c8796..fbd29468 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -1,12 +1,13 @@ #include "AcceptsTelemetryIF.h" #include "CommandingServiceBase.h" #include "TmTcMessage.h" +#include #include "../tcdistribution/PUSDistributorIF.h" #include "../objectmanager/ObjectManagerIF.h" #include "../ipc/QueueFactory.h" #include "../tmtcpacket/pus/TcPacketStored.h" -#include "../tmtcpacket/pus/TmPacketStoredPusA.h" +#include "../tmtcpacket/pus/TmPacketStored.h" #include "../serviceinterface/ServiceInterface.h" object_id_t CommandingServiceBase::defaultPacketSource = objects::NO_OBJECT; @@ -293,8 +294,13 @@ void CommandingServiceBase::handleRequestQueue() { ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice, const uint8_t* data, size_t dataLen, const uint8_t* headerData, size_t headerSize) { +#if FSFW_USE_PUS_C_TELEMETRY == 0 TmPacketStoredPusA tmPacketStored(this->apid, this->service, subservice, this->tmPacketCounter, data, dataLen, headerData, headerSize); +#else + TmPacketStoredPusC tmPacketStored(this->apid, this->service, subservice, + this->tmPacketCounter, data, dataLen, headerData, headerSize); +#endif ReturnValue_t result = tmPacketStored.sendPacket( requestQueue->getDefaultDestination(), requestQueue->getId()); if (result == HasReturnvaluesIF::RETURN_OK) { @@ -311,8 +317,13 @@ ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice, size_t size = 0; SerializeAdapter::serialize(&objectId, &pBuffer, &size, sizeof(object_id_t), SerializeIF::Endianness::BIG); +#if FSFW_USE_PUS_C_TELEMETRY == 0 TmPacketStoredPusA tmPacketStored(this->apid, this->service, subservice, this->tmPacketCounter, data, dataLen, buffer, size); +#else + TmPacketStoredPusC tmPacketStored(this->apid, this->service, subservice, + this->tmPacketCounter, data, dataLen, buffer, size); +#endif ReturnValue_t result = tmPacketStored.sendPacket( requestQueue->getDefaultDestination(), requestQueue->getId()); if (result == HasReturnvaluesIF::RETURN_OK) { @@ -324,8 +335,13 @@ ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice, ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice, SerializeIF* content, SerializeIF* header) { +#if FSFW_USE_PUS_C_TELEMETRY == 0 TmPacketStoredPusA tmPacketStored(this->apid, this->service, subservice, this->tmPacketCounter, content, header); +#else + TmPacketStoredPusC tmPacketStored(this->apid, this->service, subservice, + this->tmPacketCounter, content, header); +#endif ReturnValue_t result = tmPacketStored.sendPacket( requestQueue->getDefaultDestination(), requestQueue->getId()); if (result == HasReturnvaluesIF::RETURN_OK) { diff --git a/unittest/user/unittest/core/CatchFactory.cpp b/unittest/user/unittest/core/CatchFactory.cpp index 2c4eaf24..9afb4fdd 100644 --- a/unittest/user/unittest/core/CatchFactory.cpp +++ b/unittest/user/unittest/core/CatchFactory.cpp @@ -1,6 +1,6 @@ +#include "CatchFactory.h" #include #include -#include "CatchFactory.h" #include #include @@ -74,7 +74,7 @@ void Factory::setStaticFrameworkObjectIds() { DeviceHandlerFailureIsolation::powerConfirmationId = objects::NO_OBJECT; - TmPacketStoredPusA::timeStamperId = objects::NO_OBJECT; + TmPacketBase::timeStamperId = objects::NO_OBJECT; } From fc7e401ddc86b744e6e2bdb42291f67ca8302073 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 13 Apr 2021 01:24:26 +0200 Subject: [PATCH 165/230] pus c working --- defaultcfg/fsfwconfig/FSFWConfig.h | 2 +- tmtcpacket/pus/TmPacketPusC.cpp | 6 ++++-- tmtcpacket/pus/TmPacketPusC.h | 6 ++++-- tmtcpacket/pus/TmPacketStoredPusC.cpp | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/defaultcfg/fsfwconfig/FSFWConfig.h b/defaultcfg/fsfwconfig/FSFWConfig.h index 9a07b4ea..23129402 100644 --- a/defaultcfg/fsfwconfig/FSFWConfig.h +++ b/defaultcfg/fsfwconfig/FSFWConfig.h @@ -45,7 +45,7 @@ namespace fsfwconfig { //! Default timestamp size. The default timestamp will be an eight byte CDC //! short timestamp. -static constexpr uint8_t FSFW_MISSION_TIMESTAMP_SIZE = 8; +static constexpr uint8_t FSFW_MISSION_TIMESTAMP_SIZE = 7; //! Configure the allocated pool sizes for the event manager. static constexpr size_t FSFW_EVENTMGMR_MATCHTREE_NODES = 240; diff --git a/tmtcpacket/pus/TmPacketPusC.cpp b/tmtcpacket/pus/TmPacketPusC.cpp index a6b4c428..12f0d3f8 100644 --- a/tmtcpacket/pus/TmPacketPusC.cpp +++ b/tmtcpacket/pus/TmPacketPusC.cpp @@ -72,8 +72,10 @@ void TmPacketPusC::initializeTmPacket(uint16_t apid, uint8_t service, tmData->dataField.versionTimeReferenceField = VERSION_NUMBER_BYTE | timeRefField; tmData->dataField.serviceType = service; tmData->dataField.serviceSubtype = subservice; - tmData->dataField.subcounter = packetSubcounter; - tmData->dataField.destinationId = destinationId; + tmData->dataField.subcounterMsb = packetSubcounter << 8 & 0xff; + tmData->dataField.subcounterLsb = packetSubcounter & 0xff; + tmData->dataField.destinationIdMsb = destinationId << 8 & 0xff; + tmData->dataField.destinationIdLsb = destinationId & 0xff; //Timestamp packet if (TmPacketBase::checkAndSetStamper()) { timeStamper->addTimeStamp(tmData->dataField.time, diff --git a/tmtcpacket/pus/TmPacketPusC.h b/tmtcpacket/pus/TmPacketPusC.h index d072d5b9..fdc27548 100644 --- a/tmtcpacket/pus/TmPacketPusC.h +++ b/tmtcpacket/pus/TmPacketPusC.h @@ -22,8 +22,10 @@ struct PUSTmDataFieldHeaderPusC { uint8_t versionTimeReferenceField; uint8_t serviceType; uint8_t serviceSubtype; - uint16_t subcounter; - uint16_t destinationId; + uint8_t subcounterMsb; + uint8_t subcounterLsb; + uint8_t destinationIdMsb; + uint8_t destinationIdLsb; uint8_t time[TimeStamperIF::MISSION_TIMESTAMP_SIZE]; }; diff --git a/tmtcpacket/pus/TmPacketStoredPusC.cpp b/tmtcpacket/pus/TmPacketStoredPusC.cpp index f006412e..7f774411 100644 --- a/tmtcpacket/pus/TmPacketStoredPusC.cpp +++ b/tmtcpacket/pus/TmPacketStoredPusC.cpp @@ -56,7 +56,7 @@ TmPacketStoredPusC::TmPacketStoredPusC(uint16_t apid, uint8_t service, TmPacketStoredBase::checkAndReportLostTm(); } setData(p_data); - initializeTmPacket(apid, service, subservice, packetSubcounter); + initializeTmPacket(apid, service, subservice, packetSubcounter, destinationId, timeRefField); uint8_t *putDataHere = getSourceData(); size_t size = 0; if (header != NULL) { From cf8a9996a75c41af890e3d51599814f75aa1fe40 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 13 Apr 2021 10:42:49 +0200 Subject: [PATCH 166/230] added new test stub --- unittest/tests/tmtcpacket/CMakeLists.txt | 3 +++ unittest/tests/tmtcpacket/PusTmTest.cpp | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 unittest/tests/tmtcpacket/CMakeLists.txt create mode 100644 unittest/tests/tmtcpacket/PusTmTest.cpp diff --git a/unittest/tests/tmtcpacket/CMakeLists.txt b/unittest/tests/tmtcpacket/CMakeLists.txt new file mode 100644 index 00000000..a1a4c1b6 --- /dev/null +++ b/unittest/tests/tmtcpacket/CMakeLists.txt @@ -0,0 +1,3 @@ +target_sources(${TARGET_NAME} PRIVATE + PusTmTest.cpp +) diff --git a/unittest/tests/tmtcpacket/PusTmTest.cpp b/unittest/tests/tmtcpacket/PusTmTest.cpp new file mode 100644 index 00000000..b28b04f6 --- /dev/null +++ b/unittest/tests/tmtcpacket/PusTmTest.cpp @@ -0,0 +1,3 @@ + + + From 62e409a9f22092fdd650a1fa776d3b33a18694c2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 15 Apr 2021 10:07:39 +0200 Subject: [PATCH 167/230] doc fix --- tmtcpacket/pus/TmPacketPusC.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tmtcpacket/pus/TmPacketPusC.cpp b/tmtcpacket/pus/TmPacketPusC.cpp index 12f0d3f8..ca2bccdb 100644 --- a/tmtcpacket/pus/TmPacketPusC.cpp +++ b/tmtcpacket/pus/TmPacketPusC.cpp @@ -62,12 +62,7 @@ void TmPacketPusC::initializeTmPacket(uint16_t apid, uint8_t service, //First, set to zero. memset(&tmData->dataField, 0, sizeof(tmData->dataField)); - // NOTE: In PUS-C, the PUS Version is 2 and specified for the first 4 bits. - // The other 4 bits of the first byte are the spacecraft time reference - // status. To change to PUS-C, set 0b00100000. - // Set CCSDS_secondary header flag to 0, version number to 001 and ack - // to 0000 - /* Only account for last 4 bytes */ + /* Only account for last 4 bytes for time reference field */ timeRefField &= 0b1111; tmData->dataField.versionTimeReferenceField = VERSION_NUMBER_BYTE | timeRefField; tmData->dataField.serviceType = service; From 770356f8b68f2d897852b811d1ed61e0f57e6f69 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 19 Apr 2021 14:38:56 +0200 Subject: [PATCH 168/230] fix for warning print --- osal/linux/tcpipHelpers.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osal/linux/tcpipHelpers.cpp b/osal/linux/tcpipHelpers.cpp index 3e8f6009..d7c644ec 100644 --- a/osal/linux/tcpipHelpers.cpp +++ b/osal/linux/tcpipHelpers.cpp @@ -99,8 +99,8 @@ void tcpip::handleError(Protocol protocol, ErrorSources errorSrc, dur_millis_t s sif::warning << "tcpip::handleError: " << protocolString << " | " << errorSrcString << " | " << infoString << std::endl; #else - sif::printWarning("tcpip::handleError: %s | %s | %s\n", protocolString, - errorSrcString, infoString); + sif::printWarning("tcpip::handleError: %s | %s | %s\n", protocolString.c_str(), + errorSrcString.c_str(), infoString.c_str()); #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ if(sleepDuration > 0) { From 98add88d143105f5c04d17629083d9bab2ee2916 Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Tue, 20 Apr 2021 13:01:24 +0200 Subject: [PATCH 169/230] Makes linux realtime optional Adds new config variable FSFW_USE_REALTIME_FOR_LINUX --- defaultcfg/fsfwconfig/FSFWConfig.h | 4 ++++ osal/host/PeriodicTask.cpp | 2 +- osal/linux/PosixThread.cpp | 9 ++++++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/defaultcfg/fsfwconfig/FSFWConfig.h b/defaultcfg/fsfwconfig/FSFWConfig.h index ed86e6e1..385808fe 100644 --- a/defaultcfg/fsfwconfig/FSFWConfig.h +++ b/defaultcfg/fsfwconfig/FSFWConfig.h @@ -57,6 +57,10 @@ static constexpr size_t FSFW_EVENTMGMR_RANGEMATCHERS = 120; static constexpr uint8_t FSFW_CSB_FIFO_DEPTH = 6; static constexpr size_t FSFW_PRINT_BUFFER_SIZE = 124; + +//! Defines if the real time scheduler for linux should be used. +//! If set to 1 the binary needs "cap_sys_nice=eip" privileges to run +#define FSFW_USE_REALTIME_FOR_LINUX 0 } #endif /* CONFIG_FSFWCONFIG_H_ */ diff --git a/osal/host/PeriodicTask.cpp b/osal/host/PeriodicTask.cpp index 7663d522..0a99b03a 100644 --- a/osal/host/PeriodicTask.cpp +++ b/osal/host/PeriodicTask.cpp @@ -19,7 +19,7 @@ PeriodicTask::PeriodicTask(const char *name, TaskPriority setPriority, void (*setDeadlineMissedFunc)()) : started(false), taskName(name), period(setPeriod), deadlineMissedFunc(setDeadlineMissedFunc) { - // It is propably possible to set task priorities by using the native + // It is probably possible to set task priorities by using the native // task handles for Windows / Linux mainThread = std::thread(&PeriodicTask::taskEntryPoint, this, this); #if defined(WIN32) diff --git a/osal/linux/PosixThread.cpp b/osal/linux/PosixThread.cpp index bd8e7258..ead32e87 100644 --- a/osal/linux/PosixThread.cpp +++ b/osal/linux/PosixThread.cpp @@ -184,8 +184,11 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { strerror(status) << std::endl; #endif } - - // TODO FIFO -> This needs root privileges for the process +#ifndef FSFW_USE_REALTIME_FOR_LINUX +#error "Please define FSFW_USE_REALTIME_FOR_LINUX with either 0 or 1" +#endif +#if FSFW_USE_REALTIME_FOR_LINUX == 1 + // FIFO -> This needs root privileges for the process status = pthread_attr_setschedpolicy(&attributes,SCHED_FIFO); if(status != 0){ #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -203,7 +206,7 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { strerror(status) << std::endl; #endif } - +#endif //Set Signal Mask for suspend until startTask is called sigset_t waitSignal; sigemptyset(&waitSignal); From 03095776f16a216edc5d12c0dbc81b7205abb874 Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Tue, 20 Apr 2021 13:31:15 +0200 Subject: [PATCH 170/230] Added a comment and corrected a mistake --- defaultcfg/fsfwconfig/FSFWConfig.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/defaultcfg/fsfwconfig/FSFWConfig.h b/defaultcfg/fsfwconfig/FSFWConfig.h index 385808fe..8f82251b 100644 --- a/defaultcfg/fsfwconfig/FSFWConfig.h +++ b/defaultcfg/fsfwconfig/FSFWConfig.h @@ -52,15 +52,18 @@ static constexpr size_t FSFW_EVENTMGMR_RANGEMATCHERS = 120; //! Defines the FIFO depth of each commanding service base which //! also determines how many commands a CSB service can handle in one cycle -//! simulataneously. This will increase the required RAM for +//! Simultaneously. This will increase the required RAM for //! each CSB service ! static constexpr uint8_t FSFW_CSB_FIFO_DEPTH = 6; static constexpr size_t FSFW_PRINT_BUFFER_SIZE = 124; //! Defines if the real time scheduler for linux should be used. +//! If set to 0, this will also disable priority settings for linux +//! as most systems will not allow to set nice values without privileges +//! For embedded linux system set this to 1. //! If set to 1 the binary needs "cap_sys_nice=eip" privileges to run -#define FSFW_USE_REALTIME_FOR_LINUX 0 +#define FSFW_USE_REALTIME_FOR_LINUX 1 } #endif /* CONFIG_FSFWCONFIG_H_ */ From 6873d2b8473469290a268149cb939a745e92e67f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Apr 2021 14:46:59 +0200 Subject: [PATCH 171/230] temp sensor update --- thermal/TemperatureSensor.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/thermal/TemperatureSensor.h b/thermal/TemperatureSensor.h index ceb8a861..f1e17c55 100644 --- a/thermal/TemperatureSensor.h +++ b/thermal/TemperatureSensor.h @@ -122,6 +122,11 @@ protected: timeval uptimeOfOldTemperature; void doChildOperation() { + ReturnValue_t result = poolVariable->read(MutexIF::TimeoutType::WAITING, 20); + if(result != HasReturnvaluesIF::RETURN_OK) { + return; + } + if ((not poolVariable->isValid()) or (not healthHelper.healthTable->isHealthy(getObjectId()))) { setInvalid(); From 64efb8ec7f2cd64c188791043289e4a45d79ad87 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Apr 2021 14:58:35 +0200 Subject: [PATCH 172/230] temperature sensor update --- thermal/TemperatureSensor.h | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/thermal/TemperatureSensor.h b/thermal/TemperatureSensor.h index f1e17c55..abe446c0 100644 --- a/thermal/TemperatureSensor.h +++ b/thermal/TemperatureSensor.h @@ -69,14 +69,14 @@ public: * @param outputSet Output dataset for the output temperature to fetch it with read() * @param thermalModule respective thermal module, if it has one */ - TemperatureSensor(object_id_t setObjectid, - inputType *inputValue, gp_id_t variableGpid, PoolVariableIF* inputVariable, + TemperatureSensor(object_id_t setObjectid,lp_var_t* inputTemperature, + gp_id_t variableGpid, PoolVariableIF* inputVariable, uint8_t vectorIndex, Parameters parameters = {0, 0, 0, 0, 0, 0}, - LocalPoolDataSetBase *outputSet = NULL, ThermalModuleIF *thermalModule = NULL) : + LocalPoolDataSetBase *outputSet = nullptr, ThermalModuleIF *thermalModule = nullptr) : AbstractTemperatureSensor(setObjectid, thermalModule), parameters(parameters), - inputValue(inputValue), poolVariable(inputVariable), + inputTemperature(inputTemperature), outputTemperature(variableGpid, outputSet, PoolVariableIF::VAR_WRITE), - sensorMonitor(setObjectid, DOMAIN_ID_SENSOR, poolVariable, + sensorMonitor(setObjectid, DOMAIN_ID_SENSOR, variableGpid, DEFAULT_CONFIRMATION_COUNT, parameters.lowerLimit, parameters.upperLimit, TEMP_SENSOR_LOW, TEMP_SENSOR_HIGH), oldTemperature(20), uptimeOfOldTemperature({ thermal::INVALID_TEMPERATURE, 0 }) { @@ -110,10 +110,7 @@ protected: UsedParameters parameters; - inputType* inputValue; - - PoolVariableIF* poolVariable; - + lp_var_t* inputTemperature; lp_var_t outputTemperature; LimitMonitor sensorMonitor; @@ -122,18 +119,18 @@ protected: timeval uptimeOfOldTemperature; void doChildOperation() { - ReturnValue_t result = poolVariable->read(MutexIF::TimeoutType::WAITING, 20); + ReturnValue_t result = inputTemperature->read(MutexIF::TimeoutType::WAITING, 20); if(result != HasReturnvaluesIF::RETURN_OK) { return; } - if ((not poolVariable->isValid()) or + if ((not inputTemperature->isValid()) or (not healthHelper.healthTable->isHealthy(getObjectId()))) { setInvalid(); return; } - outputTemperature = calculateOutputTemperature(*inputValue); + outputTemperature = calculateOutputTemperature(inputTemperature->value); outputTemperature.setValid(PoolVariableIF::VALID); timeval uptime; From e6a8371d4a6a54ad4091eb3bf48da6aea96d522e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Apr 2021 15:00:59 +0200 Subject: [PATCH 173/230] temperature sensor update --- thermal/TemperatureSensor.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/thermal/TemperatureSensor.h b/thermal/TemperatureSensor.h index abe446c0..55138cc3 100644 --- a/thermal/TemperatureSensor.h +++ b/thermal/TemperatureSensor.h @@ -137,9 +137,9 @@ protected: Clock::getUptime(&uptime); if (uptimeOfOldTemperature.tv_sec != INVALID_UPTIME) { - //In theory, we could use an AbsValueMonitor to monitor the gradient. - //But this would require storing the maxGradient in DP and quite some overhead. - //The concept of delta limits is a bit strange anyway. + // In theory, we could use an AbsValueMonitor to monitor the gradient. + // But this would require storing the maxGradient in DP and quite some overhead. + // The concept of delta limits is a bit strange anyway. float deltaTime; float deltaTemp; @@ -152,11 +152,10 @@ protected: } if (parameters.gradient < deltaTemp / deltaTime) { triggerEvent(TEMP_SENSOR_GRADIENT); - //Don't set invalid, as we did not recognize it as invalid with full authority, let FDIR handle it + // Don't set invalid, as we did not recognize it as invalid with full authority, let FDIR handle it } } - //Check is done against raw limits. SHOULDDO: Why? Using C would be more easy to handle. sensorMonitor.doCheck(outputTemperature.value); if (sensorMonitor.isOutOfLimits()) { From 153c44601b484fef84795456fa32c8749e574d55 Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Tue, 20 Apr 2021 15:04:42 +0200 Subject: [PATCH 174/230] refixed spelling --- defaultcfg/fsfwconfig/FSFWConfig.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/defaultcfg/fsfwconfig/FSFWConfig.h b/defaultcfg/fsfwconfig/FSFWConfig.h index 8f82251b..e1e0ec64 100644 --- a/defaultcfg/fsfwconfig/FSFWConfig.h +++ b/defaultcfg/fsfwconfig/FSFWConfig.h @@ -52,7 +52,7 @@ static constexpr size_t FSFW_EVENTMGMR_RANGEMATCHERS = 120; //! Defines the FIFO depth of each commanding service base which //! also determines how many commands a CSB service can handle in one cycle -//! Simultaneously. This will increase the required RAM for +//! simultaneously. This will increase the required RAM for //! each CSB service ! static constexpr uint8_t FSFW_CSB_FIFO_DEPTH = 6; From a66fc5339606495fd5222a2bbcf6160647289bf8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Apr 2021 15:31:03 +0200 Subject: [PATCH 175/230] config define moved, better warning --- defaultcfg/fsfwconfig/FSFWConfig.h | 13 +++++++------ osal/linux/PosixThread.cpp | 10 +++++++++- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/defaultcfg/fsfwconfig/FSFWConfig.h b/defaultcfg/fsfwconfig/FSFWConfig.h index e1e0ec64..fe18a2f4 100644 --- a/defaultcfg/fsfwconfig/FSFWConfig.h +++ b/defaultcfg/fsfwconfig/FSFWConfig.h @@ -40,6 +40,13 @@ //! Specify whether a special mode store is used for Subsystem components. #define FSFW_USE_MODESTORE 0 +//! Defines if the real time scheduler for linux should be used. +//! If set to 0, this will also disable priority settings for linux +//! as most systems will not allow to set nice values without privileges +//! For embedded linux system set this to 1. +//! If set to 1 the binary needs "cap_sys_nice=eip" privileges to run +#define FSFW_USE_REALTIME_FOR_LINUX 1 + namespace fsfwconfig { //! Default timestamp size. The default timestamp will be an eight byte CDC //! short timestamp. @@ -58,12 +65,6 @@ static constexpr uint8_t FSFW_CSB_FIFO_DEPTH = 6; static constexpr size_t FSFW_PRINT_BUFFER_SIZE = 124; -//! Defines if the real time scheduler for linux should be used. -//! If set to 0, this will also disable priority settings for linux -//! as most systems will not allow to set nice values without privileges -//! For embedded linux system set this to 1. -//! If set to 1 the binary needs "cap_sys_nice=eip" privileges to run -#define FSFW_USE_REALTIME_FOR_LINUX 1 } #endif /* CONFIG_FSFWCONFIG_H_ */ diff --git a/osal/linux/PosixThread.cpp b/osal/linux/PosixThread.cpp index f1cff992..72adfb14 100644 --- a/osal/linux/PosixThread.cpp +++ b/osal/linux/PosixThread.cpp @@ -223,8 +223,16 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { status = pthread_create(&thread,&attributes,fnc_,arg_); if(status != 0){ #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "Posix Thread create failed with: " << + sif::error << "PosixThread::createTask: Failed with: " << strerror(status) << std::endl; + sif::error << "For FSFW_USE_REALTIME_FOR_LINUX == 1 make sure to call " << + "\"all sudo setcap 'cap_sys_nice=eip'\" on the application or set " + "/etc/security/limit.conf" << std::endl; +#else + sif::printError("PosixThread::createTask: Create failed with: %s\n", strerror(status)); + sif::printError("For FSFW_USE_REALTIME_FOR_LINUX == 1 make sure to call " + "\"all sudo setcap 'cap_sys_nice=eip'\" on the application or set " + "/etc/security/limit.conf\n"); #endif } From 7b29583f8f34e96b23fd6202252f58146e17d978 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Apr 2021 15:32:12 +0200 Subject: [PATCH 176/230] small improvements --- defaultcfg/fsfwconfig/FSFWConfig.h | 13 +++++++------ osal/linux/PosixThread.cpp | 10 +++++++++- osal/linux/tcpipHelpers.cpp | 1 + 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/defaultcfg/fsfwconfig/FSFWConfig.h b/defaultcfg/fsfwconfig/FSFWConfig.h index e1e0ec64..fe18a2f4 100644 --- a/defaultcfg/fsfwconfig/FSFWConfig.h +++ b/defaultcfg/fsfwconfig/FSFWConfig.h @@ -40,6 +40,13 @@ //! Specify whether a special mode store is used for Subsystem components. #define FSFW_USE_MODESTORE 0 +//! Defines if the real time scheduler for linux should be used. +//! If set to 0, this will also disable priority settings for linux +//! as most systems will not allow to set nice values without privileges +//! For embedded linux system set this to 1. +//! If set to 1 the binary needs "cap_sys_nice=eip" privileges to run +#define FSFW_USE_REALTIME_FOR_LINUX 1 + namespace fsfwconfig { //! Default timestamp size. The default timestamp will be an eight byte CDC //! short timestamp. @@ -58,12 +65,6 @@ static constexpr uint8_t FSFW_CSB_FIFO_DEPTH = 6; static constexpr size_t FSFW_PRINT_BUFFER_SIZE = 124; -//! Defines if the real time scheduler for linux should be used. -//! If set to 0, this will also disable priority settings for linux -//! as most systems will not allow to set nice values without privileges -//! For embedded linux system set this to 1. -//! If set to 1 the binary needs "cap_sys_nice=eip" privileges to run -#define FSFW_USE_REALTIME_FOR_LINUX 1 } #endif /* CONFIG_FSFWCONFIG_H_ */ diff --git a/osal/linux/PosixThread.cpp b/osal/linux/PosixThread.cpp index f1cff992..72adfb14 100644 --- a/osal/linux/PosixThread.cpp +++ b/osal/linux/PosixThread.cpp @@ -223,8 +223,16 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { status = pthread_create(&thread,&attributes,fnc_,arg_); if(status != 0){ #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "Posix Thread create failed with: " << + sif::error << "PosixThread::createTask: Failed with: " << strerror(status) << std::endl; + sif::error << "For FSFW_USE_REALTIME_FOR_LINUX == 1 make sure to call " << + "\"all sudo setcap 'cap_sys_nice=eip'\" on the application or set " + "/etc/security/limit.conf" << std::endl; +#else + sif::printError("PosixThread::createTask: Create failed with: %s\n", strerror(status)); + sif::printError("For FSFW_USE_REALTIME_FOR_LINUX == 1 make sure to call " + "\"all sudo setcap 'cap_sys_nice=eip'\" on the application or set " + "/etc/security/limit.conf\n"); #endif } diff --git a/osal/linux/tcpipHelpers.cpp b/osal/linux/tcpipHelpers.cpp index 4c1b9a78..3e8f6009 100644 --- a/osal/linux/tcpipHelpers.cpp +++ b/osal/linux/tcpipHelpers.cpp @@ -1,5 +1,6 @@ #include "../common/tcpipHelpers.h" +#include "../../serviceinterface/ServiceInterface.h" #include "../../tasks/TaskFactory.h" #include From 524e50a6dd5649b9748c677b72e00bdb9e9a725e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Apr 2021 15:54:44 +0200 Subject: [PATCH 177/230] comment block corrected --- thermal/TemperatureSensor.h | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/thermal/TemperatureSensor.h b/thermal/TemperatureSensor.h index 55138cc3..b4ea4504 100644 --- a/thermal/TemperatureSensor.h +++ b/thermal/TemperatureSensor.h @@ -60,18 +60,17 @@ public: /** * Instantiate Temperature Sensor Object. - * @param setObjectid objectId of the sensor object - * @param inputValue Pointer to input value which is converted to a temperature - * @param variableGpid Global Pool ID of the output value - * @param inputVariable Input variable handle - * @param vectorIndex Vector Index for the sensor monitor - * @param parameters Calculation parameters, temperature limits, gradient limit - * @param outputSet Output dataset for the output temperature to fetch it with read() - * @param thermalModule respective thermal module, if it has one + * @param setObjectid objectId of the sensor object + * @param inputTemperature Pointer to a raw input value which is converted to an floating + * point C output temperature + * @param variableGpid Global Pool ID of the output value + * @param vectorIndex Vector Index for the sensor monitor + * @param parameters Calculation parameters, temperature limits, gradient limit + * @param outputSet Output dataset for the output temperature to fetch it with read() + * @param thermalModule Respective thermal module, if it has one */ TemperatureSensor(object_id_t setObjectid,lp_var_t* inputTemperature, - gp_id_t variableGpid, PoolVariableIF* inputVariable, - uint8_t vectorIndex, Parameters parameters = {0, 0, 0, 0, 0, 0}, + gp_id_t variableGpid, uint8_t vectorIndex, Parameters parameters = {0, 0, 0, 0, 0, 0}, LocalPoolDataSetBase *outputSet = nullptr, ThermalModuleIF *thermalModule = nullptr) : AbstractTemperatureSensor(setObjectid, thermalModule), parameters(parameters), inputTemperature(inputTemperature), From 0c342ad7fcc715266a2562f65f2cec034d40e919 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Apr 2021 15:57:11 +0200 Subject: [PATCH 178/230] minor changes --- thermal/TemperatureSensor.h | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/thermal/TemperatureSensor.h b/thermal/TemperatureSensor.h index b4ea4504..69c16c7f 100644 --- a/thermal/TemperatureSensor.h +++ b/thermal/TemperatureSensor.h @@ -1,5 +1,5 @@ -#ifndef TEMPERATURESENSOR_H_ -#define TEMPERATURESENSOR_H_ +#ifndef FSFW_THERMAL_TEMPERATURESENSOR_H_ +#define FSFW_THERMAL_TEMPERATURESENSOR_H_ #include "tcsDefinitions.h" #include "AbstractTemperatureSensor.h" @@ -151,7 +151,8 @@ protected: } if (parameters.gradient < deltaTemp / deltaTime) { triggerEvent(TEMP_SENSOR_GRADIENT); - // Don't set invalid, as we did not recognize it as invalid with full authority, let FDIR handle it + // Don't set invalid, as we did not recognize it as invalid with full authority, + // let FDIR handle it } } @@ -181,7 +182,10 @@ public: static const uint16_t ADDRESS_C = 2; static const uint16_t ADDRESS_GRADIENT = 3; - static const uint16_t DEFAULT_CONFIRMATION_COUNT = 1; //!< Changed due to issue with later temperature checking even tough the sensor monitor was confirming already (Was 10 before with comment = Correlates to a 10s confirmation time. Chosen rather large, should not be so bad for components and helps survive glitches.) + //! Changed due to issue with later temperature checking even tough the sensor monitor was + //! confirming already (Was 10 before with comment = Correlates to a 10s confirmation time. + //! Chosen rather large, should not be so bad for components and helps survive glitches.) + static const uint16_t DEFAULT_CONFIRMATION_COUNT = 1; static const uint8_t DOMAIN_ID_SENSOR = 1; @@ -221,4 +225,4 @@ public: }; -#endif /* TEMPERATURESENSOR_H_ */ +#endif /* FSFW_THERMAL_TEMPERATURESENSOR_H_ */ From 38a5e7e618ebb7a9190b894b2ba6d302049aa042 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Apr 2021 16:00:01 +0200 Subject: [PATCH 179/230] ctor variable better name --- thermal/TemperatureSensor.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/thermal/TemperatureSensor.h b/thermal/TemperatureSensor.h index 69c16c7f..c7b9d771 100644 --- a/thermal/TemperatureSensor.h +++ b/thermal/TemperatureSensor.h @@ -63,19 +63,19 @@ public: * @param setObjectid objectId of the sensor object * @param inputTemperature Pointer to a raw input value which is converted to an floating * point C output temperature - * @param variableGpid Global Pool ID of the output value + * @param outputGpid Global Pool ID of the output value * @param vectorIndex Vector Index for the sensor monitor * @param parameters Calculation parameters, temperature limits, gradient limit * @param outputSet Output dataset for the output temperature to fetch it with read() * @param thermalModule Respective thermal module, if it has one */ TemperatureSensor(object_id_t setObjectid,lp_var_t* inputTemperature, - gp_id_t variableGpid, uint8_t vectorIndex, Parameters parameters = {0, 0, 0, 0, 0, 0}, + gp_id_t outputGpid, uint8_t vectorIndex, Parameters parameters = {0, 0, 0, 0, 0, 0}, LocalPoolDataSetBase *outputSet = nullptr, ThermalModuleIF *thermalModule = nullptr) : AbstractTemperatureSensor(setObjectid, thermalModule), parameters(parameters), inputTemperature(inputTemperature), - outputTemperature(variableGpid, outputSet, PoolVariableIF::VAR_WRITE), - sensorMonitor(setObjectid, DOMAIN_ID_SENSOR, variableGpid, + outputTemperature(outputGpid, outputSet, PoolVariableIF::VAR_WRITE), + sensorMonitor(setObjectid, DOMAIN_ID_SENSOR, outputGpid, DEFAULT_CONFIRMATION_COUNT, parameters.lowerLimit, parameters.upperLimit, TEMP_SENSOR_LOW, TEMP_SENSOR_HIGH), oldTemperature(20), uptimeOfOldTemperature({ thermal::INVALID_TEMPERATURE, 0 }) { From d792679d49d6e3cc1cf323e046abc1baf7d11c1a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Apr 2021 16:09:50 +0200 Subject: [PATCH 180/230] calling empty ctor now (coverity) --- serialize/SerializeElement.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serialize/SerializeElement.h b/serialize/SerializeElement.h index 47080292..db66f9cc 100644 --- a/serialize/SerializeElement.h +++ b/serialize/SerializeElement.h @@ -25,7 +25,7 @@ public: } SerializeElement() : - LinkedElement(this) { + LinkedElement(this), entry() { } ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize, From 54ff8f9341c4d7ea16296b9bd5c4167ddb19a2ee Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Apr 2021 16:12:50 +0200 Subject: [PATCH 181/230] heater tweaks + coverity fix --- thermal/Heater.cpp | 596 +++++++++++++++++++++++---------------------- thermal/Heater.h | 115 ++++----- 2 files changed, 359 insertions(+), 352 deletions(-) diff --git a/thermal/Heater.cpp b/thermal/Heater.cpp index 782ce296..8bfa030b 100644 --- a/thermal/Heater.cpp +++ b/thermal/Heater.cpp @@ -1,350 +1,354 @@ -#include "../devicehandlers/DeviceHandlerFailureIsolation.h" #include "Heater.h" +#include "../devicehandlers/DeviceHandlerFailureIsolation.h" #include "../power/Fuse.h" #include "../ipc/QueueFactory.h" Heater::Heater(uint32_t objectId, uint8_t switch0, uint8_t switch1) : - HealthDevice(objectId, 0), internalState(STATE_OFF), powerSwitcher( - NULL), pcduQueueId(0), switch0(switch0), switch1(switch1), wasOn( - false), timedOut(false), reactedToBeingFaulty(false), passive( - false), eventQueue(NULL), heaterOnCountdown(10800000)/*about two orbits*/, parameterHelper( - this), lastAction(CLEAR) { - eventQueue = QueueFactory::instance()->createMessageQueue(); +HealthDevice(objectId, 0), internalState(STATE_OFF), powerSwitcher( + NULL), pcduQueueId(0), switch0(switch0), switch1(switch1), wasOn(false), timedOut(false), + reactedToBeingFaulty(false), passive(false), eventQueue(NULL), + heaterOnCountdown(10800000)/*about two orbits*/, parameterHelper(this), lastAction(CLEAR) { + eventQueue = QueueFactory::instance()->createMessageQueue(); } Heater::~Heater() { - QueueFactory::instance()->deleteMessageQueue(eventQueue); + QueueFactory::instance()->deleteMessageQueue(eventQueue); } ReturnValue_t Heater::set() { - passive = false; - //wait for clear before doing anything - if (internalState == STATE_WAIT) { - return HasReturnvaluesIF::RETURN_OK; - } - if (healthHelper.healthTable->isHealthy(getObjectId())) { - doAction(SET); - if ((internalState == STATE_OFF) || (internalState == STATE_PASSIVE)){ - return HasReturnvaluesIF::RETURN_FAILED; - } else { - return HasReturnvaluesIF::RETURN_OK; - } - } else { - if (healthHelper.healthTable->isFaulty(getObjectId())) { - if (!reactedToBeingFaulty) { - reactedToBeingFaulty = true; - doAction(CLEAR); - } - } - return HasReturnvaluesIF::RETURN_FAILED; - } + passive = false; + //wait for clear before doing anything + if (internalState == STATE_WAIT) { + return HasReturnvaluesIF::RETURN_OK; + } + if (healthHelper.healthTable->isHealthy(getObjectId())) { + doAction(SET); + if ((internalState == STATE_OFF) || (internalState == STATE_PASSIVE)){ + return HasReturnvaluesIF::RETURN_FAILED; + } else { + return HasReturnvaluesIF::RETURN_OK; + } + } else { + if (healthHelper.healthTable->isFaulty(getObjectId())) { + if (!reactedToBeingFaulty) { + reactedToBeingFaulty = true; + doAction(CLEAR); + } + } + return HasReturnvaluesIF::RETURN_FAILED; + } } void Heater::clear(bool passive) { - this->passive = passive; - //Force switching off - if (internalState == STATE_WAIT) { - internalState = STATE_ON; - } - if (healthHelper.healthTable->isHealthy(getObjectId())) { - doAction(CLEAR); - } else if (healthHelper.healthTable->isFaulty(getObjectId())) { - if (!reactedToBeingFaulty) { - reactedToBeingFaulty = true; - doAction(CLEAR); - } - } + this->passive = passive; + //Force switching off + if (internalState == STATE_WAIT) { + internalState = STATE_ON; + } + if (healthHelper.healthTable->isHealthy(getObjectId())) { + doAction(CLEAR); + } else if (healthHelper.healthTable->isFaulty(getObjectId())) { + if (!reactedToBeingFaulty) { + reactedToBeingFaulty = true; + doAction(CLEAR); + } + } } void Heater::doAction(Action action) { - //only act if we are not in the right state or in a transition - if (action == SET) { - if ((internalState == STATE_OFF) || (internalState == STATE_PASSIVE) - || (internalState == STATE_EXTERNAL_CONTROL)) { - switchCountdown.setTimeout(powerSwitcher->getSwitchDelayMs()); - internalState = STATE_WAIT_FOR_SWITCHES_ON; - powerSwitcher->sendSwitchCommand(switch0, PowerSwitchIF::SWITCH_ON); - powerSwitcher->sendSwitchCommand(switch1, PowerSwitchIF::SWITCH_ON); - } - } else { //clear - if ((internalState == STATE_ON) || (internalState == STATE_FAULTY) - || (internalState == STATE_EXTERNAL_CONTROL)) { - internalState = STATE_WAIT_FOR_SWITCHES_OFF; - switchCountdown.setTimeout(powerSwitcher->getSwitchDelayMs()); - powerSwitcher->sendSwitchCommand(switch0, - PowerSwitchIF::SWITCH_OFF); - powerSwitcher->sendSwitchCommand(switch1, - PowerSwitchIF::SWITCH_OFF); - } - } + //only act if we are not in the right state or in a transition + if (action == SET) { + if ((internalState == STATE_OFF) || (internalState == STATE_PASSIVE) + || (internalState == STATE_EXTERNAL_CONTROL)) { + switchCountdown.setTimeout(powerSwitcher->getSwitchDelayMs()); + internalState = STATE_WAIT_FOR_SWITCHES_ON; + powerSwitcher->sendSwitchCommand(switch0, PowerSwitchIF::SWITCH_ON); + powerSwitcher->sendSwitchCommand(switch1, PowerSwitchIF::SWITCH_ON); + } + } else { //clear + if ((internalState == STATE_ON) || (internalState == STATE_FAULTY) + || (internalState == STATE_EXTERNAL_CONTROL)) { + internalState = STATE_WAIT_FOR_SWITCHES_OFF; + switchCountdown.setTimeout(powerSwitcher->getSwitchDelayMs()); + powerSwitcher->sendSwitchCommand(switch0, + PowerSwitchIF::SWITCH_OFF); + powerSwitcher->sendSwitchCommand(switch1, + PowerSwitchIF::SWITCH_OFF); + } + } } void Heater::setPowerSwitcher(PowerSwitchIF* powerSwitch) { - this->powerSwitcher = powerSwitch; + this->powerSwitcher = powerSwitch; } ReturnValue_t Heater::performOperation(uint8_t opCode) { - handleQueue(); - handleEventQueue(); + handleQueue(); + handleEventQueue(); - if (!healthHelper.healthTable->isFaulty(getObjectId())) { - reactedToBeingFaulty = false; - } + if (!healthHelper.healthTable->isFaulty(getObjectId())) { + reactedToBeingFaulty = false; + } - switch (internalState) { - case STATE_ON: - if ((powerSwitcher->getSwitchState(switch0) == PowerSwitchIF::SWITCH_OFF) - || (powerSwitcher->getSwitchState(switch1) - == PowerSwitchIF::SWITCH_OFF)) { - //switch went off on its own - //trigger event. FDIR can confirm if it is caused by MniOps and decide on the action - //do not trigger FD events when under external control - if (healthHelper.getHealth() != EXTERNAL_CONTROL) { - triggerEvent(PowerSwitchIF::SWITCH_WENT_OFF); - } else { - internalState = STATE_EXTERNAL_CONTROL; - } - } - break; - case STATE_OFF: - //check if heater is on, ie both switches are on - //if so, just command it to off, to resolve the situation or force a switch stayed on event - //But, only do anything if not already faulty (state off is the stable point for being faulty) - if ((!healthHelper.healthTable->isFaulty(getObjectId())) - && (powerSwitcher->getSwitchState(switch0) - == PowerSwitchIF::SWITCH_ON) - && (powerSwitcher->getSwitchState(switch1) - == PowerSwitchIF::SWITCH_ON)) { - //do not trigger FD events when under external control - if (healthHelper.getHealth() != EXTERNAL_CONTROL) { - internalState = STATE_WAIT_FOR_SWITCHES_OFF; - switchCountdown.setTimeout(powerSwitcher->getSwitchDelayMs()); - powerSwitcher->sendSwitchCommand(switch0, - PowerSwitchIF::SWITCH_OFF); - powerSwitcher->sendSwitchCommand(switch1, - PowerSwitchIF::SWITCH_OFF); - } else { - internalState = STATE_EXTERNAL_CONTROL; - } - } - break; - case STATE_PASSIVE: - break; - case STATE_WAIT_FOR_SWITCHES_ON: - if (switchCountdown.hasTimedOut()) { - if ((powerSwitcher->getSwitchState(switch0) - == PowerSwitchIF::SWITCH_OFF) - || (powerSwitcher->getSwitchState(switch1) - == PowerSwitchIF::SWITCH_OFF)) { - triggerEvent(HEATER_STAYED_OFF); - internalState = STATE_WAIT_FOR_FDIR; //wait before retrying or anything - } else { - triggerEvent(HEATER_ON); - internalState = STATE_ON; - } - } - break; - case STATE_WAIT_FOR_SWITCHES_OFF: - if (switchCountdown.hasTimedOut()) { - //only check for both being on (ie heater still on) - if ((powerSwitcher->getSwitchState(switch0) - == PowerSwitchIF::SWITCH_ON) - && (powerSwitcher->getSwitchState(switch1) - == PowerSwitchIF::SWITCH_ON)) { - if (healthHelper.healthTable->isFaulty(getObjectId())) { - if (passive) { - internalState = STATE_PASSIVE; - } else { - internalState = STATE_OFF; //just accept it - } - triggerEvent(HEATER_ON); //but throw an event to make it more visible - break; - } - triggerEvent(HEATER_STAYED_ON); - internalState = STATE_WAIT_FOR_FDIR; //wait before retrying or anything - } else { - triggerEvent(HEATER_OFF); - if (passive) { - internalState = STATE_PASSIVE; - } else { - internalState = STATE_OFF; - } - } - } - break; - default: - break; - } + switch (internalState) { + case STATE_ON: + if ((powerSwitcher->getSwitchState(switch0) == PowerSwitchIF::SWITCH_OFF) + || (powerSwitcher->getSwitchState(switch1) + == PowerSwitchIF::SWITCH_OFF)) { + //switch went off on its own + //trigger event. FDIR can confirm if it is caused by MniOps and decide on the action + //do not trigger FD events when under external control + if (healthHelper.getHealth() != EXTERNAL_CONTROL) { + triggerEvent(PowerSwitchIF::SWITCH_WENT_OFF); + } else { + internalState = STATE_EXTERNAL_CONTROL; + } + } + break; + case STATE_OFF: + //check if heater is on, ie both switches are on + //if so, just command it to off, to resolve the situation or force a switch stayed on event + //But, only do anything if not already faulty (state off is the stable point for being faulty) + if ((!healthHelper.healthTable->isFaulty(getObjectId())) + && (powerSwitcher->getSwitchState(switch0) + == PowerSwitchIF::SWITCH_ON) + && (powerSwitcher->getSwitchState(switch1) + == PowerSwitchIF::SWITCH_ON)) { + //do not trigger FD events when under external control + if (healthHelper.getHealth() != EXTERNAL_CONTROL) { + internalState = STATE_WAIT_FOR_SWITCHES_OFF; + switchCountdown.setTimeout(powerSwitcher->getSwitchDelayMs()); + powerSwitcher->sendSwitchCommand(switch0, + PowerSwitchIF::SWITCH_OFF); + powerSwitcher->sendSwitchCommand(switch1, + PowerSwitchIF::SWITCH_OFF); + } else { + internalState = STATE_EXTERNAL_CONTROL; + } + } + break; + case STATE_PASSIVE: + break; + case STATE_WAIT_FOR_SWITCHES_ON: + if (switchCountdown.hasTimedOut()) { + if ((powerSwitcher->getSwitchState(switch0) + == PowerSwitchIF::SWITCH_OFF) + || (powerSwitcher->getSwitchState(switch1) + == PowerSwitchIF::SWITCH_OFF)) { + triggerEvent(HEATER_STAYED_OFF); + internalState = STATE_WAIT_FOR_FDIR; //wait before retrying or anything + } else { + triggerEvent(HEATER_ON); + internalState = STATE_ON; + } + } + break; + case STATE_WAIT_FOR_SWITCHES_OFF: + if (switchCountdown.hasTimedOut()) { + //only check for both being on (ie heater still on) + if ((powerSwitcher->getSwitchState(switch0) + == PowerSwitchIF::SWITCH_ON) + && (powerSwitcher->getSwitchState(switch1) + == PowerSwitchIF::SWITCH_ON)) { + if (healthHelper.healthTable->isFaulty(getObjectId())) { + if (passive) { + internalState = STATE_PASSIVE; + } else { + internalState = STATE_OFF; //just accept it + } + triggerEvent(HEATER_ON); //but throw an event to make it more visible + break; + } + triggerEvent(HEATER_STAYED_ON); + internalState = STATE_WAIT_FOR_FDIR; //wait before retrying or anything + } else { + triggerEvent(HEATER_OFF); + if (passive) { + internalState = STATE_PASSIVE; + } else { + internalState = STATE_OFF; + } + } + } + break; + default: + break; + } - if ((powerSwitcher->getSwitchState(switch0) == PowerSwitchIF::SWITCH_ON) - && (powerSwitcher->getSwitchState(switch1) - == PowerSwitchIF::SWITCH_ON)) { - if (wasOn) { - if (heaterOnCountdown.hasTimedOut()) { - //SHOULDDO this means if a heater fails in single mode, the timeout will start again - //I am not sure if this is a bug, but atm I have no idea how to fix this and think - //it will be ok. whatcouldpossiblygowrongâ„¢ - if (!timedOut) { - triggerEvent(HEATER_TIMEOUT); - timedOut = true; - } - } - } else { - wasOn = true; - heaterOnCountdown.resetTimer(); - timedOut = false; - } - } else { - wasOn = false; - } + if ((powerSwitcher->getSwitchState(switch0) == PowerSwitchIF::SWITCH_ON) + && (powerSwitcher->getSwitchState(switch1) + == PowerSwitchIF::SWITCH_ON)) { + if (wasOn) { + if (heaterOnCountdown.hasTimedOut()) { + //SHOULDDO this means if a heater fails in single mode, the timeout will start again + //I am not sure if this is a bug, but atm I have no idea how to fix this and think + //it will be ok. whatcouldpossiblygowrongâ„¢ + if (!timedOut) { + triggerEvent(HEATER_TIMEOUT); + timedOut = true; + } + } + } else { + wasOn = true; + heaterOnCountdown.resetTimer(); + timedOut = false; + } + } else { + wasOn = false; + } - return HasReturnvaluesIF::RETURN_OK; + return HasReturnvaluesIF::RETURN_OK; } void Heater::setSwitch(uint8_t number, ReturnValue_t state, - uint32_t* uptimeOfSwitching) { - if (powerSwitcher == NULL) { - return; - } - if (powerSwitcher->getSwitchState(number) == state) { - *uptimeOfSwitching = INVALID_UPTIME; - } else { - if ((*uptimeOfSwitching == INVALID_UPTIME)) { - powerSwitcher->sendSwitchCommand(number, state); - Clock::getUptime(uptimeOfSwitching); - } else { - uint32_t currentUptime; - Clock::getUptime(¤tUptime); - if (currentUptime - *uptimeOfSwitching - > powerSwitcher->getSwitchDelayMs()) { - *uptimeOfSwitching = INVALID_UPTIME; - if (healthHelper.healthTable->isHealthy(getObjectId())) { - if (state == PowerSwitchIF::SWITCH_ON) { - triggerEvent(HEATER_STAYED_OFF); - } else { - triggerEvent(HEATER_STAYED_ON); - } - } - //SHOULDDO MiniOps during switch timeout leads to a faulty switch - } - } - } + uint32_t* uptimeOfSwitching) { + if (powerSwitcher == NULL) { + return; + } + if (powerSwitcher->getSwitchState(number) == state) { + *uptimeOfSwitching = INVALID_UPTIME; + } else { + if ((*uptimeOfSwitching == INVALID_UPTIME)) { + powerSwitcher->sendSwitchCommand(number, state); + Clock::getUptime(uptimeOfSwitching); + } else { + uint32_t currentUptime; + Clock::getUptime(¤tUptime); + if (currentUptime - *uptimeOfSwitching + > powerSwitcher->getSwitchDelayMs()) { + *uptimeOfSwitching = INVALID_UPTIME; + if (healthHelper.healthTable->isHealthy(getObjectId())) { + if (state == PowerSwitchIF::SWITCH_ON) { + triggerEvent(HEATER_STAYED_OFF); + } else { + triggerEvent(HEATER_STAYED_ON); + } + } + //SHOULDDO MiniOps during switch timeout leads to a faulty switch + } + } + } } MessageQueueId_t Heater::getCommandQueue() const { - return commandQueue->getId(); + return commandQueue->getId(); } ReturnValue_t Heater::initialize() { - ReturnValue_t result = SystemObject::initialize(); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } + ReturnValue_t result = SystemObject::initialize(); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } - EventManagerIF* manager = objectManager->get( - objects::EVENT_MANAGER); - if (manager == NULL) { - return HasReturnvaluesIF::RETURN_FAILED; - } - result = manager->registerListener(eventQueue->getId()); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } + EventManagerIF* manager = objectManager->get( + objects::EVENT_MANAGER); + if (manager == NULL) { + return HasReturnvaluesIF::RETURN_FAILED; + } + result = manager->registerListener(eventQueue->getId()); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } - ConfirmsFailuresIF* pcdu = objectManager->get( - DeviceHandlerFailureIsolation::powerConfirmationId); - if (pcdu == NULL) { - return HasReturnvaluesIF::RETURN_FAILED; - } - pcduQueueId = pcdu->getEventReceptionQueue(); + ConfirmsFailuresIF* pcdu = objectManager->get( + DeviceHandlerFailureIsolation::powerConfirmationId); + if (pcdu == NULL) { + return HasReturnvaluesIF::RETURN_FAILED; + } + pcduQueueId = pcdu->getEventReceptionQueue(); - result = manager->subscribeToAllEventsFrom(eventQueue->getId(), - getObjectId()); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } + result = manager->subscribeToAllEventsFrom(eventQueue->getId(), + getObjectId()); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } - result = parameterHelper.initialize(); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } + result = parameterHelper.initialize(); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } - result = healthHelper.initialize(); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } + result = healthHelper.initialize(); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } - return HasReturnvaluesIF::RETURN_OK; + return HasReturnvaluesIF::RETURN_OK; } void Heater::handleQueue() { - CommandMessage command; - ReturnValue_t result = commandQueue->receiveMessage(&command); - if (result == HasReturnvaluesIF::RETURN_OK) { - result = healthHelper.handleHealthCommand(&command); - if (result == HasReturnvaluesIF::RETURN_OK) { - return; - } - parameterHelper.handleParameterMessage(&command); - } + CommandMessage command; + ReturnValue_t result = commandQueue->receiveMessage(&command); + if (result == HasReturnvaluesIF::RETURN_OK) { + result = healthHelper.handleHealthCommand(&command); + if (result == HasReturnvaluesIF::RETURN_OK) { + return; + } + result = parameterHelper.handleParameterMessage(&command); + if (result == HasReturnvaluesIF::RETURN_OK) { + return; + } + } } ReturnValue_t Heater::getParameter(uint8_t domainId, uint8_t uniqueId, ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues, - uint16_t startAtIndex) { - if (domainId != DOMAIN_ID_BASE) { - return INVALID_DOMAIN_ID; - } - switch (uniqueId) { - case 0: - parameterWrapper->set(heaterOnCountdown.timeout); - break; - default: - return INVALID_IDENTIFIER_ID; - } - return HasReturnvaluesIF::RETURN_OK; + uint16_t startAtIndex) { + if (domainId != DOMAIN_ID_BASE) { + return INVALID_DOMAIN_ID; + } + switch (uniqueId) { + case 0: + parameterWrapper->set(heaterOnCountdown.timeout); + break; + default: + return INVALID_IDENTIFIER_ID; + } + return HasReturnvaluesIF::RETURN_OK; } void Heater::handleEventQueue() { - EventMessage event; - for (ReturnValue_t result = eventQueue->receiveMessage(&event); - result == HasReturnvaluesIF::RETURN_OK; - result = eventQueue->receiveMessage(&event)) { - switch (event.getMessageId()) { - case EventMessage::EVENT_MESSAGE: - switch (event.getEvent()) { - case Fuse::FUSE_WENT_OFF: - case HEATER_STAYED_OFF: - case HEATER_STAYED_ON://Setting it faulty does not help, but we need to reach a stable state and can check for being faulty before throwing this event again. - if (healthHelper.healthTable->isCommandable(getObjectId())) { - healthHelper.setHealth(HasHealthIF::FAULTY); - internalState = STATE_FAULTY; - } - break; - case PowerSwitchIF::SWITCH_WENT_OFF: - internalState = STATE_WAIT; - event.setMessageId(EventMessage::CONFIRMATION_REQUEST); - if (pcduQueueId != 0) { - eventQueue->sendMessage(pcduQueueId, &event); - } else { - healthHelper.setHealth(HasHealthIF::FAULTY); - internalState = STATE_FAULTY; - } - break; - default: - return; - } - break; - case EventMessage::YOUR_FAULT: - healthHelper.setHealth(HasHealthIF::FAULTY); - internalState = STATE_FAULTY; - break; - case EventMessage::MY_FAULT: - //do nothing, we are already in STATE_WAIT and wait for a clear() - break; - default: - return; - } - } + EventMessage event; + for (ReturnValue_t result = eventQueue->receiveMessage(&event); + result == HasReturnvaluesIF::RETURN_OK; + result = eventQueue->receiveMessage(&event)) { + switch (event.getMessageId()) { + case EventMessage::EVENT_MESSAGE: + switch (event.getEvent()) { + case Fuse::FUSE_WENT_OFF: + case HEATER_STAYED_OFF: + // Setting it faulty does not help, but we need to reach a stable state and can check + // for being faulty before throwing this event again. + case HEATER_STAYED_ON: + if (healthHelper.healthTable->isCommandable(getObjectId())) { + healthHelper.setHealth(HasHealthIF::FAULTY); + internalState = STATE_FAULTY; + } + break; + case PowerSwitchIF::SWITCH_WENT_OFF: + internalState = STATE_WAIT; + event.setMessageId(EventMessage::CONFIRMATION_REQUEST); + if (pcduQueueId != 0) { + eventQueue->sendMessage(pcduQueueId, &event); + } else { + healthHelper.setHealth(HasHealthIF::FAULTY); + internalState = STATE_FAULTY; + } + break; + default: + return; + } + break; + case EventMessage::YOUR_FAULT: + healthHelper.setHealth(HasHealthIF::FAULTY); + internalState = STATE_FAULTY; + break; + case EventMessage::MY_FAULT: + //do nothing, we are already in STATE_WAIT and wait for a clear() + break; + default: + return; + } + } } diff --git a/thermal/Heater.h b/thermal/Heater.h index f83957a2..19f13c79 100644 --- a/thermal/Heater.h +++ b/thermal/Heater.h @@ -1,90 +1,93 @@ -#ifndef FRAMEWORK_THERMAL_HEATER_H_ -#define FRAMEWORK_THERMAL_HEATER_H_ +#ifndef FSFW_THERMAL_HEATER_H_ +#define FSFW_THERMAL_HEATER_H_ #include "../devicehandlers/HealthDevice.h" #include "../parameters/ParameterHelper.h" #include "../power/PowerSwitchIF.h" #include "../returnvalues/HasReturnvaluesIF.h" #include "../timemanager/Countdown.h" -#include -//class RedundantHeater; +#include + class Heater: public HealthDevice, public ReceivesParameterMessagesIF { - friend class RedundantHeater; + friend class RedundantHeater; public: - static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::HEATER; - static const Event HEATER_ON = MAKE_EVENT(0, severity::INFO); - static const Event HEATER_OFF = MAKE_EVENT(1, severity::INFO); - static const Event HEATER_TIMEOUT = MAKE_EVENT(2, severity::LOW); - static const Event HEATER_STAYED_ON = MAKE_EVENT(3, severity::LOW); - static const Event HEATER_STAYED_OFF = MAKE_EVENT(4, severity::LOW); + static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::HEATER; + static const Event HEATER_ON = MAKE_EVENT(0, severity::INFO); + static const Event HEATER_OFF = MAKE_EVENT(1, severity::INFO); + static const Event HEATER_TIMEOUT = MAKE_EVENT(2, severity::LOW); + static const Event HEATER_STAYED_ON = MAKE_EVENT(3, severity::LOW); + static const Event HEATER_STAYED_OFF = MAKE_EVENT(4, severity::LOW); - Heater(uint32_t objectId, uint8_t switch0, uint8_t switch1); - virtual ~Heater(); + Heater(uint32_t objectId, uint8_t switch0, uint8_t switch1); + virtual ~Heater(); - ReturnValue_t performOperation(uint8_t opCode); + ReturnValue_t performOperation(uint8_t opCode); - ReturnValue_t initialize(); + ReturnValue_t initialize(); - ReturnValue_t set(); - void clear(bool passive); + ReturnValue_t set(); + void clear(bool passive); - void setPowerSwitcher(PowerSwitchIF *powerSwitch); + void setPowerSwitcher(PowerSwitchIF *powerSwitch); - MessageQueueId_t getCommandQueue() const; + MessageQueueId_t getCommandQueue() const; - ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, - ParameterWrapper *parameterWrapper, - const ParameterWrapper *newValues, uint16_t startAtIndex); + ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, + ParameterWrapper *parameterWrapper, + const ParameterWrapper *newValues, uint16_t startAtIndex); protected: - static const uint32_t INVALID_UPTIME = 0; + static const uint32_t INVALID_UPTIME = 0; - enum InternalState { - STATE_ON, - STATE_OFF, - STATE_PASSIVE, - STATE_WAIT_FOR_SWITCHES_ON, - STATE_WAIT_FOR_SWITCHES_OFF, - STATE_WAIT_FOR_FDIR, //used to avoid doing anything until fdir decided what to do - STATE_FAULTY, - STATE_WAIT, //used when waiting for system to recover from miniops - STATE_EXTERNAL_CONTROL //entered when under external control and a fdir reaction would be triggered. This is useful when leaving external control into an unknown state - //if no fdir reaction is triggered under external control the state is still ok and no need for any special treatment is needed - } internalState; + enum InternalState { + STATE_ON, + STATE_OFF, + STATE_PASSIVE, + STATE_WAIT_FOR_SWITCHES_ON, + STATE_WAIT_FOR_SWITCHES_OFF, + STATE_WAIT_FOR_FDIR, // Used to avoid doing anything until fdir decided what to do + STATE_FAULTY, + STATE_WAIT, // Used when waiting for system to recover from miniops + // Entered when under external control and a fdir reaction would be triggered. + // This is useful when leaving external control into an unknown state + STATE_EXTERNAL_CONTROL + // If no fdir reaction is triggered under external control the state is still ok and + // no need for any special treatment is needed + } internalState; - PowerSwitchIF *powerSwitcher; - MessageQueueId_t pcduQueueId; + PowerSwitchIF *powerSwitcher; + MessageQueueId_t pcduQueueId; - uint8_t switch0; - uint8_t switch1; + uint8_t switch0; + uint8_t switch1; - bool wasOn; + bool wasOn; - bool timedOut; + bool timedOut; - bool reactedToBeingFaulty; + bool reactedToBeingFaulty; - bool passive; + bool passive; - MessageQueueIF* eventQueue; - Countdown heaterOnCountdown; - Countdown switchCountdown; - ParameterHelper parameterHelper; + MessageQueueIF* eventQueue; + Countdown heaterOnCountdown; + Countdown switchCountdown; + ParameterHelper parameterHelper; - enum Action { - SET, CLEAR - } lastAction; + enum Action { + SET, CLEAR + } lastAction; - void doAction(Action action); + void doAction(Action action); - void setSwitch(uint8_t number, ReturnValue_t state, - uint32_t *upTimeOfSwitching); + void setSwitch(uint8_t number, ReturnValue_t state, + uint32_t *upTimeOfSwitching); - void handleQueue(); + void handleQueue(); - void handleEventQueue(); + void handleEventQueue(); }; -#endif /* FRAMEWORK_THERMAL_HEATER_H_ */ +#endif /* FSFW_THERMAL_HEATER_H_ */ From 864621ee37892cef944e1384d6fde38aa5770e1d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Apr 2021 16:15:30 +0200 Subject: [PATCH 182/230] small fix for linux printout --- osal/linux/tcpipHelpers.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osal/linux/tcpipHelpers.cpp b/osal/linux/tcpipHelpers.cpp index 3e8f6009..d7c644ec 100644 --- a/osal/linux/tcpipHelpers.cpp +++ b/osal/linux/tcpipHelpers.cpp @@ -99,8 +99,8 @@ void tcpip::handleError(Protocol protocol, ErrorSources errorSrc, dur_millis_t s sif::warning << "tcpip::handleError: " << protocolString << " | " << errorSrcString << " | " << infoString << std::endl; #else - sif::printWarning("tcpip::handleError: %s | %s | %s\n", protocolString, - errorSrcString, infoString); + sif::printWarning("tcpip::handleError: %s | %s | %s\n", protocolString.c_str(), + errorSrcString.c_str(), infoString.c_str()); #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ if(sleepDuration > 0) { From a2ba3181b91a5f3657ee8f72b7638cadc27864a4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Apr 2021 16:16:35 +0200 Subject: [PATCH 183/230] small coverity tweak --- devicehandlers/HealthDevice.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/devicehandlers/HealthDevice.cpp b/devicehandlers/HealthDevice.cpp index 418ed257..e23dd5b6 100644 --- a/devicehandlers/HealthDevice.cpp +++ b/devicehandlers/HealthDevice.cpp @@ -16,9 +16,9 @@ ReturnValue_t HealthDevice::performOperation(uint8_t opCode) { CommandMessage command; ReturnValue_t result = commandQueue->receiveMessage(&command); if (result == HasReturnvaluesIF::RETURN_OK) { - healthHelper.handleHealthCommand(&command); + result = healthHelper.handleHealthCommand(&command); } - return HasReturnvaluesIF::RETURN_OK; + return result; } ReturnValue_t HealthDevice::initialize() { From 0055d34d9a156f805edf63e9d5970562b372755a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Apr 2021 16:17:37 +0200 Subject: [PATCH 184/230] bugfix found by coverity --- timemanager/TimeMessage.cpp | 2 +- timemanager/TimeMessage.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/timemanager/TimeMessage.cpp b/timemanager/TimeMessage.cpp index a1042efe..66aea0f4 100644 --- a/timemanager/TimeMessage.cpp +++ b/timemanager/TimeMessage.cpp @@ -25,6 +25,6 @@ uint32_t TimeMessage::getCounterValue() { return temp; } -size_t TimeMessage::getMinimumMessageSize() { +size_t TimeMessage::getMinimumMessageSize() const { return this->MAX_SIZE; } diff --git a/timemanager/TimeMessage.h b/timemanager/TimeMessage.h index f5ac3e14..00778fb7 100644 --- a/timemanager/TimeMessage.h +++ b/timemanager/TimeMessage.h @@ -11,7 +11,7 @@ protected: * @brief This call always returns the same fixed size of the message. * @return Returns HEADER_SIZE + \c sizeof(timeval) + sizeof(uint32_t). */ - size_t getMinimumMessageSize(); + size_t getMinimumMessageSize() const override; public: /** From cc8c3aef3d3047c4a6692f24513459043a3c9cfd Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Apr 2021 16:18:39 +0200 Subject: [PATCH 185/230] removed unused interface --- tmtcpacket/pus/TmPacketIF.h | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 tmtcpacket/pus/TmPacketIF.h diff --git a/tmtcpacket/pus/TmPacketIF.h b/tmtcpacket/pus/TmPacketIF.h deleted file mode 100644 index bd66523b..00000000 --- a/tmtcpacket/pus/TmPacketIF.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef FSFW_TMTCPACKET_PUS_TMPACKETIF_H_ -#define FSFW_TMTCPACKET_PUS_TMPACKETIF_H_ - - - - - -#endif /* FSFW_TMTCPACKET_PUS_TMPACKETIF_H_ */ From 4fb792447e037cabbd4800f40e4fabeb44d6c143 Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Tue, 20 Apr 2021 17:29:56 +0200 Subject: [PATCH 186/230] Small rearragenment in Heater.cpp --- thermal/Heater.cpp | 7 +++---- thermal/Heater.h | 16 ++++++++-------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/thermal/Heater.cpp b/thermal/Heater.cpp index 8bfa030b..aeade8d1 100644 --- a/thermal/Heater.cpp +++ b/thermal/Heater.cpp @@ -5,10 +5,9 @@ #include "../ipc/QueueFactory.h" Heater::Heater(uint32_t objectId, uint8_t switch0, uint8_t switch1) : -HealthDevice(objectId, 0), internalState(STATE_OFF), powerSwitcher( - NULL), pcduQueueId(0), switch0(switch0), switch1(switch1), wasOn(false), timedOut(false), - reactedToBeingFaulty(false), passive(false), eventQueue(NULL), - heaterOnCountdown(10800000)/*about two orbits*/, parameterHelper(this), lastAction(CLEAR) { +HealthDevice(objectId, 0), internalState(STATE_OFF), switch0(switch0), switch1(switch1), + heaterOnCountdown(10800000)/*about two orbits*/, + parameterHelper(this) { eventQueue = QueueFactory::instance()->createMessageQueue(); } diff --git a/thermal/Heater.h b/thermal/Heater.h index 19f13c79..2caddd85 100644 --- a/thermal/Heater.h +++ b/thermal/Heater.h @@ -57,28 +57,28 @@ protected: // no need for any special treatment is needed } internalState; - PowerSwitchIF *powerSwitcher; - MessageQueueId_t pcduQueueId; + PowerSwitchIF *powerSwitcher = nullptr; + MessageQueueId_t pcduQueueId = MessageQueueIF::NO_QUEUE; uint8_t switch0; uint8_t switch1; - bool wasOn; + bool wasOn = false; - bool timedOut; + bool timedOut = false; - bool reactedToBeingFaulty; + bool reactedToBeingFaulty = false; - bool passive; + bool passive = false; - MessageQueueIF* eventQueue; + MessageQueueIF* eventQueue = nullptr; Countdown heaterOnCountdown; Countdown switchCountdown; ParameterHelper parameterHelper; enum Action { SET, CLEAR - } lastAction; + } lastAction = CLEAR; void doAction(Action action); From 629814bc9ba00112668d0edaa62e0690cb5ead98 Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Tue, 20 Apr 2021 17:35:28 +0200 Subject: [PATCH 187/230] Just comments --- thermal/Heater.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/thermal/Heater.cpp b/thermal/Heater.cpp index aeade8d1..77049438 100644 --- a/thermal/Heater.cpp +++ b/thermal/Heater.cpp @@ -224,7 +224,6 @@ void Heater::setSwitch(uint8_t number, ReturnValue_t state, triggerEvent(HEATER_STAYED_ON); } } - //SHOULDDO MiniOps during switch timeout leads to a faulty switch } } } @@ -317,7 +316,7 @@ void Heater::handleEventQueue() { switch (event.getEvent()) { case Fuse::FUSE_WENT_OFF: case HEATER_STAYED_OFF: - // Setting it faulty does not help, but we need to reach a stable state and can check + // HEATER_STAYED_ON is a setting if faulty does not help, but we need to reach a stable state and can check // for being faulty before throwing this event again. case HEATER_STAYED_ON: if (healthHelper.healthTable->isCommandable(getObjectId())) { From 3f91803422a97a448a23da550a05cae1564f900b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Apr 2021 18:35:11 +0200 Subject: [PATCH 188/230] fixes from code review --- defaultcfg/fsfwconfig/FSFWConfig.h | 4 ++-- tmtcpacket/pus/TmPacketStoredPusC.h | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/defaultcfg/fsfwconfig/FSFWConfig.h b/defaultcfg/fsfwconfig/FSFWConfig.h index 2e5a7aae..1abdab4c 100644 --- a/defaultcfg/fsfwconfig/FSFWConfig.h +++ b/defaultcfg/fsfwconfig/FSFWConfig.h @@ -50,8 +50,8 @@ #define FSFW_USE_REALTIME_FOR_LINUX 1 namespace fsfwconfig { -//! Default timestamp size. The default timestamp will be an eight byte CDC -//! short timestamp. + +//! Default timestamp size. The default timestamp will be an seven byte CDC short timestamp. static constexpr uint8_t FSFW_MISSION_TIMESTAMP_SIZE = 7; //! Configure the allocated pool sizes for the event manager. diff --git a/tmtcpacket/pus/TmPacketStoredPusC.h b/tmtcpacket/pus/TmPacketStoredPusC.h index 83478a94..883dc0ff 100644 --- a/tmtcpacket/pus/TmPacketStoredPusC.h +++ b/tmtcpacket/pus/TmPacketStoredPusC.h @@ -5,7 +5,7 @@ #include /** - * This class generates a ECSS PUS A Telemetry packet within a given + * This class generates a ECSS PUS C Telemetry packet within a given * intermediate storage. * As most packets are passed between tasks with the help of a storage * anyway, it seems logical to create a Packet-In-Storage access class @@ -42,6 +42,9 @@ public: * @param headerData The header Data of the Application field, * will be copied in front of data * @param headerSize The size of the headerDataF + * @param destinationId Destination ID containing the application process ID as specified + * by PUS C + * @param timeRefField 4 bit time reference field as specified by PUS C */ TmPacketStoredPusC( uint16_t apid, uint8_t service, uint8_t subservice, uint16_t packetCounter = 0, const uint8_t* data = nullptr, From 03ef63302b681651daefde2f17421dabda4c6945 Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Tue, 20 Apr 2021 20:45:15 +0200 Subject: [PATCH 189/230] Replaced Magic Numbers --- subsystem/SubsystemBase.cpp | 9 ++++----- subsystem/SubsystemBase.h | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/subsystem/SubsystemBase.cpp b/subsystem/SubsystemBase.cpp index bcfa4b0e..565e0712 100644 --- a/subsystem/SubsystemBase.cpp +++ b/subsystem/SubsystemBase.cpp @@ -5,8 +5,7 @@ SubsystemBase::SubsystemBase(object_id_t setObjectId, object_id_t parent, Mode_t initialMode, uint16_t commandQueueDepth) : - SystemObject(setObjectId), mode(initialMode), submode(SUBMODE_NONE), - childrenChangedMode(false), + SystemObject(setObjectId), mode(initialMode), commandQueue(QueueFactory::instance()->createMessageQueue( commandQueueDepth, CommandMessage::MAX_MESSAGE_SIZE)), healthHelper(this, setObjectId), modeHelper(this), parentId(parent) { @@ -167,16 +166,16 @@ MessageQueueId_t SubsystemBase::getCommandQueue() const { } ReturnValue_t SubsystemBase::initialize() { - MessageQueueId_t parentQueue = 0; + MessageQueueId_t parentQueue = MessageQueueIF::NO_QUEUE; ReturnValue_t result = SystemObject::initialize(); if (result != RETURN_OK) { return result; } - if (parentId != 0) { + if (parentId != objects::NO_OBJECT) { SubsystemBase *parent = objectManager->get(parentId); - if (parent == NULL) { + if (parent == nullptr) { return RETURN_FAILED; } parentQueue = parent->getCommandQueue(); diff --git a/subsystem/SubsystemBase.h b/subsystem/SubsystemBase.h index b8e4f902..5d107701 100644 --- a/subsystem/SubsystemBase.h +++ b/subsystem/SubsystemBase.h @@ -56,9 +56,9 @@ protected: Mode_t mode; - Submode_t submode; + Submode_t submode = SUBMODE_NONE; - bool childrenChangedMode; + bool childrenChangedMode = false; /** * Always check this against <=0, so you are robust against too many replies From 06631d06a57c30946563d8726ea9ef9a7e6c1c84 Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Tue, 20 Apr 2021 22:01:56 +0200 Subject: [PATCH 190/230] Added comments in AssemblyBase and SubsystemBase --- devicehandlers/AssemblyBase.h | 22 +++++++++++++++++++--- subsystem/SubsystemBase.h | 11 +++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/devicehandlers/AssemblyBase.h b/devicehandlers/AssemblyBase.h index 353d5f89..6cac81b4 100644 --- a/devicehandlers/AssemblyBase.h +++ b/devicehandlers/AssemblyBase.h @@ -24,6 +24,13 @@ * 1. check logic when active-> checkChildrenStateOn * 2. transition logic to change the mode -> commandChildren * + * Important: + * + * The implementation must call registerChild(object_id_t child) + * for all commanded children during initialization. + * The implementation must call the initialization function of the base class. + * (This will call the function in SubsystemBase) + * */ class AssemblyBase: public SubsystemBase { public: @@ -41,9 +48,6 @@ public: virtual ~AssemblyBase(); protected: - - // SHOULDDO: Change that OVERWRITE_HEALTH may be returned - // (or return internalState directly?) /** * Command children to reach [mode,submode] combination * Can be done by setting #commandsOutstanding correctly, @@ -68,6 +72,18 @@ protected: virtual ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) = 0; + /** + * Check whether a combination of mode and submode is valid. + * + * Ground Controller like precise return values from HasModesIF. + * So, please return any of them. + * + * @param mode The targeted mode + * @param submode The targeted submmode + * @return Any information why this combination is invalid from HasModesIF + * like HasModesIF::INVALID_SUBMODE. + * On success return HasReturnvaluesIF::RETURN_OK + */ virtual ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) = 0; diff --git a/subsystem/SubsystemBase.h b/subsystem/SubsystemBase.h index 5d107701..6b2e9b5f 100644 --- a/subsystem/SubsystemBase.h +++ b/subsystem/SubsystemBase.h @@ -37,6 +37,17 @@ public: virtual MessageQueueId_t getCommandQueue() const override; + /** + * Function to register the child objects. + * Performs a checks if the child does implement HasHealthIF and/or HasModesIF + * + * Also adds them to the internal childrenMap. + * + * @param objectId + * @return RETURN_OK if successful + * CHILD_DOESNT_HAVE_MODES if Child is no HasHealthIF and no HasModesIF + * COULD_NOT_INSERT_CHILD If the Child could not be added to the ChildrenMap + */ ReturnValue_t registerChild(object_id_t objectId); virtual ReturnValue_t initialize() override; From 3356ccc9d4bbbe336249b2fb4763adcaea0acd52 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 22 Apr 2021 17:45:46 +0200 Subject: [PATCH 191/230] tested new comment export string for retvals --- ipc/MessageQueueIF.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ipc/MessageQueueIF.h b/ipc/MessageQueueIF.h index 74ccb29a..217174f6 100644 --- a/ipc/MessageQueueIF.h +++ b/ipc/MessageQueueIF.h @@ -22,11 +22,11 @@ public: static const uint8_t INTERFACE_ID = CLASS_ID::MESSAGE_QUEUE_IF; //! No new messages on the queue static const ReturnValue_t EMPTY = MAKE_RETURN_CODE(1); - //! No space left for more messages + //! [EXPORT] : [COMMENT] No space left for more messages static const ReturnValue_t FULL = MAKE_RETURN_CODE(2); - //! Returned if a reply method was called without partner + //! [EXPORT] : [COMMENT] Returned if a reply method was called without partner static const ReturnValue_t NO_REPLY_PARTNER = MAKE_RETURN_CODE(3); - //! Returned if the target destination is invalid. + //! [EXPORT] : [COMMENT] Returned if the target destination is invalid. static constexpr ReturnValue_t DESTINATION_INVALID = MAKE_RETURN_CODE(4); virtual ~MessageQueueIF() {} From 7f1cbaef23d2c508e0bf88b190cb57eefd361e3e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 22 Apr 2021 18:09:23 +0200 Subject: [PATCH 192/230] updated default cmakelists --- defaultcfg/fsfwconfig/CMakeLists.txt | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/defaultcfg/fsfwconfig/CMakeLists.txt b/defaultcfg/fsfwconfig/CMakeLists.txt index cbd4ecde..178fc273 100644 --- a/defaultcfg/fsfwconfig/CMakeLists.txt +++ b/defaultcfg/fsfwconfig/CMakeLists.txt @@ -1,15 +1,23 @@ -target_sources(${LIB_FSFW_NAME} PRIVATE - ipc/missionMessageTypes.cpp - objects/FsfwFactory.cpp - pollingsequence/PollingSequenceFactory.cpp -) - -# Should be added to include path target_include_directories(${TARGET_NAME} PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} ) -if(NOT FSFW_CONFIG_PATH) - set(FSFW_CONFIG_PATH ${CMAKE_CURRENT_SOURCE_DIR}) +target_sources(${TARGET_NAME} PRIVATE + ipc/missionMessageTypes.cpp + pollingsequence/PollingSequenceFactory.cpp + objects/FsfwFactory.cpp +) + +# If a special translation file for object IDs exists, compile it. +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/objects/translateObjects.cpp") + target_sources(${TARGET_NAME} PRIVATE + objects/translateObjects.cpp + ) endif() +# If a special translation file for events exists, compile it. +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/objects/translateObjects.cpp") + target_sources(${TARGET_NAME} PRIVATE + events/translateEvents.cpp + ) +endif() From 18a9729c75875f8bee674f03dd93a5eeeb657a66 Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" Date: Sat, 24 Apr 2021 13:52:06 +0200 Subject: [PATCH 193/230] added multiple reply support --- devicehandlers/DeviceHandlerBase.cpp | 19 ++++++++++++------- devicehandlers/DeviceHandlerBase.h | 18 ++++++++++++++++-- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 0649aaa0..472b81f0 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -456,6 +456,15 @@ ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceComm } } +size_t DeviceHandlerBase::getNextReplyLength(DeviceCommandId_t commandId){ + DeviceReplyIter iter = deviceReplyMap.find(commandId); + if(iter != deviceReplyMap.end()) { + return iter->second.replyLen; + }else{ + return 0; + } +} + ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceReply, uint16_t delayCycles, uint16_t maxDelayCycles, bool periodic) { auto replyIter = deviceReplyMap.find(deviceReply); @@ -646,16 +655,12 @@ void DeviceHandlerBase::doGetWrite() { void DeviceHandlerBase::doSendRead() { ReturnValue_t result; - size_t requestLen = 0; + size_t replyLen = 0; if(cookieInfo.pendingCommand != deviceCommandMap.end()) { - DeviceReplyIter iter = deviceReplyMap.find( - cookieInfo.pendingCommand->first); - if(iter != deviceReplyMap.end()) { - requestLen = iter->second.replyLen; - } + replyLen = getNextReplyLength(cookieInfo.pendingCommand->first); } - result = communicationInterface->requestReceiveMessage(comCookie, requestLen); + result = communicationInterface->requestReceiveMessage(comCookie, replyLen); if (result == RETURN_OK) { cookieInfo.state = COOKIE_READ_SENT; diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index d61b0407..496c08ff 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -471,13 +471,27 @@ protected: ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles, LocalPoolDataSetBase* dataSet = nullptr, size_t replyLen = 0, bool periodic = false); + /** - * @brief A simple command to add a command to the commandList. + * @brief A simple command to add a command to the commandList. * @param deviceCommand The command to add * @return - @c RETURN_OK when the command was successfully inserted, * - @c RETURN_FAILED else. */ ReturnValue_t insertInCommandMap(DeviceCommandId_t deviceCommand); + + /** + * @brief This function returns the reply length of the next reply to read. + * + * @param deviceCommand The command which triggered the device reply. + * + * @details The default implementation assumes only one reply is triggered by the command. In + * case the command triggers multiple replies (e.g. one acknowledgment, one data, + * and one execution status reply), this function can be overwritten to get the + * reply length of the next reply to read. + */ + virtual size_t getNextReplyLength(DeviceCommandId_t deviceCommand); + /** * @brief This is a helper method to facilitate updating entries * in the reply map. @@ -953,7 +967,7 @@ protected: * - NO_REPLY_EXPECTED if there was no reply found. This is not an * error case as many commands do not expect a reply. */ - virtual ReturnValue_t enableReplyInReplyMap(DeviceCommandMap::iterator cmd, + virtual ReturnValue_t enableReplyInReplyMap(DeviceCommandMap::iterator command, uint8_t expectedReplies = 1, bool useAlternateId = false, DeviceCommandId_t alternateReplyID = 0); From 56d43f5b49c0a737e4604238dfe8ce0988ed4b04 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 24 Apr 2021 22:46:12 +0200 Subject: [PATCH 194/230] better output --- objectmanager/ObjectManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/objectmanager/ObjectManager.cpp b/objectmanager/ObjectManager.cpp index 3c2be532..674fedc1 100644 --- a/objectmanager/ObjectManager.cpp +++ b/objectmanager/ObjectManager.cpp @@ -108,9 +108,9 @@ void ObjectManager::initialize() { result = it.second->checkObjectConnections(); if ( result != RETURN_OK ) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "ObjectManager::ObjectManager: Object " << std::hex << - (int) it.first << " connection check failed with code 0x" - << result << std::dec << std::endl; + sif::error << "ObjectManager::ObjectManager: Object 0x" << std::hex << + (int) it.first << " connection check failed with code 0x" << result << + std::dec << std::endl; #endif errorCount++; } From ff33a1274daf1af83832501036f2adbb807ba690 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 24 Apr 2021 23:54:13 +0200 Subject: [PATCH 195/230] deleted old bridge --- osal/linux/TmTcUnixUdpBridge.cpp | 157 ------------------------------- osal/linux/TmTcUnixUdpBridge.h | 49 ---------- 2 files changed, 206 deletions(-) delete mode 100644 osal/linux/TmTcUnixUdpBridge.cpp delete mode 100644 osal/linux/TmTcUnixUdpBridge.h diff --git a/osal/linux/TmTcUnixUdpBridge.cpp b/osal/linux/TmTcUnixUdpBridge.cpp deleted file mode 100644 index 62ac41c0..00000000 --- a/osal/linux/TmTcUnixUdpBridge.cpp +++ /dev/null @@ -1,157 +0,0 @@ -#include "TmTcUnixUdpBridge.h" -#include "../common/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_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 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; -} diff --git a/osal/linux/TmTcUnixUdpBridge.h b/osal/linux/TmTcUnixUdpBridge.h deleted file mode 100644 index fd932714..00000000 --- a/osal/linux/TmTcUnixUdpBridge.h +++ /dev/null @@ -1,49 +0,0 @@ -#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 UdpTcPollingTask; -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); - -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; - - //! 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_ */ From 87fee9bd0e8e59d762ae7885fb6918505072201c Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" Date: Sun, 25 Apr 2021 11:40:04 +0200 Subject: [PATCH 196/230] dhb multiple replies support --- devicehandlers/DeviceHandlerBase.cpp | 36 ++++++++++++++++++---------- devicehandlers/DeviceHandlerBase.h | 18 ++++++++++++-- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 531a0642..4e457016 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -308,6 +308,14 @@ void DeviceHandlerBase::doStateMachine() { uint32_t currentUptime; Clock::getUptime(¤tUptime); if (currentUptime - timeoutStart >= childTransitionDelay) { +#if FSFW_VERBOSE_LEVEL >= 1 + char printout[60]; + sprintf(printout, "Transition timeout (%lu) occured !", + static_cast(childTransitionDelay)); + /* Very common configuration error, so print it */ + printWarningOrError(sif::OutputTypes::OUT_WARNING, "doStateMachine", + RETURN_FAILED, printout); +#endif triggerEvent(MODE_TRANSITION_FAILED, childTransitionFailure, 0); setMode(transitionSourceMode, transitionSourceSubMode); break; @@ -448,6 +456,15 @@ ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceComm } } +size_t DeviceHandlerBase::getNextReplyLength(DeviceCommandId_t commandId){ + DeviceReplyIter iter = deviceReplyMap.find(commandId); + if(iter != deviceReplyMap.end()) { + return iter->second.replyLen; + }else{ + return 0; + } +} + ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceReply, uint16_t delayCycles, uint16_t maxDelayCycles, bool periodic) { auto replyIter = deviceReplyMap.find(deviceReply); @@ -638,16 +655,12 @@ void DeviceHandlerBase::doGetWrite() { void DeviceHandlerBase::doSendRead() { ReturnValue_t result; - size_t requestLen = 0; + size_t replyLen = 0; if(cookieInfo.pendingCommand != deviceCommandMap.end()) { - DeviceReplyIter iter = deviceReplyMap.find( - cookieInfo.pendingCommand->first); - if(iter != deviceReplyMap.end()) { - requestLen = iter->second.replyLen; - } + replyLen = getNextReplyLength(cookieInfo.pendingCommand->first); } - result = communicationInterface->requestReceiveMessage(comCookie, requestLen); + result = communicationInterface->requestReceiveMessage(comCookie, replyLen); if (result == RETURN_OK) { cookieInfo.state = COOKIE_READ_SENT; @@ -1501,10 +1514,9 @@ void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType, if(errorType == sif::OutputTypes::OUT_WARNING) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "DeviceHandlerBase::" << functionName << ": Object ID " - << std::hex << std::setw(8) << std::setfill('0') - << this->getObjectId() << " | " << errorPrint << std::dec - << std::setfill(' ') << std::endl; + sif::warning << "DeviceHandlerBase::" << functionName << ": Object ID 0x" << std::hex << + std::setw(8) << std::setfill('0') << this->getObjectId() << " | " << errorPrint << + std::dec << std::setfill(' ') << std::endl; #else sif::printWarning("DeviceHandlerBase::%s: Object ID 0x%08x | %s\n", functionName, this->getObjectId(), errorPrint); @@ -1512,7 +1524,7 @@ void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType, } else if(errorType == sif::OutputTypes::OUT_ERROR) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "DeviceHandlerBase::" << functionName << ": Object ID " + sif::error << "DeviceHandlerBase::" << functionName << ": Object ID 0x" << std::hex << std::setw(8) << std::setfill('0') << this->getObjectId() << " | " << errorPrint << std::dec << std::setfill(' ') << std::endl; diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index d61b0407..496c08ff 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -471,13 +471,27 @@ protected: ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles, LocalPoolDataSetBase* dataSet = nullptr, size_t replyLen = 0, bool periodic = false); + /** - * @brief A simple command to add a command to the commandList. + * @brief A simple command to add a command to the commandList. * @param deviceCommand The command to add * @return - @c RETURN_OK when the command was successfully inserted, * - @c RETURN_FAILED else. */ ReturnValue_t insertInCommandMap(DeviceCommandId_t deviceCommand); + + /** + * @brief This function returns the reply length of the next reply to read. + * + * @param deviceCommand The command which triggered the device reply. + * + * @details The default implementation assumes only one reply is triggered by the command. In + * case the command triggers multiple replies (e.g. one acknowledgment, one data, + * and one execution status reply), this function can be overwritten to get the + * reply length of the next reply to read. + */ + virtual size_t getNextReplyLength(DeviceCommandId_t deviceCommand); + /** * @brief This is a helper method to facilitate updating entries * in the reply map. @@ -953,7 +967,7 @@ protected: * - NO_REPLY_EXPECTED if there was no reply found. This is not an * error case as many commands do not expect a reply. */ - virtual ReturnValue_t enableReplyInReplyMap(DeviceCommandMap::iterator cmd, + virtual ReturnValue_t enableReplyInReplyMap(DeviceCommandMap::iterator command, uint8_t expectedReplies = 1, bool useAlternateId = false, DeviceCommandId_t alternateReplyID = 0); From 413ff0d1b9f0a0ed172ff1b427aab8f3f8d40a16 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Apr 2021 14:17:57 +0200 Subject: [PATCH 197/230] parameter wrapper bugfix --- parameters/ParameterHelper.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/parameters/ParameterHelper.cpp b/parameters/ParameterHelper.cpp index 24d0b2b1..e80c2c47 100644 --- a/parameters/ParameterHelper.cpp +++ b/parameters/ParameterHelper.cpp @@ -65,6 +65,9 @@ ReturnValue_t ParameterHelper::handleParameterMessage(CommandMessage *message) { ParameterWrapper ownerWrapper; result = owner->getParameter(domain, uniqueIdentifier, &ownerWrapper, &streamWrapper, linearIndex); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } result = ownerWrapper.copyFrom(&streamWrapper, linearIndex); if (result != HasReturnvaluesIF::RETURN_OK) { From 818634755d21e908c3e54e53ceb7907ac3999401 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Apr 2021 15:47:49 +0200 Subject: [PATCH 198/230] checking returnvalue now --- parameters/ParameterHelper.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/parameters/ParameterHelper.cpp b/parameters/ParameterHelper.cpp index 24d0b2b1..e80c2c47 100644 --- a/parameters/ParameterHelper.cpp +++ b/parameters/ParameterHelper.cpp @@ -65,6 +65,9 @@ ReturnValue_t ParameterHelper::handleParameterMessage(CommandMessage *message) { ParameterWrapper ownerWrapper; result = owner->getParameter(domain, uniqueIdentifier, &ownerWrapper, &streamWrapper, linearIndex); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } result = ownerWrapper.copyFrom(&streamWrapper, linearIndex); if (result != HasReturnvaluesIF::RETURN_OK) { From 054de9781b28b511167cfc2a9d21c79831eef2b9 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 27 Apr 2021 14:17:27 +0200 Subject: [PATCH 199/230] avoid duplicate printout --- devicehandlers/DeviceHandlerBase.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 4e457016..1623a1ac 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -308,11 +308,11 @@ void DeviceHandlerBase::doStateMachine() { uint32_t currentUptime; Clock::getUptime(¤tUptime); if (currentUptime - timeoutStart >= childTransitionDelay) { -#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_VERBOSE_LEVEL >= 1 && FSFW_OBJ_EVENT_TRANSLATION == 0 char printout[60]; sprintf(printout, "Transition timeout (%lu) occured !", static_cast(childTransitionDelay)); - /* Very common configuration error, so print it */ + /* Common configuration error for development, so print it */ printWarningOrError(sif::OutputTypes::OUT_WARNING, "doStateMachine", RETURN_FAILED, printout); #endif From 097244bf8b429d1b107343a3dbd77fa537a9c86d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 29 Apr 2021 19:51:38 +0200 Subject: [PATCH 200/230] use timestamp size from FSFWConfig.h --- timemanager/TimeStamperIF.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/timemanager/TimeStamperIF.h b/timemanager/TimeStamperIF.h index 57b7f014..534cc734 100644 --- a/timemanager/TimeStamperIF.h +++ b/timemanager/TimeStamperIF.h @@ -2,6 +2,7 @@ #define FSFW_TIMEMANAGER_TIMESTAMPERIF_H_ #include "../returnvalues/HasReturnvaluesIF.h" +#include /** * A class implementing this IF provides facilities to add a time stamp to the @@ -16,8 +17,7 @@ public: //! This is a mission-specific constant and determines the total //! size reserved for timestamps. - //! TODO: Default define in FSFWConfig ? - static const uint8_t MISSION_TIMESTAMP_SIZE = 8; + static const uint8_t MISSION_TIMESTAMP_SIZE = fsfwconfig::FSFW_MISSION_TIMESTAMP_SIZE; virtual ReturnValue_t addTimeStamp(uint8_t* buffer, const uint8_t maxSize) = 0; virtual ~TimeStamperIF() {} From f3530d3c7ede036e02a65963fcf36da4e5dc024a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 30 Apr 2021 23:59:45 +0200 Subject: [PATCH 201/230] small format change for event to test --- datalinklayer/DataLinkLayer.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/datalinklayer/DataLinkLayer.h b/datalinklayer/DataLinkLayer.h index 17a57d61..27e69006 100644 --- a/datalinklayer/DataLinkLayer.h +++ b/datalinklayer/DataLinkLayer.h @@ -19,7 +19,8 @@ class VirtualChannelReception; class DataLinkLayer : public CCSDSReturnValuesIF { public: static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_1; - static const Event RF_AVAILABLE = MAKE_EVENT(0, severity::INFO); //!< A RF available signal was detected. P1: raw RFA state, P2: 0 + //! [EXPORT] : [COMMENT] A RF available signal was detected. P1: raw RFA state, P2: 0 + static const Event RF_AVAILABLE = MAKE_EVENT(0, severity::INFO); static const Event RF_LOST = MAKE_EVENT(1, severity::INFO); //!< A previously found RF available signal was lost. P1: raw RFA state, P2: 0 static const Event BIT_LOCK = MAKE_EVENT(2, severity::INFO); //!< A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0 static const Event BIT_LOCK_LOST = MAKE_EVENT(3, severity::INFO); //!< A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0 From 126def219b30b1ca97c8fbc03825ed139e2a56ec Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 5 May 2021 12:59:42 +0200 Subject: [PATCH 202/230] continued tmtc server and bridge --- osal/common/CMakeLists.txt | 1 + osal/common/TcpTmTcBridge.cpp | 57 ++++++++++++ osal/common/TcpTmTcBridge.h | 54 +++++++++++ osal/common/TcpTmTcServer.cpp | 152 +++++++++++++++++++++++-------- osal/common/TcpTmTcServer.h | 26 +++++- osal/common/UdpTcPollingTask.cpp | 4 +- osal/common/UdpTcPollingTask.h | 8 +- osal/common/UdpTmTcBridge.cpp | 21 ++--- osal/common/UdpTmTcBridge.h | 6 +- osal/common/tcpipCommon.cpp | 3 + osal/common/tcpipCommon.h | 3 +- 11 files changed, 270 insertions(+), 65 deletions(-) create mode 100644 osal/common/TcpTmTcBridge.cpp create mode 100644 osal/common/TcpTmTcBridge.h diff --git a/osal/common/CMakeLists.txt b/osal/common/CMakeLists.txt index af76484d..b7c8c033 100644 --- a/osal/common/CMakeLists.txt +++ b/osal/common/CMakeLists.txt @@ -5,6 +5,7 @@ if(DEFINED WIN32 OR DEFINED UNIX) UdpTcPollingTask.cpp UdpTmTcBridge.cpp TcpTmTcServer.cpp + TcpTmTcBridge.cpp ) endif() diff --git a/osal/common/TcpTmTcBridge.cpp b/osal/common/TcpTmTcBridge.cpp new file mode 100644 index 00000000..a88b68e9 --- /dev/null +++ b/osal/common/TcpTmTcBridge.cpp @@ -0,0 +1,57 @@ +#include "TcpTmTcBridge.h" +#include "tcpipHelpers.h" + +#include +#include +#include + +#ifdef _WIN32 + +#include + +#elif defined(__unix__) + +#include +#include + +#endif + +const std::string TcpTmTcBridge::DEFAULT_UDP_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; + +TcpTmTcBridge::TcpTmTcBridge(object_id_t objectId, object_id_t tcDestination, + object_id_t tmStoreId, object_id_t tcStoreId): + TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) { + mutex = MutexFactory::instance()->createMutex(); + communicationLinkUp = false; +} + +ReturnValue_t TcpTmTcBridge::initialize() { + ReturnValue_t result = TmTcBridge::initialize(); + if(result != HasReturnvaluesIF::RETURN_OK) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "TmTcUdpBridge::initialize: TmTcBridge initialization failed!" + << std::endl; +#endif + return result; + } + + return HasReturnvaluesIF::RETURN_OK; +} + +TcpTmTcBridge::~TcpTmTcBridge() { + if(mutex != nullptr) { + MutexFactory::instance()->deleteMutex(mutex); + } +} + +ReturnValue_t TcpTmTcBridge::sendTm(const uint8_t *data, size_t dataLen) { + + return HasReturnvaluesIF::RETURN_OK; +} + + +void TcpTmTcBridge::setMutexProperties(MutexIF::TimeoutType timeoutType, + dur_millis_t timeoutMs) { + this->timeoutType = timeoutType; + this->mutexTimeoutMs = timeoutMs; +} diff --git a/osal/common/TcpTmTcBridge.h b/osal/common/TcpTmTcBridge.h new file mode 100644 index 00000000..db45fca8 --- /dev/null +++ b/osal/common/TcpTmTcBridge.h @@ -0,0 +1,54 @@ +#ifndef FSFW_OSAL_COMMON_TCPTMTCBRIDGE_H_ +#define FSFW_OSAL_COMMON_TCPTMTCBRIDGE_H_ + +#include "TcpIpBase.h" +#include "../../tmtcservices/TmTcBridge.h" + +#ifdef _WIN32 + +#include + +#elif defined(__unix__) + +#include + +#endif + +#include + +/** + * @brief This class should be used with the UdpTcPollingTask to implement a UDP server + * for receiving and sending PUS TMTC. + */ +class TcpTmTcBridge: + public TmTcBridge { + //friend class UdpTcPollingTask; +public: + /* The ports chosen here should not be used by any other process. */ + static const std::string DEFAULT_UDP_SERVER_PORT; + + TcpTmTcBridge(object_id_t objectId, object_id_t tcDestination, + object_id_t tmStoreId = objects::TM_STORE, + object_id_t tcStoreId = objects::TC_STORE); + virtual~ TcpTmTcBridge(); + + /** + * Set properties of internal mutex. + */ + void setMutexProperties(MutexIF::TimeoutType timeoutType, dur_millis_t timeoutMs); + + ReturnValue_t initialize() override; + +protected: + virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override; + +private: + + //! 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 /* FSFW_OSAL_COMMON_TCPTMTCBRIDGE_H_ */ + diff --git a/osal/common/TcpTmTcServer.cpp b/osal/common/TcpTmTcServer.cpp index 08a62ffb..8717783e 100644 --- a/osal/common/TcpTmTcServer.cpp +++ b/osal/common/TcpTmTcServer.cpp @@ -1,6 +1,12 @@ #include "TcpTmTcServer.h" +#include "TcpTmTcBridge.h" #include "tcpipHelpers.h" + +#include "../../container/SharedRingBuffer.h" +#include "../../ipc/MessageQueueSenderIF.h" +#include "../../objectmanager/ObjectManagerIF.h" #include "../../serviceinterface/ServiceInterface.h" +#include "../../tmtcservices/TmTcMessage.h" #ifdef _WIN32 #include @@ -12,12 +18,17 @@ #endif -const std::string TcpTmTcServer::DEFAULT_TCP_SERVER_PORT = "7301"; -const std::string TcpTmTcServer::DEFAULT_TCP_CLIENT_PORT = "7302"; +#ifndef FSFW_TCP_RECV_WIRETAPPING_ENABLED +#define FSFW_TCP_RECV_WIRETAPPING_ENABLED 0 +#endif -TcpTmTcServer::TcpTmTcServer(object_id_t objectId, object_id_t tmtcUnixUdpBridge, +const std::string TcpTmTcServer::DEFAULT_TCP_SERVER_PORT = "7301"; + +TcpTmTcServer::TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge, + /*SharedRingBuffer* tcpRingBuffer, */ size_t receptionBufferSize, std::string customTcpServerPort): - SystemObject(objectId), tcpPort(customTcpServerPort) { + SystemObject(objectId), tmtcBridgeId(tmtcTcpBridge), tcpPort(customTcpServerPort), + receptionBuffer(receptionBufferSize) /*, tcpRingBuffer(tcpRingBuffer) */ { if(tcpPort == "") { tcpPort = DEFAULT_TCP_SERVER_PORT; } @@ -26,11 +37,34 @@ TcpTmTcServer::TcpTmTcServer(object_id_t objectId, object_id_t tmtcUnixUdpBridge ReturnValue_t TcpTmTcServer::initialize() { using namespace tcpip; + /* + if(tcpRingBuffer == nullptr) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "TcpTmTcServer::initialize: Invalid ring buffer!" << std::endl; +#else + sif::printError("TcpTmTcServer::initialize: Invalid ring buffer!\n"); +#endif + return ObjectManagerIF::CHILD_INIT_FAILED; + } + */ + ReturnValue_t result = TcpIpBase::initialize(); if(result != HasReturnvaluesIF::RETURN_OK) { return result; } + tcStore = objectManager->get(objects::TC_STORE); + if (tcStore == nullptr) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "TcpTmTcServer::initialize: TC store uninitialized!" << std::endl; +#else + sif::printError("TcpTmTcServer::initialize: TC store uninitialized!\n"); +#endif + return ObjectManagerIF::CHILD_INIT_FAILED; + } + + tmtcBridge = objectManager->get(tmtcBridgeId); + int retval = 0; struct addrinfo *addrResult = nullptr; struct addrinfo hints = {}; @@ -42,10 +76,6 @@ ReturnValue_t TcpTmTcServer::initialize() { retval = getaddrinfo(nullptr, tcpPort.c_str(), &hints, &addrResult); if (retval != 0) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "TcWinTcpServer::TcpTmTcServer: Retrieving address info failed!" << - std::endl; -#endif handleError(Protocol::TCP, ErrorSources::GETADDRINFO_CALL); return HasReturnvaluesIF::RETURN_FAILED; } @@ -54,9 +84,6 @@ ReturnValue_t TcpTmTcServer::initialize() { 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(Protocol::TCP, ErrorSources::SOCKET_CALL); return HasReturnvaluesIF::RETURN_FAILED; @@ -64,10 +91,6 @@ ReturnValue_t TcpTmTcServer::initialize() { retval = bind(listenerTcpSocket, addrResult->ai_addr, static_cast(addrResult->ai_addrlen)); if(retval == SOCKET_ERROR) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "TcWinTcpServer::TcpTmTcServer: Binding socket failed!" << - std::endl; -#endif freeaddrinfo(addrResult); handleError(Protocol::TCP, ErrorSources::BIND_CALL); return HasReturnvaluesIF::RETURN_FAILED; @@ -85,7 +108,7 @@ TcpTmTcServer::~TcpTmTcServer() { 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_t clientSocket = 0; + socket_t connSocket = 0; sockaddr clientSockAddr = {}; socklen_t connectorSockAddrLen = 0; int retval = 0; @@ -98,35 +121,92 @@ ReturnValue_t TcpTmTcServer::performOperation(uint8_t opCode) { continue; } - clientSocket = accept(listenerTcpSocket, &clientSockAddr, &connectorSockAddrLen); + connSocket = accept(listenerTcpSocket, &clientSockAddr, &connectorSockAddrLen); - if(clientSocket == INVALID_SOCKET) { + if(connSocket == INVALID_SOCKET) { handleError(Protocol::TCP, ErrorSources::ACCEPT_CALL, 500); - closeSocket(clientSocket); + closeSocket(connSocket); continue; }; - retval = recv(clientSocket, reinterpret_cast(receptionBuffer.data()), - receptionBuffer.size(), 0); - if(retval > 0) { -#if FSFW_TCP_RCV_WIRETAPPING_ENABLED == 1 - sif::info << "TcpTmTcServer::performOperation: Received " << retval << " bytes." - std::endl; -#endif - handleError(Protocol::TCP, ErrorSources::RECV_CALL, 500); - } - else if(retval == 0) { - - } - else { - - } + handleServerOperation(connSocket); /* Done, shut down connection */ - retval = shutdown(clientSocket, SHUT_SEND); - closeSocket(clientSocket); + retval = shutdown(connSocket, SHUT_SEND); + if(retval != 0) { + handleError(Protocol::TCP, ErrorSources::SHUTDOWN_CALL); + } + closeSocket(connSocket); } return HasReturnvaluesIF::RETURN_OK; } +ReturnValue_t TcpTmTcServer::initializeAfterTaskCreation() { + /* Initialize the destination after task creation. This ensures + that the destination has already been set in the TMTC bridge. */ + targetTcDestination = tmtcBridge->getRequestQueue(); +// +// if(tcpRingBuffer != nullptr) { +// auto fifoCheck = tcpRingBuffer->getReceiveSizesFIFO(); +// if (fifoCheck == nullptr) { +//#if FSFW_CPP_OSTREAM_ENABLED == 1 +// sif::error << "TcpTmTcServer::initializeAfterTaskCreation: " +// "TCP ring buffer does not have a FIFO!" << std::endl; +//#else +// sif::printError("TcpTmTcServer::initialize: TCP ring buffer does not have a FIFO!\n"); +//#endif /* FSFW_CPP_OSTREAM_ENABLED == 0 */ +// } +// } + + return HasReturnvaluesIF::RETURN_OK; +} + +void TcpTmTcServer::handleServerOperation(socket_t connSocket) { + int retval = 0; + do { + retval = recv(connSocket, + reinterpret_cast(receptionBuffer.data()), + receptionBuffer.capacity(), + tcpFlags); + if (retval > 0) { + handleTcReception(retval); + } + else if(retval == 0) { + /* Client has finished sending telecommands, send telemetry now */ + } + else { + /* Should not happen */ + } + } while(retval > 0); +} + +ReturnValue_t TcpTmTcServer::handleTcReception(size_t bytesRecvd) { +#if FSFW_TCP_RECV_WIRETAPPING_ENABLED == 1 + arrayprinter::print(receptionBuffer.data(), bytesRead); +#endif + store_address_t storeId; + ReturnValue_t result = tcStore->addData(&storeId, receptionBuffer.data(), bytesRecvd); + if (result != HasReturnvaluesIF::RETURN_OK) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning<< "TcpTmTcServer::handleServerOperation: Data storage failed." << std::endl; + sif::warning << "Packet size: " << bytesRecvd << std::endl; +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + } + + 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::warning << "UdpTcPollingTask::handleSuccessfullTcRead: " + " Sending message to queue failed" << std::endl; +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + tcStore->deleteData(storeId); + } + return result; +} diff --git a/osal/common/TcpTmTcServer.h b/osal/common/TcpTmTcServer.h index 4dcc77a2..6db6621d 100644 --- a/osal/common/TcpTmTcServer.h +++ b/osal/common/TcpTmTcServer.h @@ -2,7 +2,11 @@ #define FSFW_OSAL_WINDOWS_TCWINTCPSERVER_H_ #include "TcpIpBase.h" +#include "../../ipc/messageQueueDefinitions.h" +#include "../../ipc/MessageQueueIF.h" +#include "../../objectmanager/frameworkObjects.h" #include "../../objectmanager/SystemObject.h" +#include "../../storagemanager/StorageManagerIF.h" #include "../../tasks/ExecutableObjectIF.h" #ifdef __unix__ @@ -12,8 +16,9 @@ #include #include -//! Debugging preprocessor define. -#define FSFW_TCP_RCV_WIRETAPPING_ENABLED 0 +class TcpTmTcBridge; +//class SharedRingBuffer; + /** * @brief Windows TCP server used to receive telecommands on a Windows Host @@ -28,26 +33,39 @@ 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; + static constexpr size_t ETHERNET_MTU_SIZE = 1500; - TcpTmTcServer(object_id_t objectId, object_id_t tmtcUnixUdpBridge, + TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge /*, SharedRingBuffer* tcpRingBuffer*/, + size_t receptionBufferSize = ETHERNET_MTU_SIZE, std::string customTcpServerPort = ""); virtual~ TcpTmTcServer(); ReturnValue_t initialize() override; ReturnValue_t performOperation(uint8_t opCode) override; + ReturnValue_t initializeAfterTaskCreation() override; + +protected: + StorageManagerIF* tcStore = nullptr; private: + //! TMTC bridge is cached. + object_id_t tmtcBridgeId = objects::NO_OBJECT; + TcpTmTcBridge* tmtcBridge = nullptr; std::string tcpPort; + int tcpFlags = 0; socket_t listenerTcpSocket = 0; struct sockaddr tcpAddress; + MessageQueueId_t targetTcDestination = MessageQueueIF::NO_QUEUE; int tcpAddrLen = sizeof(tcpAddress); int currentBacklog = 3; std::vector receptionBuffer; + //SharedRingBuffer* tcpRingBuffer; int tcpSockOpt = 0; - + void handleServerOperation(socket_t connSocket); + ReturnValue_t handleTcReception(size_t bytesRecvd); }; #endif /* FSFW_OSAL_WINDOWS_TCWINTCPSERVER_H_ */ diff --git a/osal/common/UdpTcPollingTask.cpp b/osal/common/UdpTcPollingTask.cpp index 47f67b29..d79e2447 100644 --- a/osal/common/UdpTcPollingTask.cpp +++ b/osal/common/UdpTcPollingTask.cpp @@ -18,9 +18,9 @@ #define FSFW_UDP_RECV_WIRETAPPING_ENABLED 0 UdpTcPollingTask::UdpTcPollingTask(object_id_t objectId, - object_id_t tmtcUnixUdpBridge, size_t maxRecvSize, + object_id_t tmtcUdpBridge, size_t maxRecvSize, double timeoutSeconds): SystemObject(objectId), - tmtcBridgeId(tmtcUnixUdpBridge) { + tmtcBridgeId(tmtcUdpBridge) { if(frameSize > 0) { this->frameSize = frameSize; } diff --git a/osal/common/UdpTcPollingTask.h b/osal/common/UdpTcPollingTask.h index 052eced5..cfe74b34 100644 --- a/osal/common/UdpTcPollingTask.h +++ b/osal/common/UdpTcPollingTask.h @@ -1,5 +1,5 @@ -#ifndef FSFW_OSAL_WINDOWS_TCSOCKETPOLLINGTASK_H_ -#define FSFW_OSAL_WINDOWS_TCSOCKETPOLLINGTASK_H_ +#ifndef FSFW_OSAL_COMMON_UDPTCPOLLINGTASK_H_ +#define FSFW_OSAL_COMMON_UDPTCPOLLINGTASK_H_ #include "UdpTmTcBridge.h" #include "../../objectmanager/SystemObject.h" @@ -22,7 +22,7 @@ public: //! 0.5 default milliseconds timeout for now. static constexpr timeval DEFAULT_TIMEOUT = {0, 500}; - UdpTcPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge, + UdpTcPollingTask(object_id_t objectId, object_id_t tmtcUdpBridge, size_t maxRecvSize = 0, double timeoutSeconds = -1); virtual~ UdpTcPollingTask(); @@ -57,4 +57,4 @@ private: ReturnValue_t handleSuccessfullTcRead(size_t bytesRead); }; -#endif /* FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_ */ +#endif /* FSFW_OSAL_COMMON_UDPTCPOLLINGTASK_H_ */ diff --git a/osal/common/UdpTmTcBridge.cpp b/osal/common/UdpTmTcBridge.cpp index ba23f521..ccbb194e 100644 --- a/osal/common/UdpTmTcBridge.cpp +++ b/osal/common/UdpTmTcBridge.cpp @@ -16,7 +16,9 @@ #endif //! Debugging preprocessor define. +#ifndef FSFW_UDP_SEND_WIRETAPPING_ENABLED #define FSFW_UDP_SEND_WIRETAPPING_ENABLED 0 +#endif const std::string UdpTmTcBridge::DEFAULT_UDP_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; @@ -38,7 +40,7 @@ ReturnValue_t UdpTmTcBridge::initialize() { ReturnValue_t result = TmTcBridge::initialize(); if(result != HasReturnvaluesIF::RETURN_OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TmTcUdpBridge::initialize: TmTcBridge initialization failed!" + sif::error << "UdpTmTcBridge::initialize: TmTcBridge initialization failed!" << std::endl; #endif return result; @@ -54,10 +56,10 @@ ReturnValue_t UdpTmTcBridge::initialize() { /* Tell the user that we could not find a usable */ /* Winsock DLL. */ #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TmTcUdpBridge::TmTcUdpBridge: WSAStartup failed with error: " << + sif::error << "UdpTmTcBridge::UdpTmTcBridge: WSAStartup failed with error: " << err << std::endl; #else - sif::printError("TmTcUdpBridge::TmTcUdpBridge: WSAStartup failed with error: %d\n", + sif::printError("UdpTmTcBridge::UdpTmTcBridge: WSAStartup failed with error: %d\n", err); #endif return HasReturnvaluesIF::RETURN_FAILED; @@ -78,19 +80,12 @@ ReturnValue_t UdpTmTcBridge::initialize() { 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 << "TmTcUdpBridge::TmTcUdpBridge: Retrieving address info failed!" << - std::endl; -#endif + tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::GETADDRINFO_CALL); 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 << "TmTcUdpBridge::TmTcUdpBridge: Could not open UDP socket!" << - std::endl; -#endif freeaddrinfo(addrResult); tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::SOCKET_CALL); return HasReturnvaluesIF::RETURN_FAILED; @@ -102,10 +97,6 @@ ReturnValue_t UdpTmTcBridge::initialize() { retval = bind(serverSocket, addrResult->ai_addr, static_cast(addrResult->ai_addrlen)); if(retval != 0) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TmTcUdpBridge::TmTcUdpBridge: Could not bind " - "local port (" << udpServerPort << ") to server socket!" << std::endl; -#endif freeaddrinfo(addrResult); tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::BIND_CALL); return HasReturnvaluesIF::RETURN_FAILED; diff --git a/osal/common/UdpTmTcBridge.h b/osal/common/UdpTmTcBridge.h index 8b8d1949..290f5eb0 100644 --- a/osal/common/UdpTmTcBridge.h +++ b/osal/common/UdpTmTcBridge.h @@ -1,5 +1,5 @@ -#ifndef FSFW_OSAL_WINDOWS_TMTCWINUDPBRIDGE_H_ -#define FSFW_OSAL_WINDOWS_TMTCWINUDPBRIDGE_H_ +#ifndef FSFW_OSAL_COMMON_TMTCUDPBRIDGE_H_ +#define FSFW_OSAL_COMMON_TMTCUDPBRIDGE_H_ #include "TcpIpBase.h" #include "../../tmtcservices/TmTcBridge.h" @@ -56,5 +56,5 @@ private: MutexIF* mutex; }; -#endif /* FSFW_OSAL_HOST_TMTCWINUDPBRIDGE_H_ */ +#endif /* FSFW_OSAL_COMMON_TMTCUDPBRIDGE_H_ */ diff --git a/osal/common/tcpipCommon.cpp b/osal/common/tcpipCommon.cpp index 551e2a42..d4a3e8e6 100644 --- a/osal/common/tcpipCommon.cpp +++ b/osal/common/tcpipCommon.cpp @@ -35,6 +35,9 @@ void tcpip::determineErrorStrings(Protocol protocol, ErrorSources errorSrc, std: else if(errorSrc == ErrorSources::GETADDRINFO_CALL) { srcString = "getaddrinfo call"; } + else if(errorSrc == ErrorSources::SHUTDOWN_CALL) { + srcString = "shutdown call"; + } else { srcString = "unknown call"; } diff --git a/osal/common/tcpipCommon.h b/osal/common/tcpipCommon.h index 22b914dc..eb1bd910 100644 --- a/osal/common/tcpipCommon.h +++ b/osal/common/tcpipCommon.h @@ -29,7 +29,8 @@ enum class ErrorSources { RECVFROM_CALL, LISTEN_CALL, ACCEPT_CALL, - SENDTO_CALL + SENDTO_CALL, + SHUTDOWN_CALL }; void determineErrorStrings(Protocol protocol, ErrorSources errorSrc, std::string& protStr, From c1d30aad13753591b57db9e549333a596b606947 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 5 May 2021 15:59:41 +0200 Subject: [PATCH 203/230] TCP server implementation finished A lot of smaller tweaks and smaller refactoring done in UDP TMTC bridge as well --- osal/common/TcpTmTcBridge.cpp | 26 ++++++++-- osal/common/TcpTmTcBridge.h | 25 ++++++++-- osal/common/TcpTmTcServer.cpp | 86 ++++++++++++++++++++-------------- osal/common/TcpTmTcServer.h | 44 ++++++++++++----- osal/common/UdpTcPollingTask.h | 7 +-- osal/common/UdpTmTcBridge.cpp | 2 +- osal/common/UdpTmTcBridge.h | 10 +++- osal/common/tcpipCommon.cpp | 6 +++ osal/common/tcpipCommon.h | 1 + tmtcservices/TmTcBridge.cpp | 7 ++- tmtcservices/TmTcBridge.h | 3 +- 11 files changed, 152 insertions(+), 65 deletions(-) diff --git a/osal/common/TcpTmTcBridge.cpp b/osal/common/TcpTmTcBridge.cpp index a88b68e9..24fab9a9 100644 --- a/osal/common/TcpTmTcBridge.cpp +++ b/osal/common/TcpTmTcBridge.cpp @@ -22,15 +22,18 @@ TcpTmTcBridge::TcpTmTcBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId, object_id_t tcStoreId): TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) { mutex = MutexFactory::instance()->createMutex(); - communicationLinkUp = false; + // Connection is always up, TM is requested by connecting to server and receiving packets + registerCommConnect(); } ReturnValue_t TcpTmTcBridge::initialize() { ReturnValue_t result = TmTcBridge::initialize(); if(result != HasReturnvaluesIF::RETURN_OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TmTcUdpBridge::initialize: TmTcBridge initialization failed!" + sif::error << "TcpTmTcBridge::initialize: TmTcBridge initialization failed!" << std::endl; +#else + sif::printError("TcpTmTcBridge::initialize: TmTcBridge initialization failed!\n"); #endif return result; } @@ -44,8 +47,25 @@ TcpTmTcBridge::~TcpTmTcBridge() { } } -ReturnValue_t TcpTmTcBridge::sendTm(const uint8_t *data, size_t dataLen) { +ReturnValue_t TcpTmTcBridge::handleTm() { + // Simply store the telemetry in the FIFO, the server will use it to access the TM + MutexGuard guard(mutex, timeoutType, mutexTimeoutMs); + TmTcMessage message; + ReturnValue_t status = HasReturnvaluesIF::RETURN_OK; + for (ReturnValue_t result = tmTcReceptionQueue->receiveMessage(&message); + result == HasReturnvaluesIF::RETURN_OK; + result = tmTcReceptionQueue->receiveMessage(&message)) + { + status = storeDownlinkData(&message); + if(status != HasReturnvaluesIF::RETURN_OK) { + break; + } + } + return HasReturnvaluesIF::RETURN_OK; +} +ReturnValue_t TcpTmTcBridge::sendTm(const uint8_t *data, size_t dataLen) { + // Not used. The Server uses the FIFO to access and send the telemetry. return HasReturnvaluesIF::RETURN_OK; } diff --git a/osal/common/TcpTmTcBridge.h b/osal/common/TcpTmTcBridge.h index db45fca8..6cfacb9f 100644 --- a/osal/common/TcpTmTcBridge.h +++ b/osal/common/TcpTmTcBridge.h @@ -17,16 +17,30 @@ #include /** - * @brief This class should be used with the UdpTcPollingTask to implement a UDP server - * for receiving and sending PUS TMTC. + * @brief This class should be used with the TcpTmTcServer to implement a TCP server + * for receiving and sending PUS telemetry and telecommands (TMTC) + * @details + * This bridge tasks takes care of filling a FIFO which generated telemetry. The TcpTmTcServer + * will take care of sending the telemetry stored in the FIFO if a client connects to the + * server. This bridge will also be the default destination for telecommands, but the telecommands + * will be relayed to a specified tcDestination directly. */ class TcpTmTcBridge: public TmTcBridge { - //friend class UdpTcPollingTask; + friend class TcpTmTcServer; public: /* The ports chosen here should not be used by any other process. */ static const std::string DEFAULT_UDP_SERVER_PORT; + /** + * Constructor + * @param objectId Object ID of the TcpTmTcBridge. + * @param tcDestination Destination for received TC packets. Any received telecommands will + * be sent there directly. The destination object needs to implement + * AcceptsTelecommandsIF. + * @param tmStoreId TM store object ID. It is recommended to the default object ID + * @param tcStoreId TC store object ID. It is recommended to the default object ID + */ TcpTmTcBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId = objects::TM_STORE, object_id_t tcStoreId = objects::TC_STORE); @@ -39,12 +53,15 @@ public: ReturnValue_t initialize() override; + protected: + ReturnValue_t handleTm() override; virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override; private: - //! Access to the client address is mutex protected as it is set by another task. + //! Access to the FIFO needs to be mutex protected because it is used by the bridge and + //! the server. MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; dur_millis_t mutexTimeoutMs = 20; MutexIF* mutex; diff --git a/osal/common/TcpTmTcServer.cpp b/osal/common/TcpTmTcServer.cpp index 8717783e..25403e8b 100644 --- a/osal/common/TcpTmTcServer.cpp +++ b/osal/common/TcpTmTcServer.cpp @@ -4,6 +4,7 @@ #include "../../container/SharedRingBuffer.h" #include "../../ipc/MessageQueueSenderIF.h" +#include "../../ipc/MutexGuard.h" #include "../../objectmanager/ObjectManagerIF.h" #include "../../serviceinterface/ServiceInterface.h" #include "../../tmtcservices/TmTcMessage.h" @@ -25,10 +26,9 @@ const std::string TcpTmTcServer::DEFAULT_TCP_SERVER_PORT = "7301"; TcpTmTcServer::TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge, - /*SharedRingBuffer* tcpRingBuffer, */ size_t receptionBufferSize, - std::string customTcpServerPort): - SystemObject(objectId), tmtcBridgeId(tmtcTcpBridge), tcpPort(customTcpServerPort), - receptionBuffer(receptionBufferSize) /*, tcpRingBuffer(tcpRingBuffer) */ { + size_t receptionBufferSize, std::string customTcpServerPort): + SystemObject(objectId), tmtcBridgeId(tmtcTcpBridge), + tcpPort(customTcpServerPort), receptionBuffer(receptionBufferSize) { if(tcpPort == "") { tcpPort = DEFAULT_TCP_SERVER_PORT; } @@ -37,17 +37,6 @@ TcpTmTcServer::TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge, ReturnValue_t TcpTmTcServer::initialize() { using namespace tcpip; - /* - if(tcpRingBuffer == nullptr) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TcpTmTcServer::initialize: Invalid ring buffer!" << std::endl; -#else - sif::printError("TcpTmTcServer::initialize: Invalid ring buffer!\n"); -#endif - return ObjectManagerIF::CHILD_INIT_FAILED; - } - */ - ReturnValue_t result = TcpIpBase::initialize(); if(result != HasReturnvaluesIF::RETURN_OK) { return result; @@ -74,13 +63,14 @@ ReturnValue_t TcpTmTcServer::initialize() { hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_PASSIVE; + // Listen to all addresses (0.0.0.0) by using AI_PASSIVE in the hint flags retval = getaddrinfo(nullptr, tcpPort.c_str(), &hints, &addrResult); if (retval != 0) { handleError(Protocol::TCP, ErrorSources::GETADDRINFO_CALL); return HasReturnvaluesIF::RETURN_FAILED; } - /* Open TCP (stream) socket */ + // Open TCP (stream) socket listenerTcpSocket = socket(addrResult->ai_family, addrResult->ai_socktype, addrResult->ai_protocol); if(listenerTcpSocket == INVALID_SOCKET) { @@ -89,6 +79,7 @@ ReturnValue_t TcpTmTcServer::initialize() { return HasReturnvaluesIF::RETURN_FAILED; } + // Bind to the address found by getaddrinfo retval = bind(listenerTcpSocket, addrResult->ai_addr, static_cast(addrResult->ai_addrlen)); if(retval == SOCKET_ERROR) { freeaddrinfo(addrResult); @@ -107,15 +98,15 @@ TcpTmTcServer::~TcpTmTcServer() { 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 */ + // If a connection is accepted, the corresponding socket will be assigned to the new socket socket_t connSocket = 0; sockaddr clientSockAddr = {}; socklen_t connectorSockAddrLen = 0; int retval = 0; - /* Listen for connection requests permanently for lifetime of program */ + // Listen for connection requests permanently for lifetime of program while(true) { - retval = listen(listenerTcpSocket, currentBacklog); + retval = listen(listenerTcpSocket, tcpBacklog); if(retval == SOCKET_ERROR) { handleError(Protocol::TCP, ErrorSources::LISTEN_CALL, 500); continue; @@ -131,7 +122,7 @@ ReturnValue_t TcpTmTcServer::performOperation(uint8_t opCode) { handleServerOperation(connSocket); - /* Done, shut down connection */ + // Done, shut down connection and go back to listening for client requests retval = shutdown(connSocket, SHUT_SEND); if(retval != 0) { handleError(Protocol::TCP, ErrorSources::SHUTDOWN_CALL); @@ -142,29 +133,21 @@ ReturnValue_t TcpTmTcServer::performOperation(uint8_t opCode) { } ReturnValue_t TcpTmTcServer::initializeAfterTaskCreation() { + if(tmtcBridge == nullptr) { + return ObjectManagerIF::CHILD_INIT_FAILED; + } /* Initialize the destination after task creation. This ensures that the destination has already been set in the TMTC bridge. */ targetTcDestination = tmtcBridge->getRequestQueue(); - -// -// if(tcpRingBuffer != nullptr) { -// auto fifoCheck = tcpRingBuffer->getReceiveSizesFIFO(); -// if (fifoCheck == nullptr) { -//#if FSFW_CPP_OSTREAM_ENABLED == 1 -// sif::error << "TcpTmTcServer::initializeAfterTaskCreation: " -// "TCP ring buffer does not have a FIFO!" << std::endl; -//#else -// sif::printError("TcpTmTcServer::initialize: TCP ring buffer does not have a FIFO!\n"); -//#endif /* FSFW_CPP_OSTREAM_ENABLED == 0 */ -// } -// } - + tcStore = tmtcBridge->tcStore; + tmStore = tmtcBridge->tmStore; return HasReturnvaluesIF::RETURN_OK; } void TcpTmTcServer::handleServerOperation(socket_t connSocket) { int retval = 0; do { + // Read all telecommands sent by the client retval = recv(connSocket, reinterpret_cast(receptionBuffer.data()), receptionBuffer.capacity(), @@ -173,10 +156,12 @@ void TcpTmTcServer::handleServerOperation(socket_t connSocket) { handleTcReception(retval); } else if(retval == 0) { - /* Client has finished sending telecommands, send telemetry now */ + // Client has finished sending telecommands, send telemetry now + handleTmSending(connSocket); } else { - /* Should not happen */ + // Should not happen + tcpip::handleError(tcpip::Protocol::TCP, tcpip::ErrorSources::RECV_CALL); } } while(retval > 0); } @@ -210,3 +195,32 @@ ReturnValue_t TcpTmTcServer::handleTcReception(size_t bytesRecvd) { } return result; } + +void TcpTmTcServer::setTcpBacklog(uint8_t tcpBacklog) { + this->tcpBacklog = tcpBacklog; +} + +ReturnValue_t TcpTmTcServer::handleTmSending(socket_t connSocket) { + // Access to the FIFO is mutex protected because it is filled by the bridge + MutexGuard(tmtcBridge->mutex, tmtcBridge->timeoutType, tmtcBridge->mutexTimeoutMs); + store_address_t storeId; + while((not tmtcBridge->tmFifo->empty()) and + (tmtcBridge->packetSentCounter < tmtcBridge->sentPacketsPerCycle)) { + tmtcBridge->tmFifo->retrieve(&storeId); + + // Using the store accessor will take care of deleting TM from the store automatically + ConstStorageAccessor storeAccessor(storeId); + ReturnValue_t result = tmStore->getData(storeId, storeAccessor); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + int retval = send(connSocket, + reinterpret_cast(storeAccessor.data()), + storeAccessor.size(), + tcpTmFlags); + if(retval != static_cast(storeAccessor.size())) { + tcpip::handleError(tcpip::Protocol::TCP, tcpip::ErrorSources::SEND_CALL); + } + } + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/osal/common/TcpTmTcServer.h b/osal/common/TcpTmTcServer.h index 6db6621d..e4328370 100644 --- a/osal/common/TcpTmTcServer.h +++ b/osal/common/TcpTmTcServer.h @@ -1,5 +1,5 @@ -#ifndef FSFW_OSAL_WINDOWS_TCWINTCPSERVER_H_ -#define FSFW_OSAL_WINDOWS_TCWINTCPSERVER_H_ +#ifndef FSFW_OSAL_COMMON_TCP_TMTC_SERVER_H_ +#define FSFW_OSAL_COMMON_TCP_TMTC_SERVER_H_ #include "TcpIpBase.h" #include "../../ipc/messageQueueDefinitions.h" @@ -17,13 +17,22 @@ #include class TcpTmTcBridge; -//class SharedRingBuffer; - /** - * @brief Windows TCP server used to receive telecommands on a Windows Host + * @brief TCP server implementation * @details - * Based on: https://docs.microsoft.com/en-us/windows/win32/winsock/complete-server-code + * This server will run for the whole program lifetime and will take care of serving client + * requests on a specified TCP server port. This server waas written in a generic way and + * can be used on Unix and on Windows systems. + * + * If a connection is accepted, the server will read all telecommands sent by a client and then + * send all telemetry currently found in the TMTC bridge FIFO. + * + * Reading telemetry without sending telecommands is possible by connecting, shutting down the + * send operation immediately and then reading the telemetry. It is therefore recommended to + * connect to the server regularly, even if no telecommands need to be sent. + * + * The server will listen to a specific port on all addresses (0.0.0.0). */ class TcpTmTcServer: public SystemObject, @@ -35,18 +44,28 @@ public: static const std::string DEFAULT_TCP_CLIENT_PORT; static constexpr size_t ETHERNET_MTU_SIZE = 1500; - TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge /*, SharedRingBuffer* tcpRingBuffer*/, - size_t receptionBufferSize = ETHERNET_MTU_SIZE, + /** + * TCP Server Constructor + * @param objectId Object ID of the TCP Server + * @param tmtcTcpBridge Object ID of the TCP TMTC Bridge object + * @param receptionBufferSize This will be the size of the reception buffer. Default buffer + * size will be the Ethernet MTU size + * @param customTcpServerPort The user can specify another port than the default (7301) here. + */ + TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge, + size_t receptionBufferSize = ETHERNET_MTU_SIZE + 1, std::string customTcpServerPort = ""); virtual~ TcpTmTcServer(); + void setTcpBacklog(uint8_t tcpBacklog); + ReturnValue_t initialize() override; ReturnValue_t performOperation(uint8_t opCode) override; ReturnValue_t initializeAfterTaskCreation() override; protected: StorageManagerIF* tcStore = nullptr; - + StorageManagerIF* tmStore = nullptr; private: //! TMTC bridge is cached. object_id_t tmtcBridgeId = objects::NO_OBJECT; @@ -58,14 +77,15 @@ private: struct sockaddr tcpAddress; MessageQueueId_t targetTcDestination = MessageQueueIF::NO_QUEUE; int tcpAddrLen = sizeof(tcpAddress); - int currentBacklog = 3; + int tcpBacklog = 3; std::vector receptionBuffer; - //SharedRingBuffer* tcpRingBuffer; int tcpSockOpt = 0; + int tcpTmFlags = 0; void handleServerOperation(socket_t connSocket); ReturnValue_t handleTcReception(size_t bytesRecvd); + ReturnValue_t handleTmSending(socket_t connSocket); }; -#endif /* FSFW_OSAL_WINDOWS_TCWINTCPSERVER_H_ */ +#endif /* FSFW_OSAL_COMMON_TCP_TMTC_SERVER_H_ */ diff --git a/osal/common/UdpTcPollingTask.h b/osal/common/UdpTcPollingTask.h index cfe74b34..9a680fb8 100644 --- a/osal/common/UdpTcPollingTask.h +++ b/osal/common/UdpTcPollingTask.h @@ -9,8 +9,11 @@ #include /** - * @brief This class should be used with the UdpTmTcBridge to implement a UDP server + * @brief This class can be used with the UdpTmTcBridge to implement a UDP server * for receiving and sending PUS TMTC. + * @details + * This task is exclusively used to poll telecommands from a given socket and transfer them + * to the FSFW software bus. It used the blocking recvfrom call to do this. */ class UdpTcPollingTask: public TcpIpBase, @@ -45,8 +48,6 @@ private: object_id_t tmtcBridgeId = objects::NO_OBJECT; UdpTmTcBridge* tmtcBridge = nullptr; MessageQueueId_t targetTcDestination = MessageQueueIF::NO_QUEUE; - - //! See: https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-recvfrom int receptionFlags = 0; std::vector receptionBuffer; diff --git a/osal/common/UdpTmTcBridge.cpp b/osal/common/UdpTmTcBridge.cpp index ccbb194e..b07ca7a5 100644 --- a/osal/common/UdpTmTcBridge.cpp +++ b/osal/common/UdpTmTcBridge.cpp @@ -23,7 +23,7 @@ const std::string UdpTmTcBridge::DEFAULT_UDP_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; UdpTmTcBridge::UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, - object_id_t tmStoreId, object_id_t tcStoreId, std::string udpServerPort): + std::string udpServerPort, object_id_t tmStoreId, object_id_t tcStoreId): TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) { if(udpServerPort == "") { this->udpServerPort = DEFAULT_UDP_SERVER_PORT; diff --git a/osal/common/UdpTmTcBridge.h b/osal/common/UdpTmTcBridge.h index 290f5eb0..74084a9d 100644 --- a/osal/common/UdpTmTcBridge.h +++ b/osal/common/UdpTmTcBridge.h @@ -17,8 +17,13 @@ #include /** - * @brief This class should be used with the UdpTcPollingTask to implement a UDP server + * @brief This class can be used with the UdpTcPollingTask to implement a UDP server * for receiving and sending PUS TMTC. + * @details + * This bridge task will take care of sending telemetry back to a UDP client if a connection + * was established and store them in a FIFO if this was not done yet. It is also be the default + * destination for telecommands, but the telecommands will be relayed to a specified tcDestination + * directly. */ class UdpTmTcBridge: public TmTcBridge, @@ -29,7 +34,8 @@ public: static const std::string DEFAULT_UDP_SERVER_PORT; UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, - object_id_t tmStoreId, object_id_t tcStoreId, std::string udpServerPort = ""); + std::string udpServerPort = "", object_id_t tmStoreId = objects::TM_STORE, + object_id_t tcStoreId = objects::TC_STORE); virtual~ UdpTmTcBridge(); /** diff --git a/osal/common/tcpipCommon.cpp b/osal/common/tcpipCommon.cpp index d4a3e8e6..ca4dbf18 100644 --- a/osal/common/tcpipCommon.cpp +++ b/osal/common/tcpipCommon.cpp @@ -32,6 +32,12 @@ void tcpip::determineErrorStrings(Protocol protocol, ErrorSources errorSrc, std: else if(errorSrc == ErrorSources::RECVFROM_CALL) { srcString = "recvfrom call"; } + else if(errorSrc == ErrorSources::SEND_CALL) { + srcString = "send call"; + } + else if(errorSrc == ErrorSources::SENDTO_CALL) { + srcString = "sendto call"; + } else if(errorSrc == ErrorSources::GETADDRINFO_CALL) { srcString = "getaddrinfo call"; } diff --git a/osal/common/tcpipCommon.h b/osal/common/tcpipCommon.h index eb1bd910..ce7a90cd 100644 --- a/osal/common/tcpipCommon.h +++ b/osal/common/tcpipCommon.h @@ -29,6 +29,7 @@ enum class ErrorSources { RECVFROM_CALL, LISTEN_CALL, ACCEPT_CALL, + SEND_CALL, SENDTO_CALL, SHUTDOWN_CALL }; diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index dcffac41..1257ef89 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -183,8 +183,11 @@ ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage *message) { if(tmFifo->full()) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::debug << "TmTcBridge::storeDownlinkData: TM downlink max. number " - << "of stored packet IDs reached! " << std::endl; + sif::warning << "TmTcBridge::storeDownlinkData: TM downlink max. number " + "of stored packet IDs reached!" << std::endl; +#else + sif::printWarning("TmTcBridge::storeDownlinkData: TM downlink max. number " + "of stored packet IDs reached!\n"); #endif if(overwriteOld) { tmFifo->retrieve(&storeId); diff --git a/tmtcservices/TmTcBridge.h b/tmtcservices/TmTcBridge.h index 0177648c..d3e1c547 100644 --- a/tmtcservices/TmTcBridge.h +++ b/tmtcservices/TmTcBridge.h @@ -150,8 +150,7 @@ protected: void printData(uint8_t * data, size_t dataLen); /** - * This fifo can be used to store downlink data - * which can not be sent at the moment. + * This FIFO can be used to store downlink data which can not be sent at the moment. */ DynamicFIFO* tmFifo = nullptr; uint8_t sentPacketsPerCycle = DEFAULT_STORED_DATA_SENT_PER_CYCLE; From 8b17c40aa61537a70ce947b1db8bf338dea2ae16 Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Tue, 11 May 2021 15:02:04 +0200 Subject: [PATCH 204/230] Added Network Byte Order --- serialize/SerializeIF.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/serialize/SerializeIF.h b/serialize/SerializeIF.h index d72218f0..dfd854e3 100644 --- a/serialize/SerializeIF.h +++ b/serialize/SerializeIF.h @@ -19,7 +19,10 @@ class SerializeIF { public: enum class Endianness : uint8_t { - BIG, LITTLE, MACHINE + BIG, + LITTLE, + MACHINE, + NETWORK = BIG // Added for convenience like htons on sockets }; static const uint8_t INTERFACE_ID = CLASS_ID::SERIALIZE_IF; From d807998f4de768be499aa3a48f9bf2d577057667 Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Tue, 11 May 2021 15:25:38 +0200 Subject: [PATCH 205/230] Added Missing includes in Host Osal Updated correct defaults for Host MessageQueues --- osal/host/MessageQueue.cpp | 2 ++ osal/host/MessageQueue.h | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/osal/host/MessageQueue.cpp b/osal/host/MessageQueue.cpp index 41c55a3d..4e286271 100644 --- a/osal/host/MessageQueue.cpp +++ b/osal/host/MessageQueue.cpp @@ -5,6 +5,8 @@ #include "../../ipc/MutexFactory.h" #include "../../ipc/MutexGuard.h" +#include + MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize): messageSize(maxMessageSize), messageDepth(messageDepth) { queueLock = MutexFactory::instance()->createMutex(); diff --git a/osal/host/MessageQueue.h b/osal/host/MessageQueue.h index e965123d..1c9b5e33 100644 --- a/osal/host/MessageQueue.h +++ b/osal/host/MessageQueue.h @@ -217,15 +217,15 @@ private: * @brief The class stores the queue id it got assigned. * If initialization fails, the queue id is set to zero. */ - MessageQueueId_t mqId = 0; + MessageQueueId_t mqId = MessageQueueIF::NO_QUEUE; size_t messageSize = 0; size_t messageDepth = 0; MutexIF* queueLock; bool defaultDestinationSet = false; - MessageQueueId_t defaultDestination = 0; - MessageQueueId_t lastPartner = 0; + MessageQueueId_t defaultDestination = MessageQueueIF::NO_QUEUE; + MessageQueueId_t lastPartner = MessageQueueIF::NO_QUEUE; }; #endif /* FRAMEWORK_OSAL_HOST_MESSAGEQUEUE_H_ */ From 9d0155d9ae58425bf982cd4712be3b7d83efc87b Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Tue, 11 May 2021 15:30:49 +0200 Subject: [PATCH 206/230] Added a returnvalue --- osal/host/MessageQueue.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osal/host/MessageQueue.cpp b/osal/host/MessageQueue.cpp index 4e286271..a779bdcb 100644 --- a/osal/host/MessageQueue.cpp +++ b/osal/host/MessageQueue.cpp @@ -128,8 +128,7 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, internalErrorReporter->queueMessageNotSent(); } } - // TODO: Better returnvalue - return HasReturnvaluesIF::RETURN_FAILED; + return MessageQueueIF::DESTINATION_INVALID; } if(targetQueue->messageQueue.size() < targetQueue->messageDepth) { MutexGuard mutexLock(targetQueue->queueLock, MutexIF::TimeoutType::WAITING, 20); From e1c91f82b763b0d57710a16ab40697df87e6ce74 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 12 May 2021 10:54:10 +0200 Subject: [PATCH 207/230] some fixes and tweaks --- events/EventManager.cpp | 48 +++++++++++++++++++---------- objectmanager/ObjectManagerIF.h | 2 +- serviceinterface/ServiceInterface.h | 4 +-- 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/events/EventManager.cpp b/events/EventManager.cpp index 5b2b31b5..2d4b6a49 100644 --- a/events/EventManager.cpp +++ b/events/EventManager.cpp @@ -2,7 +2,7 @@ #include "EventMessage.h" #include -#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../serviceinterface/ServiceInterface.h" #include "../ipc/QueueFactory.h" #include "../ipc/MutexFactory.h" @@ -120,23 +120,39 @@ ReturnValue_t EventManager::unsubscribeFromEventRange(MessageQueueId_t listener, void EventManager::printEvent(EventMessage* message) { const char *string = 0; switch (message->getSeverity()) { - case severity::INFO: -#if DEBUG_INFO_EVENT == 1 - string = translateObject(message->getReporter()); + case severity::INFO: { +#if FSFW_DEBUG_INFO == 1 + string = translateObject(message->getReporter()); #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << "EVENT: "; - if (string != 0) { - sif::info << string; - } else { - sif::info << "0x" << std::hex << message->getReporter() << std::dec; - } - sif::info << " reported " << translateEvents(message->getEvent()) << " (" - << std::dec << message->getEventId() << std::hex << ") P1: 0x" - << message->getParameter1() << " P2: 0x" - << message->getParameter2() << std::dec << std::endl; -#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ + sif::info << "EVENT: "; + if (string != 0) { + sif::info << string; + } + else { + sif::info << "0x" << std::hex << std::setfill('0') << std::setw(8) << + message->getReporter() << std::setfill(' ') << std::dec; + } + sif::info << " reported " << translateEvents(message->getEvent()) << " (" + << std::dec << message->getEventId() << std::hex << ") P1: 0x" + << message->getParameter1() << " P2: 0x" + << message->getParameter2() << std::dec << std::endl; +#else + const char totalString[140] = {}; + if (string != 0) { + snprintf((char*) totalString, sizeof(totalString),"Event: %s", string); + } + else { + snprintf((char*) totalString, sizeof(totalString),"Event: 0x%08x", + message->getReporter()); + } + snprintf((char*) totalString, sizeof(totalString), + " reported %s | ID %d | P1: 0x%x | P2: 0x%x\n", translateEvents(message->getEvent()), + message->getEventId(), message->getParameter1(), message->getParameter2()); + sif::printInfo("%s", totalString); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 0 */ #endif /* DEBUG_INFO_EVENT == 1 */ - break; + break; + } default: string = translateObject(message->getReporter()); #if FSFW_CPP_OSTREAM_ENABLED == 1 diff --git a/objectmanager/ObjectManagerIF.h b/objectmanager/ObjectManagerIF.h index 8bebb609..61e6f423 100644 --- a/objectmanager/ObjectManagerIF.h +++ b/objectmanager/ObjectManagerIF.h @@ -4,7 +4,7 @@ #include "frameworkObjects.h" #include "SystemObjectIF.h" #include "../returnvalues/HasReturnvaluesIF.h" -#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../serviceinterface/ServiceInterface.h" /** * @brief This class provides an interface to the global object manager. diff --git a/serviceinterface/ServiceInterface.h b/serviceinterface/ServiceInterface.h index 1f7e5e84..e95dd9a4 100644 --- a/serviceinterface/ServiceInterface.h +++ b/serviceinterface/ServiceInterface.h @@ -5,9 +5,9 @@ #include "serviceInterfaceDefintions.h" #if FSFW_CPP_OSTREAM_ENABLED == 1 -#include +#include "ServiceInterfaceStream.h" #else -#include +#include "ServiceInterfacePrinter.h" #endif #endif /* FSFW_SERVICEINTERFACE_SERVICEINTERFACE_H_ */ From cd016c8281598140708952e44c7823f71e1e63cf Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 12 May 2021 13:40:26 +0200 Subject: [PATCH 208/230] event manager printout refactoring --- events/EventManager.cpp | 150 +++++++++++++++++++++++----------------- events/EventManager.h | 2 + 2 files changed, 87 insertions(+), 65 deletions(-) diff --git a/events/EventManager.cpp b/events/EventManager.cpp index 2d4b6a49..8e8f797f 100644 --- a/events/EventManager.cpp +++ b/events/EventManager.cpp @@ -1,8 +1,6 @@ #include "EventManager.h" #include "EventMessage.h" -#include -#include "../serviceinterface/ServiceInterface.h" #include "../ipc/QueueFactory.h" #include "../ipc/MutexFactory.h" @@ -115,69 +113,6 @@ ReturnValue_t EventManager::unsubscribeFromEventRange(MessageQueueId_t listener, return result; } -#if FSFW_OBJ_EVENT_TRANSLATION == 1 - -void EventManager::printEvent(EventMessage* message) { - const char *string = 0; - switch (message->getSeverity()) { - case severity::INFO: { -#if FSFW_DEBUG_INFO == 1 - string = translateObject(message->getReporter()); -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << "EVENT: "; - if (string != 0) { - sif::info << string; - } - else { - sif::info << "0x" << std::hex << std::setfill('0') << std::setw(8) << - message->getReporter() << std::setfill(' ') << std::dec; - } - sif::info << " reported " << translateEvents(message->getEvent()) << " (" - << std::dec << message->getEventId() << std::hex << ") P1: 0x" - << message->getParameter1() << " P2: 0x" - << message->getParameter2() << std::dec << std::endl; -#else - const char totalString[140] = {}; - if (string != 0) { - snprintf((char*) totalString, sizeof(totalString),"Event: %s", string); - } - else { - snprintf((char*) totalString, sizeof(totalString),"Event: 0x%08x", - message->getReporter()); - } - snprintf((char*) totalString, sizeof(totalString), - " reported %s | ID %d | P1: 0x%x | P2: 0x%x\n", translateEvents(message->getEvent()), - message->getEventId(), message->getParameter1(), message->getParameter2()); - sif::printInfo("%s", totalString); -#endif /* FSFW_CPP_OSTREAM_ENABLED == 0 */ -#endif /* DEBUG_INFO_EVENT == 1 */ - break; - } - default: - string = translateObject(message->getReporter()); -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::debug << "EventManager: "; - if (string != 0) { - sif::debug << string; - } - else { - sif::debug << "0x" << std::hex << message->getReporter() << std::dec; - } - sif::debug << " reported " << translateEvents(message->getEvent()) - << " (" << std::dec << message->getEventId() << ") " - << std::endl; - sif::debug << std::hex << "P1 Hex: 0x" << message->getParameter1() - << ", P1 Dec: " << std::dec << message->getParameter1() - << std::endl; - sif::debug << std::hex << "P2 Hex: 0x" << message->getParameter2() - << ", P2 Dec: " << std::dec << message->getParameter2() - << std::endl; -#endif - break; - } -} -#endif - void EventManager::lockMutex() { mutex->lockMutex(timeoutType, timeoutMs); } @@ -191,3 +126,88 @@ void EventManager::setMutexTimeout(MutexIF::TimeoutType timeoutType, this->timeoutType = timeoutType; this->timeoutMs = timeoutMs; } + +#if FSFW_OBJ_EVENT_TRANSLATION == 1 + +void EventManager::printEvent(EventMessage* message) { + switch (message->getSeverity()) { + case severity::INFO: { +#if FSFW_DEBUG_INFO == 1 + printUtility(sif::OutputTypes::OUT_INFO, message); +#endif /* DEBUG_INFO_EVENT == 1 */ + break; + } + default: + printUtility(sif::OutputTypes::OUT_DEBUG, message); + break; + } +} + +void EventManager::printUtility(sif::OutputTypes printType, EventMessage *message) { + const char *string = 0; + if(printType == sif::OutputTypes::OUT_INFO) { + string = translateObject(message->getReporter()); +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "EventManager: "; + if (string != 0) { + sif::info << string; + } + else { + sif::info << "0x" << std::hex << std::setw(8) << std::setfill('0') << + message->getReporter() << std::setfill(' ') << std::dec; + } + sif::info << " reported " << translateEvents(message->getEvent()) + << " with event ID " << std::dec << message->getEventId() << std::endl; + sif::info << std::hex << "P1 Hex: 0x" << message->getParameter1() << + " | P1 Dec: " << std::dec << message->getParameter1() << std::hex << + " | P2 Hex: 0x" << message->getParameter2() << " | P2 Dec: " << std::dec << + message->getParameter2() << std::endl; +#else + if (string != 0) { + sif::printInfo("Event Manager: %s reported %s with event ID %d\n", + message->getReporter(), translateEvents(message->getEvent()), + message->getEventId()); + } + else { + sif::printInfo("Event Manager: Reporter ID 0x%08x reported %s with event ID %d\n", + string, translateEvents(message->getEvent()), message->getEventId()); + } + sif::printInfo("P1 Hex: 0x%x | P1 Dec: %d | P2 Hex: 0x%x | P2 Dec: %d\n", + message->getParameter1(), message->getParameter1(), + message->getParameter2(), message->getParameter2()); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 0 */ + } + else { + string = translateObject(message->getReporter()); +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::debug << "EventManager: "; + if (string != 0) { + sif::debug << string; + } + else { + sif::debug << "0x" << std::hex << message->getReporter() << std::dec; + } + sif::debug << " reported " << translateEvents(message->getEvent()) + << " with event ID " << std::dec << message->getEventId() << std::endl; + sif::debug << std::hex << "P1 Hex: 0x" << message->getParameter1() << + " | P1 Dec: " << std::dec << message->getParameter1() << std::hex << + " | P2 Hex: 0x" << message->getParameter2() << " | P2 Dec: " << std::dec << + message->getParameter2() << std::endl; +#else + if (string != 0) { + sif::printDebug("Event Manager: %s reported %s with event ID %d\n", + message->getReporter(), translateEvents(message->getEvent()), + message->getEventId()); + } + else { + sif::printDebug("Event Manager: Reporter ID 0x%08x reported %s with event ID %d\n", + string, translateEvents(message->getEvent()), message->getEventId()); + } + sif::printDebug("P1 Hex: 0x%x | P1 Dec: %d | P2 Hex: 0x%x | P2 Dec: %d\n", + message->getParameter1(), message->getParameter1(), + message->getParameter2(), message->getParameter2()); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 0 */ + } +} + +#endif /* FSFW_OBJ_EVENT_TRANSLATION == 1 */ diff --git a/events/EventManager.h b/events/EventManager.h index abce9b8b..9189d9e7 100644 --- a/events/EventManager.h +++ b/events/EventManager.h @@ -6,6 +6,7 @@ #include +#include "../serviceinterface/ServiceInterface.h" #include "../objectmanager/SystemObject.h" #include "../storagemanager/LocalPool.h" #include "../tasks/ExecutableObjectIF.h" @@ -67,6 +68,7 @@ protected: #if FSFW_OBJ_EVENT_TRANSLATION == 1 void printEvent(EventMessage *message); + void printUtility(sif::OutputTypes printType, EventMessage* message); #endif void lockMutex(); From 5b23b928cf9b187eb19b18f366a9fecfaff21c31 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 12 May 2021 14:28:37 +0200 Subject: [PATCH 209/230] added missing include --- osal/host/MessageQueue.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osal/host/MessageQueue.cpp b/osal/host/MessageQueue.cpp index 41c55a3d..4e286271 100644 --- a/osal/host/MessageQueue.cpp +++ b/osal/host/MessageQueue.cpp @@ -5,6 +5,8 @@ #include "../../ipc/MutexFactory.h" #include "../../ipc/MutexGuard.h" +#include + MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize): messageSize(maxMessageSize), messageDepth(messageDepth) { queueLock = MutexFactory::instance()->createMutex(); From d81c6f40fbc86ac9fd0123d08b5fdba09bad9d00 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 12 May 2021 14:43:08 +0200 Subject: [PATCH 210/230] define fixes --- osal/host/Clock.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/osal/host/Clock.cpp b/osal/host/Clock.cpp index c097f619..bcf486ec 100644 --- a/osal/host/Clock.cpp +++ b/osal/host/Clock.cpp @@ -2,9 +2,9 @@ #include "../../timemanager/Clock.h" #include -#if defined(WIN32) +#if defined(_WIN32) #include -#elif defined(LINUX) +#elif defined(__unix__) #include #endif @@ -92,7 +92,7 @@ timeval Clock::getUptime() { auto fraction = uptime - secondsChrono; timeval.tv_usec = std::chrono::duration_cast( fraction).count(); -#elif defined(LINUX) +#elif defined(__unix__) double uptimeSeconds; if (std::ifstream("/proc/uptime", std::ios::in) >> uptimeSeconds) { @@ -120,7 +120,6 @@ ReturnValue_t Clock::getUptime(uint32_t* uptimeMs) { } -ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) { /* Do some magic with chrono (C++20!) */ /* Right now, the library doesn't have the new features to get the required values yet. so we work around that for now. */ From 8293e6b0c742e18ddd78d4db05ac64fe58f09c60 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 12 May 2021 14:48:39 +0200 Subject: [PATCH 211/230] more include fixes --- osal/host/Clock.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osal/host/Clock.cpp b/osal/host/Clock.cpp index bcf486ec..cf9349c1 100644 --- a/osal/host/Clock.cpp +++ b/osal/host/Clock.cpp @@ -46,7 +46,7 @@ ReturnValue_t Clock::setClock(const timeval* time) { } ReturnValue_t Clock::getClock_timeval(timeval* time) { -#if defined(WIN32) +#if defined(_WIN32) auto now = std::chrono::system_clock::now(); auto secondsChrono = std::chrono::time_point_cast(now); auto epoch = now.time_since_epoch(); @@ -54,7 +54,7 @@ ReturnValue_t Clock::getClock_timeval(timeval* time) { auto fraction = now - secondsChrono; time->tv_usec = std::chrono::duration_cast(fraction).count(); return HasReturnvaluesIF::RETURN_OK; -#elif defined(LINUX) +#elif defined(__unix__) timespec timeUnix; int status = clock_gettime(CLOCK_REALTIME,&timeUnix); if(status!=0){ @@ -85,7 +85,7 @@ ReturnValue_t Clock::getClock_usecs(uint64_t* time) { timeval Clock::getUptime() { timeval timeval; -#if defined(WIN32) +#if defined(_WIN32) auto uptime = std::chrono::milliseconds(GetTickCount64()); auto secondsChrono = std::chrono::duration_cast(uptime); timeval.tv_sec = secondsChrono.count(); From a6dd2d5dcb21058c4c487ac1ef027ea6ece1b98f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 12 May 2021 16:37:12 +0200 Subject: [PATCH 212/230] event manager update --- events/EventManager.cpp | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/events/EventManager.cpp b/events/EventManager.cpp index 8e8f797f..2337ba83 100644 --- a/events/EventManager.cpp +++ b/events/EventManager.cpp @@ -156,21 +156,19 @@ void EventManager::printUtility(sif::OutputTypes printType, EventMessage *messag sif::info << "0x" << std::hex << std::setw(8) << std::setfill('0') << message->getReporter() << std::setfill(' ') << std::dec; } - sif::info << " reported " << translateEvents(message->getEvent()) - << " with event ID " << std::dec << message->getEventId() << std::endl; + sif::info << " report event with ID " << message->getEventId() << std::endl; sif::info << std::hex << "P1 Hex: 0x" << message->getParameter1() << " | P1 Dec: " << std::dec << message->getParameter1() << std::hex << " | P2 Hex: 0x" << message->getParameter2() << " | P2 Dec: " << std::dec << message->getParameter2() << std::endl; #else if (string != 0) { - sif::printInfo("Event Manager: %s reported %s with event ID %d\n", - message->getReporter(), translateEvents(message->getEvent()), + sif::printInfo("Event Manager: %s reported event with ID %d\n", string, message->getEventId()); } else { - sif::printInfo("Event Manager: Reporter ID 0x%08x reported %s with event ID %d\n", - string, translateEvents(message->getEvent()), message->getEventId()); + sif::printInfo("Event Manager: Reporter ID 0x%08x reported event with ID %d\n", + message->getReporter(), message->getEventId()); } sif::printInfo("P1 Hex: 0x%x | P1 Dec: %d | P2 Hex: 0x%x | P2 Dec: %d\n", message->getParameter1(), message->getParameter1(), @@ -185,23 +183,22 @@ void EventManager::printUtility(sif::OutputTypes printType, EventMessage *messag sif::debug << string; } else { - sif::debug << "0x" << std::hex << message->getReporter() << std::dec; + sif::debug << "0x" << std::hex << std::setw(8) << std::setfill('0') << + message->getReporter() << std::setfill(' ') << std::dec; } - sif::debug << " reported " << translateEvents(message->getEvent()) - << " with event ID " << std::dec << message->getEventId() << std::endl; + sif::debug << " report event with ID " << message->getEventId() << std::endl; sif::debug << std::hex << "P1 Hex: 0x" << message->getParameter1() << " | P1 Dec: " << std::dec << message->getParameter1() << std::hex << " | P2 Hex: 0x" << message->getParameter2() << " | P2 Dec: " << std::dec << message->getParameter2() << std::endl; #else if (string != 0) { - sif::printDebug("Event Manager: %s reported %s with event ID %d\n", - message->getReporter(), translateEvents(message->getEvent()), + sif::printDebug("Event Manager: %s reported event with ID %d\n", string, message->getEventId()); } else { - sif::printDebug("Event Manager: Reporter ID 0x%08x reported %s with event ID %d\n", - string, translateEvents(message->getEvent()), message->getEventId()); + sif::printDebug("Event Manager: Reporter ID 0x%08x reported event with ID %d\n", + message->getReporter(), message->getEventId()); } sif::printDebug("P1 Hex: 0x%x | P1 Dec: %d | P2 Hex: 0x%x | P2 Dec: %d\n", message->getParameter1(), message->getParameter1(), From d27f49c9680190169e004dead07ae0ebe0cc4fc4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 12 May 2021 16:38:02 +0200 Subject: [PATCH 213/230] added platform header file --- platform.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 platform.h diff --git a/platform.h b/platform.h new file mode 100644 index 00000000..08260094 --- /dev/null +++ b/platform.h @@ -0,0 +1,15 @@ +#ifndef FSFW_PLATFORM_H_ +#define FSFW_PLATFORM_H_ + +#if defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)) + +#define PLATFORM_UNIX + +#elif defined(_WIN32) + +#define PLATFORM_WIN + +#endif + + +#endif /* FSFW_PLATFORM_H_ */ From 1626b266d703f10444b6ea3f9fb1c1be228ec400 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 12 May 2021 16:47:53 +0200 Subject: [PATCH 214/230] platform header file --- osal/common/TcpIpBase.cpp | 13 ++++++------- osal/common/TcpIpBase.h | 9 +++++---- osal/common/TcpTmTcServer.cpp | 8 +++----- osal/common/TcpTmTcServer.h | 3 ++- osal/common/UdpTcPollingTask.cpp | 13 +++++-------- osal/common/UdpTmTcBridge.cpp | 15 ++++++--------- osal/common/UdpTmTcBridge.h | 9 +++------ osal/host/Clock.cpp | 6 ++++-- osal/host/FixedTimeslotTask.cpp | 5 +++-- osal/host/PeriodicTask.cpp | 9 +++++---- 10 files changed, 42 insertions(+), 48 deletions(-) diff --git a/osal/common/TcpIpBase.cpp b/osal/common/TcpIpBase.cpp index 27384ecc..0b37e38c 100644 --- a/osal/common/TcpIpBase.cpp +++ b/osal/common/TcpIpBase.cpp @@ -1,10 +1,9 @@ #include "TcpIpBase.h" +#include "../../platform.h" -#ifdef __unix__ - +#ifdef PLATFORM_UNIX #include #include - #endif TcpIpBase::TcpIpBase() { @@ -37,17 +36,17 @@ TcpIpBase::~TcpIpBase() { } int TcpIpBase::closeSocket(socket_t socket) { -#ifdef _WIN32 +#ifdef PLATFORM_WIN return closesocket(socket); -#elif defined(__unix__) +#elif defined(PLATFORM_UNIX) return close(socket); #endif } int TcpIpBase::getLastSocketError() { -#ifdef _WIN32 +#ifdef PLATFORM_WIN return WSAGetLastError(); -#elif defined(__unix__) +#elif defined(PLATFORM_UNIX) return errno; #endif } diff --git a/osal/common/TcpIpBase.h b/osal/common/TcpIpBase.h index 652d791a..79eefad2 100644 --- a/osal/common/TcpIpBase.h +++ b/osal/common/TcpIpBase.h @@ -1,13 +1,14 @@ #ifndef FSFW_OSAL_COMMON_TCPIPIF_H_ #define FSFW_OSAL_COMMON_TCPIPIF_H_ -#include +#include "../../returnvalues/HasReturnvaluesIF.h" +#include "../../platform.h" -#ifdef _WIN32 +#ifdef PLATFORM_WIN #include -#elif defined(__unix__) +#elif defined(PLATFORM_UNIX) #include @@ -16,7 +17,7 @@ class TcpIpBase { protected: -#ifdef _WIN32 +#ifdef PLATFORM_WIN static constexpr int SHUT_RECV = SD_RECEIVE; static constexpr int SHUT_SEND = SD_SEND; static constexpr int SHUT_BOTH = SD_BOTH; diff --git a/osal/common/TcpTmTcServer.cpp b/osal/common/TcpTmTcServer.cpp index 08a62ffb..e1a26fe7 100644 --- a/osal/common/TcpTmTcServer.cpp +++ b/osal/common/TcpTmTcServer.cpp @@ -1,15 +1,13 @@ #include "TcpTmTcServer.h" #include "tcpipHelpers.h" +#include "../../platform.h" #include "../../serviceinterface/ServiceInterface.h" -#ifdef _WIN32 +#ifdef PLATFORM_WIN #include #include - -#elif defined(__unix__) - +#elif defined(PLATFORM_UNIX) #include - #endif const std::string TcpTmTcServer::DEFAULT_TCP_SERVER_PORT = "7301"; diff --git a/osal/common/TcpTmTcServer.h b/osal/common/TcpTmTcServer.h index 4dcc77a2..91c579e5 100644 --- a/osal/common/TcpTmTcServer.h +++ b/osal/common/TcpTmTcServer.h @@ -2,10 +2,11 @@ #define FSFW_OSAL_WINDOWS_TCWINTCPSERVER_H_ #include "TcpIpBase.h" +#include "../../platform.h" #include "../../objectmanager/SystemObject.h" #include "../../tasks/ExecutableObjectIF.h" -#ifdef __unix__ +#ifdef PLATFORM_UNIX #include #endif diff --git a/osal/common/UdpTcPollingTask.cpp b/osal/common/UdpTcPollingTask.cpp index 47f67b29..68108323 100644 --- a/osal/common/UdpTcPollingTask.cpp +++ b/osal/common/UdpTcPollingTask.cpp @@ -1,17 +1,14 @@ #include "UdpTcPollingTask.h" #include "tcpipHelpers.h" +#include "../../platform.h" #include "../../globalfunctions/arrayprinter.h" #include "../../serviceinterface/ServiceInterfaceStream.h" -#ifdef _WIN32 - +#ifdef PLATFORM_WIN #include - -#else - +#elif defined(PLATFORM_UNIX) #include #include - #endif //! Debugging preprocessor define. @@ -155,7 +152,7 @@ ReturnValue_t UdpTcPollingTask::initializeAfterTaskCreation() { } void UdpTcPollingTask::setTimeout(double timeoutSeconds) { -#ifdef _WIN32 +#ifdef PLATFORM_WIN DWORD timeoutMs = timeoutSeconds * 1000.0; int result = setsockopt(serverSocket, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast(&timeoutMs), sizeof(DWORD)); @@ -165,7 +162,7 @@ void UdpTcPollingTask::setTimeout(double timeoutSeconds) { "receive timeout failed with " << strerror(errno) << std::endl; #endif } -#elif defined(__unix__) +#elif defined(PLATFORM_UNIX) timeval tval; tval = timevalOperations::toTimeval(timeoutSeconds); int result = setsockopt(serverSocket, SOL_SOCKET, SO_RCVTIMEO, diff --git a/osal/common/UdpTmTcBridge.cpp b/osal/common/UdpTmTcBridge.cpp index ba23f521..2ecc7b7c 100644 --- a/osal/common/UdpTmTcBridge.cpp +++ b/osal/common/UdpTmTcBridge.cpp @@ -1,18 +1,15 @@ +#include "UdpTmTcBridge.h" #include "tcpipHelpers.h" -#include -#include -#include - -#ifdef _WIN32 +#include "../../platform.h" +#include "../../serviceinterface/ServiceInterface.h" +#include "../../ipc/MutexGuard.h" +#ifdef PLATFORM_WIN #include - -#elif defined(__unix__) - +#elif defined(PLATFORM_UNIX) #include #include - #endif //! Debugging preprocessor define. diff --git a/osal/common/UdpTmTcBridge.h b/osal/common/UdpTmTcBridge.h index 8b8d1949..360643bb 100644 --- a/osal/common/UdpTmTcBridge.h +++ b/osal/common/UdpTmTcBridge.h @@ -2,16 +2,13 @@ #define FSFW_OSAL_WINDOWS_TMTCWINUDPBRIDGE_H_ #include "TcpIpBase.h" +#include "../../platform.h" #include "../../tmtcservices/TmTcBridge.h" -#ifdef _WIN32 - +#ifdef PLATFORM_WIN #include - -#elif defined(__unix__) - +#elif defined(PLATFORM_UNIX) #include - #endif #include diff --git a/osal/host/Clock.cpp b/osal/host/Clock.cpp index cf9349c1..b2e4c171 100644 --- a/osal/host/Clock.cpp +++ b/osal/host/Clock.cpp @@ -1,10 +1,12 @@ #include "../../serviceinterface/ServiceInterface.h" #include "../../timemanager/Clock.h" +#include "../../platform.h" #include -#if defined(_WIN32) + +#if defined(PLATFORM_WIN) #include -#elif defined(__unix__) +#elif defined(PLATFORM_UNIX) #include #endif diff --git a/osal/host/FixedTimeslotTask.cpp b/osal/host/FixedTimeslotTask.cpp index 89daa278..55f37499 100644 --- a/osal/host/FixedTimeslotTask.cpp +++ b/osal/host/FixedTimeslotTask.cpp @@ -1,4 +1,5 @@ #include "taskHelpers.h" +#include "../../platform.h" #include "../../osal/host/FixedTimeslotTask.h" #include "../../ipc/MutexFactory.h" #include "../../osal/host/Mutex.h" @@ -9,10 +10,10 @@ #include #include -#if defined(WIN32) +#if defined(PLATFORM_WIN) #include #include "../windows/winTaskHelpers.h" -#elif defined(LINUX) +#elif defined(PLATFORM_UNIX) #include #endif diff --git a/osal/host/PeriodicTask.cpp b/osal/host/PeriodicTask.cpp index 09df410f..4b3fa626 100644 --- a/osal/host/PeriodicTask.cpp +++ b/osal/host/PeriodicTask.cpp @@ -2,6 +2,7 @@ #include "PeriodicTask.h" #include "taskHelpers.h" +#include "../../platform.h" #include "../../ipc/MutexFactory.h" #include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../tasks/ExecutableObjectIF.h" @@ -9,10 +10,10 @@ #include #include -#if defined(WIN32) +#if defined(PLATFORM_WIN) #include #include -#elif defined(__unix__) +#elif defined(PLATFORM_UNIX) #include #endif @@ -24,9 +25,9 @@ PeriodicTask::PeriodicTask(const char *name, TaskPriority setPriority, // It is probably possible to set task priorities by using the native // task handles for Windows / Linux mainThread = std::thread(&PeriodicTask::taskEntryPoint, this, this); -#if defined(_WIN32) +#if defined(PLATFORM_WIN) tasks::setTaskPriority(reinterpret_cast(mainThread.native_handle()), setPriority); -#elif defined(__unix__) +#elif defined(PLATFORM_UNIX) // TODO: We could reuse existing code here. #endif tasks::insertTaskName(mainThread.get_id(), taskName); From 4095be449ae4b6ebaf89fdcbfc5bc31b854594d5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 12 May 2021 17:32:40 +0200 Subject: [PATCH 215/230] some more preprocessor replacements --- osal/common/TcpIpBase.h | 6 +----- osal/host/Clock.cpp | 10 +++++----- platform.h | 5 ----- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/osal/common/TcpIpBase.h b/osal/common/TcpIpBase.h index 79eefad2..fe6a763c 100644 --- a/osal/common/TcpIpBase.h +++ b/osal/common/TcpIpBase.h @@ -5,13 +5,9 @@ #include "../../platform.h" #ifdef PLATFORM_WIN - #include - #elif defined(PLATFORM_UNIX) - #include - #endif class TcpIpBase { @@ -23,7 +19,7 @@ protected: static constexpr int SHUT_BOTH = SD_BOTH; using socket_t = SOCKET; -#elif defined(__unix__) +#elif defined(PLATFORM_UNIX) using socket_t = int; static constexpr int INVALID_SOCKET = -1; diff --git a/osal/host/Clock.cpp b/osal/host/Clock.cpp index b2e4c171..ed5aab62 100644 --- a/osal/host/Clock.cpp +++ b/osal/host/Clock.cpp @@ -48,7 +48,7 @@ ReturnValue_t Clock::setClock(const timeval* time) { } ReturnValue_t Clock::getClock_timeval(timeval* time) { -#if defined(_WIN32) +#if defined(PLATFORM_WIN) auto now = std::chrono::system_clock::now(); auto secondsChrono = std::chrono::time_point_cast(now); auto epoch = now.time_since_epoch(); @@ -56,7 +56,7 @@ ReturnValue_t Clock::getClock_timeval(timeval* time) { auto fraction = now - secondsChrono; time->tv_usec = std::chrono::duration_cast(fraction).count(); return HasReturnvaluesIF::RETURN_OK; -#elif defined(__unix__) +#elif defined(PLATFORM_UNIX) timespec timeUnix; int status = clock_gettime(CLOCK_REALTIME,&timeUnix); if(status!=0){ @@ -87,14 +87,14 @@ ReturnValue_t Clock::getClock_usecs(uint64_t* time) { timeval Clock::getUptime() { timeval timeval; -#if defined(_WIN32) +#if defined(PLATFORM_WIN) auto uptime = std::chrono::milliseconds(GetTickCount64()); auto secondsChrono = std::chrono::duration_cast(uptime); timeval.tv_sec = secondsChrono.count(); auto fraction = uptime - secondsChrono; timeval.tv_usec = std::chrono::duration_cast( fraction).count(); -#elif defined(__unix__) +#elif defined(PLATFORM_UNIX) double uptimeSeconds; if (std::ifstream("/proc/uptime", std::ios::in) >> uptimeSeconds) { @@ -121,7 +121,7 @@ ReturnValue_t Clock::getUptime(uint32_t* uptimeMs) { return HasReturnvaluesIF::RETURN_OK; } - +ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) { /* Do some magic with chrono (C++20!) */ /* Right now, the library doesn't have the new features to get the required values yet. so we work around that for now. */ diff --git a/platform.h b/platform.h index 08260094..4bca3398 100644 --- a/platform.h +++ b/platform.h @@ -2,14 +2,9 @@ #define FSFW_PLATFORM_H_ #if defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)) - #define PLATFORM_UNIX - #elif defined(_WIN32) - #define PLATFORM_WIN - #endif - #endif /* FSFW_PLATFORM_H_ */ From 4fa56a2f1d3424c2afa30d34013ce2e11533ae84 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 12 May 2021 18:37:52 +0200 Subject: [PATCH 216/230] moved string port argument --- osal/common/UdpTmTcBridge.cpp | 2 +- osal/common/UdpTmTcBridge.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osal/common/UdpTmTcBridge.cpp b/osal/common/UdpTmTcBridge.cpp index ba23f521..a3b4efa7 100644 --- a/osal/common/UdpTmTcBridge.cpp +++ b/osal/common/UdpTmTcBridge.cpp @@ -21,7 +21,7 @@ const std::string UdpTmTcBridge::DEFAULT_UDP_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; UdpTmTcBridge::UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, - object_id_t tmStoreId, object_id_t tcStoreId, std::string udpServerPort): + std::string udpServerPort, object_id_t tmStoreId, object_id_t tcStoreId): TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) { if(udpServerPort == "") { this->udpServerPort = DEFAULT_UDP_SERVER_PORT; diff --git a/osal/common/UdpTmTcBridge.h b/osal/common/UdpTmTcBridge.h index 8b8d1949..49d846a1 100644 --- a/osal/common/UdpTmTcBridge.h +++ b/osal/common/UdpTmTcBridge.h @@ -28,8 +28,8 @@ public: /* The ports chosen here should not be used by any other process. */ static const std::string DEFAULT_UDP_SERVER_PORT; - UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, - object_id_t tmStoreId, object_id_t tcStoreId, std::string udpServerPort = ""); + UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, std::string udpServerPort = "", + object_id_t tmStoreId = objects::TM_STORE, object_id_t tcStoreId = objects::TC_STORE); virtual~ UdpTmTcBridge(); /** From 0bc124fd2187bfad49589562bba812ac79a1d387 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 13 May 2021 21:46:46 +0200 Subject: [PATCH 217/230] renamed tcpip tasks --- unittest/user/testcfg/objects/systemObjectList.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unittest/user/testcfg/objects/systemObjectList.h b/unittest/user/testcfg/objects/systemObjectList.h index 88b92131..76f1ff90 100644 --- a/unittest/user/testcfg/objects/systemObjectList.h +++ b/unittest/user/testcfg/objects/systemObjectList.h @@ -15,8 +15,8 @@ namespace objects { PUS_DISTRIBUTOR = 11, TM_FUNNEL = 12, - UDP_BRIDGE = 15, - UDP_POLLING_TASK = 16, + TCPIP_BRIDGE = 15, + TCPIP_HELPER = 16, TEST_ECHO_COM_IF = 20, TEST_DEVICE = 21, From 5847081a246aea8d56b184e122052bd792b02661 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 13 May 2021 22:17:21 +0200 Subject: [PATCH 218/230] tweaks and fixes for TCP --- osal/common/TcpTmTcServer.cpp | 7 ++++--- osal/common/TcpTmTcServer.h | 2 +- osal/windows/tcpipHelpers.cpp | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/osal/common/TcpTmTcServer.cpp b/osal/common/TcpTmTcServer.cpp index 0663fed1..28fab422 100644 --- a/osal/common/TcpTmTcServer.cpp +++ b/osal/common/TcpTmTcServer.cpp @@ -99,8 +99,8 @@ 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_t connSocket = 0; - sockaddr clientSockAddr = {}; - socklen_t connectorSockAddrLen = 0; + // sockaddr clientSockAddr = {}; + // socklen_t connectorSockAddrLen = 0; int retval = 0; // Listen for connection requests permanently for lifetime of program @@ -111,7 +111,8 @@ ReturnValue_t TcpTmTcServer::performOperation(uint8_t opCode) { continue; } - connSocket = accept(listenerTcpSocket, &clientSockAddr, &connectorSockAddrLen); + //connSocket = accept(listenerTcpSocket, &clientSockAddr, &connectorSockAddrLen); + connSocket = accept(listenerTcpSocket, nullptr, nullptr); if(connSocket == INVALID_SOCKET) { handleError(Protocol::TCP, ErrorSources::ACCEPT_CALL, 500); diff --git a/osal/common/TcpTmTcServer.h b/osal/common/TcpTmTcServer.h index 191fff7b..f7c36d69 100644 --- a/osal/common/TcpTmTcServer.h +++ b/osal/common/TcpTmTcServer.h @@ -43,7 +43,7 @@ class TcpTmTcServer: 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; + static constexpr size_t ETHERNET_MTU_SIZE = 1500; /** diff --git a/osal/windows/tcpipHelpers.cpp b/osal/windows/tcpipHelpers.cpp index 03278a92..3dab9406 100644 --- a/osal/windows/tcpipHelpers.cpp +++ b/osal/windows/tcpipHelpers.cpp @@ -50,8 +50,8 @@ void tcpip::handleError(Protocol protocol, ErrorSources errorSrc, dur_millis_t s sif::warning << "tcpip::handleError: " << protocolString << " | " << errorSrcString << " | " << infoString << std::endl; #else - sif::printWarning("tcpip::handleError: %s | %s | %s\n", protocolString, - errorSrcString, infoString); + sif::printWarning("tcpip::handleError: %s | %s | %s\n", protocolString.c_str(), + errorSrcString.c_str(), infoString.c_str()); #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ #endif /* FSFW_VERBOSE_LEVEL >= 1 */ From 58a532fc4d54139ed0f39517e03f2b7788870c9a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 18 May 2021 11:13:28 +0200 Subject: [PATCH 219/230] added health service to fsfw objects --- objectmanager/frameworkObjects.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/objectmanager/frameworkObjects.h b/objectmanager/frameworkObjects.h index 2174f829..47ba6df2 100644 --- a/objectmanager/frameworkObjects.h +++ b/objectmanager/frameworkObjects.h @@ -16,6 +16,8 @@ enum framework_objects: object_id_t { PUS_SERVICE_17_TEST = 0x53000017, PUS_SERVICE_20_PARAMETERS = 0x53000020, PUS_SERVICE_200_MODE_MGMT = 0x53000200, + PUS_SERVICE_201_HEALTH = 0x53000201, + //Generic IDs for IPC, modes, health, events HEALTH_TABLE = 0x53010000, From d3423b30b0f0e2259f9fbde12b1757d54cdd1259 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 18 May 2021 11:14:26 +0200 Subject: [PATCH 220/230] minot changes --- objectmanager/frameworkObjects.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/objectmanager/frameworkObjects.h b/objectmanager/frameworkObjects.h index 47ba6df2..fdb72e30 100644 --- a/objectmanager/frameworkObjects.h +++ b/objectmanager/frameworkObjects.h @@ -1,7 +1,7 @@ #ifndef FSFW_OBJECTMANAGER_FRAMEWORKOBJECTS_H_ #define FSFW_OBJECTMANAGER_FRAMEWORKOBJECTS_H_ -#include +#include "SystemObjectIF.h" namespace objects { enum framework_objects: object_id_t { @@ -18,7 +18,6 @@ enum framework_objects: object_id_t { PUS_SERVICE_200_MODE_MGMT = 0x53000200, PUS_SERVICE_201_HEALTH = 0x53000201, - //Generic IDs for IPC, modes, health, events HEALTH_TABLE = 0x53010000, // MODE_STORE = 0x53010100, From 9e0146f5791b1c7f34c467e7118f4efb683d7205 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 18 May 2021 11:16:54 +0200 Subject: [PATCH 221/230] comment added --- objectmanager/frameworkObjects.h | 1 + 1 file changed, 1 insertion(+) diff --git a/objectmanager/frameworkObjects.h b/objectmanager/frameworkObjects.h index fdb72e30..36010807 100644 --- a/objectmanager/frameworkObjects.h +++ b/objectmanager/frameworkObjects.h @@ -3,6 +3,7 @@ #include "SystemObjectIF.h" +// The objects will be instantiated in the ID order namespace objects { enum framework_objects: object_id_t { FSFW_OBJECTS_START = 0x53000000, From 94062c67d398966ef814a206811fde07b926866a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 18 May 2021 11:28:37 +0200 Subject: [PATCH 222/230] added more pus services --- events/fwSubsystemIdRanges.h | 51 ++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/events/fwSubsystemIdRanges.h b/events/fwSubsystemIdRanges.h index 1b0b238e..88dee9b4 100644 --- a/events/fwSubsystemIdRanges.h +++ b/events/fwSubsystemIdRanges.h @@ -1,30 +1,37 @@ #ifndef FSFW_EVENTS_FWSUBSYSTEMIDRANGES_H_ #define FSFW_EVENTS_FWSUBSYSTEMIDRANGES_H_ +#include + namespace SUBSYSTEM_ID { -enum { - MEMORY = 22, - OBSW = 26, - CDH = 28, - TCS_1 = 59, - PCDU_1 = 42, - PCDU_2 = 43, - HEATER = 50, - T_SENSORS = 52, - FDIR = 70, - FDIR_1 = 71, - FDIR_2 = 72, - HK = 73, - SYSTEM_MANAGER = 74, - SYSTEM_MANAGER_1 = 75, - SYSTEM_1 = 79, - PUS_SERVICE_1 = 80, - PUS_SERVICE_9 = 89, - PUS_SERVICE_17 = 97, - FW_SUBSYSTEM_ID_RANGE +enum: uint8_t { + MEMORY = 22, + OBSW = 26, + CDH = 28, + TCS_1 = 59, + PCDU_1 = 42, + PCDU_2 = 43, + HEATER = 50, + T_SENSORS = 52, + FDIR = 70, + FDIR_1 = 71, + FDIR_2 = 72, + HK = 73, + SYSTEM_MANAGER = 74, + SYSTEM_MANAGER_1 = 75, + SYSTEM_1 = 79, + PUS_SERVICE_1 = 80, + PUS_SERVICE_2 = 82, + PUS_SERVICE_3 = 83, + PUS_SERVICE_5 = 85, + PUS_SERVICE_6 = 86, + PUS_SERVICE_8 = 88, + PUS_SERVICE_9 = 89, + PUS_SERVICE_17 = 97, + PUS_SERVICE_23 = 103, + + FW_SUBSYSTEM_ID_RANGE }; } - - #endif /* FSFW_EVENTS_FWSUBSYSTEMIDRANGES_H_ */ From 6db2efc20dc04de5e433ad2a66f23b89a70bb875 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 18 May 2021 11:36:36 +0200 Subject: [PATCH 223/230] copmment block for fw class ids --- returnvalues/FwClassIds.h | 135 ++++++++++++++++++++------------------ 1 file changed, 70 insertions(+), 65 deletions(-) diff --git a/returnvalues/FwClassIds.h b/returnvalues/FwClassIds.h index 4c9f022b..2bb83f73 100644 --- a/returnvalues/FwClassIds.h +++ b/returnvalues/FwClassIds.h @@ -1,72 +1,77 @@ #ifndef FSFW_RETURNVALUES_FWCLASSIDS_H_ #define FSFW_RETURNVALUES_FWCLASSIDS_H_ +#include + +// The comment block at the end is used by the returnvalue exporter. +// It is recommended to add it as well for mission returnvalues namespace CLASS_ID { -enum { - OPERATING_SYSTEM_ABSTRACTION = 1, //OS - OBJECT_MANAGER_IF, //OM - DEVICE_HANDLER_BASE, //DHB - RMAP_CHANNEL, //RMP - POWER_SWITCH_IF, //PS - HAS_MEMORY_IF, //PP - DEVICE_STATE_MACHINE_BASE, //DSMB - DATA_SET_CLASS, //DPS - POOL_RAW_ACCESS_CLASS, //DPR - CONTROLLER_BASE, //CTR - SUBSYSTEM_BASE, //SB - MODE_STORE_IF, //MS - SUBSYSTEM, //SS - HAS_MODES_IF, //HM - COMMAND_MESSAGE, //CM - CCSDS_TIME_HELPER_CLASS, //TIM - ARRAY_LIST, //AL - ASSEMBLY_BASE, //AB - MEMORY_HELPER, //MH - SERIALIZE_IF, //SE - FIXED_MAP, //FM - FIXED_MULTIMAP, //FMM - HAS_HEALTH_IF, //HHI - FIFO_CLASS, //FF - MESSAGE_PROXY, //MQP - TRIPLE_REDUNDACY_CHECK, //TRC - TC_PACKET_CHECK, //TCC - PACKET_DISTRIBUTION, //TCD - ACCEPTS_TELECOMMANDS_IF, //PUS - DEVICE_SERVICE_BASE, //DSB - COMMAND_SERVICE_BASE, //CSB - TM_STORE_BACKEND_IF, //TMB - TM_STORE_FRONTEND_IF, //TMF - STORAGE_AND_RETRIEVAL_SERVICE, //SR - MATCH_TREE_CLASS, //MT - EVENT_MANAGER_IF, //EV - HANDLES_FAILURES_IF, //FDI - DEVICE_HANDLER_IF, //DHI - STORAGE_MANAGER_IF, //SM - THERMAL_COMPONENT_IF, //TC - INTERNAL_ERROR_CODES, //IEC - TRAP, //TRP - CCSDS_HANDLER_IF, //CCS - PARAMETER_WRAPPER, //PAW - HAS_PARAMETERS_IF, //HPA - ASCII_CONVERTER, //ASC - POWER_SWITCHER, //POS - LIMITS_IF, //LIM - COMMANDS_ACTIONS_IF, //CF - HAS_ACTIONS_IF, //HF - DEVICE_COMMUNICATION_IF, //DC - BSP, //BSP - TIME_STAMPER_IF, //TSI 53 - SGP4PROPAGATOR_CLASS, //SGP4 54 - MUTEX_IF, //MUX 55 - MESSAGE_QUEUE_IF,//MQI 56 - SEMAPHORE_IF, //SPH 57 - LOCAL_POOL_OWNER_IF, //LPIF 58 - POOL_VARIABLE_IF, //PVA 59 - HOUSEKEEPING_MANAGER, //HKM 60 - DLE_ENCODER, //DLEE 61 - PUS_SERVICE_9, //PUS9 62 - FILE_SYSTEM, //FILS 63 - FW_CLASS_ID_COUNT //is actually count + 1 ! +enum: uint8_t { + OPERATING_SYSTEM_ABSTRACTION = 1, //OS + OBJECT_MANAGER_IF, //OM + DEVICE_HANDLER_BASE, //DHB + RMAP_CHANNEL, //RMP + POWER_SWITCH_IF, //PS + HAS_MEMORY_IF, //PP + DEVICE_STATE_MACHINE_BASE, //DSMB + DATA_SET_CLASS, //DPS + POOL_RAW_ACCESS_CLASS, //DPR + CONTROLLER_BASE, //CTR + SUBSYSTEM_BASE, //SB + MODE_STORE_IF, //MS + SUBSYSTEM, //SS + HAS_MODES_IF, //HM + COMMAND_MESSAGE, //CM + CCSDS_TIME_HELPER_CLASS, //TIM + ARRAY_LIST, //AL + ASSEMBLY_BASE, //AB + MEMORY_HELPER, //MH + SERIALIZE_IF, //SE + FIXED_MAP, //FM + FIXED_MULTIMAP, //FMM + HAS_HEALTH_IF, //HHI + FIFO_CLASS, //FF + MESSAGE_PROXY, //MQP + TRIPLE_REDUNDACY_CHECK, //TRC + TC_PACKET_CHECK, //TCC + PACKET_DISTRIBUTION, //TCD + ACCEPTS_TELECOMMANDS_IF, //PUS + DEVICE_SERVICE_BASE, //DSB + COMMAND_SERVICE_BASE, //CSB + TM_STORE_BACKEND_IF, //TMB + TM_STORE_FRONTEND_IF, //TMF + STORAGE_AND_RETRIEVAL_SERVICE, //SR + MATCH_TREE_CLASS, //MT + EVENT_MANAGER_IF, //EV + HANDLES_FAILURES_IF, //FDI + DEVICE_HANDLER_IF, //DHI + STORAGE_MANAGER_IF, //SM + THERMAL_COMPONENT_IF, //TC + INTERNAL_ERROR_CODES, //IEC + TRAP, //TRP + CCSDS_HANDLER_IF, //CCS + PARAMETER_WRAPPER, //PAW + HAS_PARAMETERS_IF, //HPA + ASCII_CONVERTER, //ASC + POWER_SWITCHER, //POS + LIMITS_IF, //LIM + COMMANDS_ACTIONS_IF, //CF + HAS_ACTIONS_IF, //HF + DEVICE_COMMUNICATION_IF, //DC + BSP, //BSP + TIME_STAMPER_IF, //TSI + SGP4PROPAGATOR_CLASS, //SGP4 + MUTEX_IF, //MUX + MESSAGE_QUEUE_IF,//MQI + SEMAPHORE_IF, //SPH + LOCAL_POOL_OWNER_IF, //LPIF + POOL_VARIABLE_IF, //PVA + HOUSEKEEPING_MANAGER, //HKM + DLE_ENCODER, //DLEE + PUS_SERVICE_3, //PUS3 + PUS_SERVICE_9, //PUS9 + FILE_SYSTEM, //FILS + FW_CLASS_ID_COUNT //is actually count + 1 ! }; } From c07672f9b461531e065213e0ef77e0246f09674f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 18 May 2021 14:57:54 +0200 Subject: [PATCH 224/230] changed class id file for refactored modgen --- returnvalues/FwClassIds.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/returnvalues/FwClassIds.h b/returnvalues/FwClassIds.h index 2bb83f73..17c37a79 100644 --- a/returnvalues/FwClassIds.h +++ b/returnvalues/FwClassIds.h @@ -7,7 +7,8 @@ // It is recommended to add it as well for mission returnvalues namespace CLASS_ID { enum: uint8_t { - OPERATING_SYSTEM_ABSTRACTION = 1, //OS + FW_CLASS_ID_START = 0, // [EXPORT] : [START] + OPERATING_SYSTEM_ABSTRACTION, //OS OBJECT_MANAGER_IF, //OM DEVICE_HANDLER_BASE, //DHB RMAP_CHANNEL, //RMP @@ -71,7 +72,7 @@ enum: uint8_t { PUS_SERVICE_3, //PUS3 PUS_SERVICE_9, //PUS9 FILE_SYSTEM, //FILS - FW_CLASS_ID_COUNT //is actually count + 1 ! + FW_CLASS_ID_COUNT // [EXPORT] : [END] }; } From e2ae9756f3eda0a54d1ec2c2beecba18d74c3618 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 18 May 2021 15:12:48 +0200 Subject: [PATCH 225/230] updated documentation --- doc/README-config.md | 24 ++++++++++++++++++--- doc/README-core.md | 20 ++++++++++++------ doc/README-highlevel.md | 47 ++++++++++++++++++++++++----------------- 3 files changed, 62 insertions(+), 29 deletions(-) diff --git a/doc/README-config.md b/doc/README-config.md index 036a7d14..b314b84e 100644 --- a/doc/README-config.md +++ b/doc/README-config.md @@ -1,10 +1,27 @@ - ## Configuring the FSFW The FSFW can be configured via the `fsfwconfig` folder. A template folder has been provided to have a starting point for this. The folder should be added -to the include path. +to the include path. The primary configuration file is the `FSFWConfig.h` folder. Some +of the available options will be explained in more detail here. +## Auto-Translation of Events + +The FSFW allows the automatic translation of events, which allows developers to track triggered +events directly via consoke output. Using this feature requires: + +1. `FSFW_OBJ_EVENT_TRANSLATION` set to 1 in the configuration file. +2. Special auto-generated translation files which translate event IDs and object IDs into + human readable strings. These files can be generated using the + [modgen Python scripts](https://git.ksat-stuttgart.de/source/modgen.git). +3. The generated translation files for the object IDs should be named `translatesObjects.cpp` + and `translateObjects.h` and should be copied to the `fsfwconfig/objects` folder +4. The generated translation files for the event IDs should be named `translateEvents.cpp` and + `translateEvents.h` and should be copied to the `fsfwconfig/events` folder + +An example implementations of these translation file generators can be found as part +of the [SOURCE project here](https://git.ksat-stuttgart.de/source/sourceobsw/-/tree/development/generators) +or the [FSFW example](https://egit.irs.uni-stuttgart.de/fsfw/fsfw_example_public/src/branch/master/generators) ### Configuring the Event Manager @@ -18,4 +35,5 @@ static constexpr size_t FSFW_EVENTMGMR_MATCHTREE_NODES = 240; static constexpr size_t FSFW_EVENTMGMT_EVENTIDMATCHERS = 120; static constexpr size_t FSFW_EVENTMGMR_RANGEMATCHERS = 120; } -``` \ No newline at end of file +``` + diff --git a/doc/README-core.md b/doc/README-core.md index 6431b831..e34890ae 100644 --- a/doc/README-core.md +++ b/doc/README-core.md @@ -19,8 +19,9 @@ A nullptr check of the returning Pointer must be done. This function is based on ```cpp template T* ObjectManagerIF::get( object_id_t id ) ``` -* A typical way to create all objects on startup is a handing a static produce function to the ObjectManager on creation. -By calling objectManager->initialize() the produce function will be called and all SystemObjects will be initialized afterwards. +* A typical way to create all objects on startup is a handing a static produce function to the + ObjectManager on creation. By calling objectManager->initialize() the produce function will be + called and all SystemObjects will be initialized afterwards. ### Event Manager @@ -36,14 +37,19 @@ By calling objectManager->initialize() the produce function will be called and a ### Stores -* The message based communication can only exchange a few bytes of information inside the message itself. Therefore, additional information can - be exchanged with Stores. With this, only the store address must be exchanged in the message. -* Internally, the FSFW uses an IPC Store to exchange data between processes. For incoming TCs a TC Store is used. For outgoing TM a TM store is used. +* The message based communication can only exchange a few bytes of information inside the message + itself. Therefore, additional information can be exchanged with Stores. With this, only the + store address must be exchanged in the message. +* Internally, the FSFW uses an IPC Store to exchange data between processes. For incoming TCs a TC + Store is used. For outgoing TM a TM store is used. * All of them should use the Thread Safe Class storagemanager/PoolManager ### Tasks There are two different types of tasks: - * The PeriodicTask just executes objects that are of type ExecutableObjectIF in the order of the insertion to the Tasks. - * FixedTimeslotTask executes a list of calls in the order of the given list. This is intended for DeviceHandlers, where polling should be in a defined order. An example can be found in defaultcfg/fsfwconfig/pollingSequence + * The PeriodicTask just executes objects that are of type ExecutableObjectIF in the order of the + insertion to the Tasks. + * FixedTimeslotTask executes a list of calls in the order of the given list. This is intended for + DeviceHandlers, where polling should be in a defined order. An example can be found in + `defaultcfg/fsfwconfig/pollingSequence` folder diff --git a/doc/README-highlevel.md b/doc/README-highlevel.md index fac89c53..dd94d6da 100644 --- a/doc/README-highlevel.md +++ b/doc/README-highlevel.md @@ -3,11 +3,12 @@ ## Structure The general structure is driven by the usage of interfaces provided by objects. -The FSFW uses C++11 as baseline. The intention behind this is that this C++ Standard should be widely available, even with older compilers. +The FSFW uses C++11 as baseline. The intention behind this is that this C++ Standard should be +widely available, even with older compilers. The FSFW uses dynamic allocation during the initialization but provides static containers during runtime. This simplifies the instantiation of objects and allows the usage of some standard containers. -Dynamic Allocation after initialization is discouraged and different solutions are provided in the FSFW to achieve that. -The fsfw uses run-time type information but exceptions are not allowed. +Dynamic Allocation after initialization is discouraged and different solutions are provided in the +FSFW to achieve that. The fsfw uses run-time type information but exceptions are not allowed. ### Failure Handling @@ -41,10 +42,11 @@ An example setup of ids can be found in the example config in "defaultcft/fsfwco ### Events -Events are tied to objects. EventIds can be generated by calling the Macro MAKE_EVENT. This works analog to the returnvalues. -Every object that needs own EventIds has to get a unique SUBSYSTEM_ID. -Every SystemObject can call triggerEvent from the parent class. -Therefore, event messages contain the specific EventId and the objectId of the object that has triggered. +Events are tied to objects. EventIds can be generated by calling the Macro MAKE_EVENT. +This works analog to the returnvalues. Every object that needs own EventIds has to get a +unique SUBSYSTEM_ID. Every SystemObject can call triggerEvent from the parent class. +Therefore, event messages contain the specific EventId and the objectId of the object that +has triggered. ### Internal Communication @@ -59,17 +61,19 @@ The services can be seen as a conversion from a TC to a message based communicat #### CCSDS Frames, CCSDS Space Packets and PUS -If the communication is based on CCSDS Frames and Space Packets, several classes can be used to distributed the packets to the corresponding services. Those can be found in tcdistribution. -If Space Packets are used, a timestamper must be created. -An example can be found in the timemanager folder, this uses CCSDSTime::CDS_short. +If the communication is based on CCSDS Frames and Space Packets, several classes can be used to +distributed the packets to the corresponding services. Those can be found in `tcdistribution`. +If Space Packets are used, a timestamper has to be provided by the user. +An example can be found in the `timemanager` folder, which uses `CCSDSTime::CDS_short`. #### Device Handlers DeviceHandlers are another important component of the FSFW. -The idea is, to have a software counterpart of every physical device to provide a simple mode, health and commanding interface. -By separating the underlying Communication Interface with DeviceCommunicationIF, a device handler (DH) can be tested on different hardware. -The DH has mechanisms to monitor the communication with the physical device which allow for FDIR reaction. -Device Handlers can be created by overriding `DeviceHandlerBase`. +The idea is, to have a software counterpart of every physical device to provide a simple mode, +health and commanding interface. By separating the underlying Communication Interface with +`DeviceCommunicationIF`, a device handler (DH) can be tested on different hardware. +The DH has mechanisms to monitor the communication with the physical device which allow +for FDIR reaction. Device Handlers can be created by implementing `DeviceHandlerBase`. A standard FDIR component for the DH will be created automatically but can be overwritten by the user. More information on DeviceHandlers can be found in the related [documentation section](doc/README-devicehandlers.md#top). @@ -81,13 +85,17 @@ DeviceHandlers and Controllers are the lowest part of the hierarchy. The next layer are Assemblies. Those assemblies act as a component which handle redundancies of handlers. Assemblies share a common core with the next level which are the Subsystems. -Those Assemblies are intended to act as auto-generated components from a database which describes the subsystem modes. -The definitions contain transition and target tables which contain the DH, Assembly and Controller Modes to be commanded. -Transition tables contain as many steps as needed to reach the mode from any other mode, e.g. a switch into any higher AOCS mode might first turn on the sensors, than the actuators and the controller as last component. +Those Assemblies are intended to act as auto-generated components from a database which describes +the subsystem modes. The definitions contain transition and target tables which contain the DH, +Assembly and Controller Modes to be commanded. +Transition tables contain as many steps as needed to reach the mode from any other mode, e.g. a +switch into any higher AOCS mode might first turn on the sensors, than the actuators and the +controller as last component. The target table is used to describe the state that is checked continuously by the subsystem. All of this allows System Modes to be generated as Subsystem object as well from the same database. This System contains list of subsystem modes in the transition and target tables. -Therefore, it allows a modular system to create system modes and easy commanding of those, because only the highest components must be commanded. +Therefore, it allows a modular system to create system modes and easy commanding of those, because +only the highest components must be commanded. The health state represents if the component is able to perform its tasks. This can be used to signal the system to avoid using this component instead of a redundant one. @@ -95,5 +103,6 @@ The on-board FDIR uses the health state for isolation and recovery. ## Unit Tests -Unit Tests are provided in the unittest folder. Those use the catch2 framework but do not include catch2 itself. More information on how to run these tests can be found in the separate +Unit Tests are provided in the unittest folder. Those use the catch2 framework but do not include +catch2 itself. More information on how to run these tests can be found in the separate [`fsfw_tests` reposoitory](https://egit.irs.uni-stuttgart.de/fsfw/fsfw_tests) From ed27d388d5d954dfbb580b5972d6dfcb3cf59aef Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 18 May 2021 15:31:04 +0200 Subject: [PATCH 226/230] added tmtc chapter in doc --- doc/README-config.md | 7 ++-- doc/README-highlevel.md | 84 ++++++++++++++++++++++++++--------------- 2 files changed, 58 insertions(+), 33 deletions(-) diff --git a/doc/README-config.md b/doc/README-config.md index b314b84e..6afba83c 100644 --- a/doc/README-config.md +++ b/doc/README-config.md @@ -1,11 +1,12 @@ -## Configuring the FSFW +Configuring the FSFW +====== The FSFW can be configured via the `fsfwconfig` folder. A template folder has been provided to have a starting point for this. The folder should be added to the include path. The primary configuration file is the `FSFWConfig.h` folder. Some of the available options will be explained in more detail here. -## Auto-Translation of Events +# Auto-Translation of Events The FSFW allows the automatic translation of events, which allows developers to track triggered events directly via consoke output. Using this feature requires: @@ -23,7 +24,7 @@ An example implementations of these translation file generators can be found as of the [SOURCE project here](https://git.ksat-stuttgart.de/source/sourceobsw/-/tree/development/generators) or the [FSFW example](https://egit.irs.uni-stuttgart.de/fsfw/fsfw_example_public/src/branch/master/generators) -### Configuring the Event Manager +## Configuring the Event Manager The number of allowed subscriptions can be modified with the following parameters: diff --git a/doc/README-highlevel.md b/doc/README-highlevel.md index dd94d6da..7bf96c64 100644 --- a/doc/README-highlevel.md +++ b/doc/README-highlevel.md @@ -1,6 +1,7 @@ -# High-level overview +High-level overview +====== -## Structure +# Structure The general structure is driven by the usage of interfaces provided by objects. The FSFW uses C++11 as baseline. The intention behind this is that this C++ Standard should be @@ -10,37 +11,44 @@ This simplifies the instantiation of objects and allows the usage of some standa Dynamic Allocation after initialization is discouraged and different solutions are provided in the FSFW to achieve that. The fsfw uses run-time type information but exceptions are not allowed. -### Failure Handling +# Failure Handling -Functions should return a defined ReturnValue_t to signal to the caller that something has gone wrong. -Returnvalues must be unique. For this the function HasReturnvaluesIF::makeReturnCode or the Macro MAKE_RETURN can be used. -The CLASS_ID is a unique id for that type of object. See returnvalues/FwClassIds. +Functions should return a defined `ReturnValue_t` to signal to the caller that something has +gone wrong. Returnvalues must be unique. For this the function `HasReturnvaluesIF::makeReturnCode` +or the macro `MAKE_RETURN` can be used. The `CLASS_ID` is a unique id for that type of object. +See `returnvalues/FwClassIds` folder. The user can add custom `CLASS_ID`s via the +`fsfwconfig` folder. -### OSAL +# OSAL The FSFW provides operation system abstraction layers for Linux, FreeRTOS and RTEMS. The OSAL provides periodic tasks, message queues, clocks and semaphores as well as mutexes. -The [OSAL README](doc/README-osal.md#top) provides more detailed information on provided components and how to use them. +The [OSAL README](doc/README-osal.md#top) provides more detailed information on provided components +and how to use them. -### Core Components +# Core Components The FSFW has following core components. More detailed informations can be found in the [core component section](doc/README-core.md#top): -1. Tasks: Abstraction for different (periodic) task types like periodic tasks or tasks with fixed timeslots -2. ObjectManager: This module stores all `SystemObjects` by mapping a provided unique object ID to the object handles. -3. Static Stores: Different stores are provided to store data of variable size (like telecommands or small telemetry) in a pool structure without - using dynamic memory allocation. These pools are allocated up front. +1. Tasks: Abstraction for different (periodic) task types like periodic tasks or tasks + with fixed timeslots +2. ObjectManager: This module stores all `SystemObjects` by mapping a provided unique object ID + to the object handles. +3. Static Stores: Different stores are provided to store data of variable size (like telecommands + or small telemetry) in a pool structure without using dynamic memory allocation. + These pools are allocated up front. 3. Clock: This module provided common time related functions 4. EventManager: This module allows routing of events generated by `SystemObjects` 5. HealthTable: A component which stores the health states of objects -### Static IDs in the framework +# Static IDs in the framework Some parts of the framework use a static routing address for communication. -An example setup of ids can be found in the example config in "defaultcft/fsfwconfig/objects/Factory::setStaticFrameworkObjectIds()". +An example setup of ids can be found in the example config in `defaultcft/fsfwconfig/objects` + inside the function `Factory::setStaticFrameworkObjectIds()`. -### Events +# Events Events are tied to objects. EventIds can be generated by calling the Macro MAKE_EVENT. This works analog to the returnvalues. Every object that needs own EventIds has to get a @@ -48,25 +56,39 @@ unique SUBSYSTEM_ID. Every SystemObject can call triggerEvent from the parent cl Therefore, event messages contain the specific EventId and the objectId of the object that has triggered. -### Internal Communication +# Internal Communication -Components communicate mostly over Message through Queues. -Those queues are created by calling the singleton QueueFactory::instance()->create(). +Components communicate mostly via Messages through Queues. +Those queues are created by calling the singleton `QueueFactory::instance()->create()` which +will create `MessageQueue` instances for the used OSAL. -### External Communication +# External Communication The external communication with the mission control system is mostly up to the user implementation. The FSFW provides PUS Services which can be used to but don't need to be used. The services can be seen as a conversion from a TC to a message based communication and back. -#### CCSDS Frames, CCSDS Space Packets and PUS +## TMTC Communication + +The FSFW provides some components to facilitate TMTC handling via the PUS commands. +For example, a UDP or TCP PUS server socket can be opended on a specific port using the +files located in `osal/common`. The FSFW example uses this functionality to allow sending telecommands +and receiving telemetry using the [TMTC commander application](https://github.com/spacefisch/tmtccmd). +Simple commands like the PUS Service 17 ping service can be tested by simply running the +`tmtc_client_cli.py` or `tmtc_client_gui.py` utility in +the [example tmtc folder](https://egit.irs.uni-stuttgart.de/fsfw/fsfw_example_public/src/branch/master/tmtc). + +More generally, any class responsible for handling incoming telecommands and sending telemetry +can implement the generic `TmTcBridge` class located in `tmtcservices`. + +## CCSDS Frames, CCSDS Space Packets and PUS If the communication is based on CCSDS Frames and Space Packets, several classes can be used to distributed the packets to the corresponding services. Those can be found in `tcdistribution`. If Space Packets are used, a timestamper has to be provided by the user. An example can be found in the `timemanager` folder, which uses `CCSDSTime::CDS_short`. -#### Device Handlers +# Device Handlers DeviceHandlers are another important component of the FSFW. The idea is, to have a software counterpart of every physical device to provide a simple mode, @@ -74,16 +96,18 @@ health and commanding interface. By separating the underlying Communication Inte `DeviceCommunicationIF`, a device handler (DH) can be tested on different hardware. The DH has mechanisms to monitor the communication with the physical device which allow for FDIR reaction. Device Handlers can be created by implementing `DeviceHandlerBase`. -A standard FDIR component for the DH will be created automatically but can be overwritten by the user. -More information on DeviceHandlers can be found in the related [documentation section](doc/README-devicehandlers.md#top). +A standard FDIR component for the DH will be created automatically but can +be overwritten by the user. More information on DeviceHandlers can be found in the +related [documentation section](doc/README-devicehandlers.md#top). -#### Modes, Health +# Modes and Health -The two interfaces HasModesIF and HasHealthIF provide access for commanding and monitoring of components. -On-board Mode Management is implement in hierarchy system. +The two interfaces `HasModesIF` and `HasHealthIF` provide access for commanding and monitoring +of components. On-board Mode Management is implement in hierarchy system. DeviceHandlers and Controllers are the lowest part of the hierarchy. -The next layer are Assemblies. Those assemblies act as a component which handle redundancies of handlers. -Assemblies share a common core with the next level which are the Subsystems. +The next layer are Assemblies. Those assemblies act as a component which handle +redundancies of handlers. Assemblies share a common core with the next level which +are the Subsystems. Those Assemblies are intended to act as auto-generated components from a database which describes the subsystem modes. The definitions contain transition and target tables which contain the DH, @@ -101,7 +125,7 @@ The health state represents if the component is able to perform its tasks. This can be used to signal the system to avoid using this component instead of a redundant one. The on-board FDIR uses the health state for isolation and recovery. -## Unit Tests +# Unit Tests Unit Tests are provided in the unittest folder. Those use the catch2 framework but do not include catch2 itself. More information on how to run these tests can be found in the separate From a8c0d96c3901d7424fdc4cb81e9d970599e3614e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 18 May 2021 15:32:52 +0200 Subject: [PATCH 227/230] some fixes --- doc/README-highlevel.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/README-highlevel.md b/doc/README-highlevel.md index 7bf96c64..33a73239 100644 --- a/doc/README-highlevel.md +++ b/doc/README-highlevel.md @@ -71,12 +71,13 @@ The services can be seen as a conversion from a TC to a message based communicat ## TMTC Communication The FSFW provides some components to facilitate TMTC handling via the PUS commands. -For example, a UDP or TCP PUS server socket can be opended on a specific port using the +For example, a UDP or TCP PUS server socket can be opened on a specific port using the files located in `osal/common`. The FSFW example uses this functionality to allow sending telecommands and receiving telemetry using the [TMTC commander application](https://github.com/spacefisch/tmtccmd). Simple commands like the PUS Service 17 ping service can be tested by simply running the `tmtc_client_cli.py` or `tmtc_client_gui.py` utility in -the [example tmtc folder](https://egit.irs.uni-stuttgart.de/fsfw/fsfw_example_public/src/branch/master/tmtc). +the [example tmtc folder](https://egit.irs.uni-stuttgart.de/fsfw/fsfw_example_public/src/branch/master/tmtc) +while the `fsfw_example` application is running. More generally, any class responsible for handling incoming telecommands and sending telemetry can implement the generic `TmTcBridge` class located in `tmtcservices`. From e147d5a4f58650adfb2c1466c437173f573723ee Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 18 May 2021 15:34:31 +0200 Subject: [PATCH 228/230] some more information --- doc/README-highlevel.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/README-highlevel.md b/doc/README-highlevel.md index 33a73239..262138a7 100644 --- a/doc/README-highlevel.md +++ b/doc/README-highlevel.md @@ -80,7 +80,9 @@ the [example tmtc folder](https://egit.irs.uni-stuttgart.de/fsfw/fsfw_example_pu while the `fsfw_example` application is running. More generally, any class responsible for handling incoming telecommands and sending telemetry -can implement the generic `TmTcBridge` class located in `tmtcservices`. +can implement the generic `TmTcBridge` class located in `tmtcservices`. Many applications +also use a dedicated polling task for reading telecommands which passes telecommands +to the `TmTcBridge` implementation. ## CCSDS Frames, CCSDS Space Packets and PUS From b7060a9c78e57f755f9c04de37e8195ddc83194e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 18 May 2021 15:35:47 +0200 Subject: [PATCH 229/230] update README --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index fb3be429..484d65c0 100644 --- a/README.md +++ b/README.md @@ -38,11 +38,12 @@ a starting point. The [configuration section](doc/README-config.md#top) provides [1. High-level overview](doc/README-highlevel.md#top)
[2. Core components](doc/README-core.md#top)
-[3. OSAL overview](doc/README-osal.md#top)
-[4. PUS services](doc/README-pus.md#top)
-[5. Device Handler overview](doc/README-devicehandlers.md#top)
-[6. Controller overview](doc/README-controllers.md#top)
-[7. Local Data Pools](doc/README-localpools.md#top)
+[3. Configuration](doc/README-config.md#top)
+[4. OSAL overview](doc/README-osal.md#top)
+[5. PUS services](doc/README-pus.md#top)
+[6. Device Handler overview](doc/README-devicehandlers.md#top)
+[7. Controller overview](doc/README-controllers.md#top)
+[8. Local Data Pools](doc/README-localpools.md#top)
From 36030ef87c96b0fce7664d8c57e12f540fa43090 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 18 May 2021 15:37:05 +0200 Subject: [PATCH 230/230] typo --- doc/README-config.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/README-config.md b/doc/README-config.md index 6afba83c..d71feb97 100644 --- a/doc/README-config.md +++ b/doc/README-config.md @@ -9,7 +9,7 @@ of the available options will be explained in more detail here. # Auto-Translation of Events The FSFW allows the automatic translation of events, which allows developers to track triggered -events directly via consoke output. Using this feature requires: +events directly via console output. Using this feature requires: 1. `FSFW_OBJ_EVENT_TRANSLATION` set to 1 in the configuration file. 2. Special auto-generated translation files which translate event IDs and object IDs into