From caa3cf538b5e6a1ba390c71d863ed9a85de0dc20 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 5 Mar 2021 13:34:06 +0100 Subject: [PATCH 01/80] formatting correction --- devicehandlers/DeviceHandlerBase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index a19e2cbc0..d61b0407d 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -119,7 +119,7 @@ public: DeviceHandlerIF::DEFAULT_THERMAL_STATE_POOL_ID, lp_id_t thermalRequestPoolId = DeviceHandlerIF::DEFAULT_THERMAL_HEATING_REQUEST_POOL_ID, - uint32_t thermalSetId = DeviceHandlerIF::DEFAULT_THERMAL_SET_ID); + uint32_t thermalSetId = DeviceHandlerIF::DEFAULT_THERMAL_SET_ID); /** * @brief Helper function to ease device handler development. * This will instruct the transition to MODE_ON immediately From 17b8d3fed05cae6e208dc3f14b6ba0d44c9ec5ef Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Mar 2021 18:12:41 +0100 Subject: [PATCH 02/80] printout for trans timeout --- devicehandlers/DeviceHandlerBase.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 10de57bd4..0649aaa04 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; From 778ef4ef230019ca4b155a77518156793cf5d308 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Mar 2021 20:36:54 +0100 Subject: [PATCH 03/80] cleaned up a bit, no functional change --- osal/linux/PosixThread.cpp | 336 ++++++++++++++++++------------------- 1 file changed, 167 insertions(+), 169 deletions(-) diff --git a/osal/linux/PosixThread.cpp b/osal/linux/PosixThread.cpp index bd8e72583..bc5cacee4 100644 --- a/osal/linux/PosixThread.cpp +++ b/osal/linux/PosixThread.cpp @@ -6,252 +6,250 @@ #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); } PosixThread::~PosixThread() { - //No deletion and no free of Stack Pointer + //No deletion and no free of Stack Pointer } ReturnValue_t PosixThread::sleep(uint64_t ns) { - //TODO sleep might be better with timer instead of sleep() - timespec time; - time.tv_sec = ns/1000000000; - time.tv_nsec = ns - time.tv_sec*1e9; + //TODO sleep might be better with timer instead of sleep() + timespec time; + time.tv_sec = ns/1000000000; + time.tv_nsec = ns - time.tv_sec*1e9; - //Remaining Time is not set here - int status = nanosleep(&time,NULL); - if(status != 0){ - switch(errno){ - case EINTR: - //The nanosleep() function was interrupted by a signal. - return HasReturnvaluesIF::RETURN_FAILED; - case EINVAL: - //The rqtp argument specified a nanosecond value less than zero or - // greater than or equal to 1000 million. - return HasReturnvaluesIF::RETURN_FAILED; - default: - return HasReturnvaluesIF::RETURN_FAILED; - } + //Remaining Time is not set here + int status = nanosleep(&time,NULL); + if(status != 0){ + switch(errno){ + case EINTR: + //The nanosleep() function was interrupted by a signal. + return HasReturnvaluesIF::RETURN_FAILED; + case EINVAL: + //The rqtp argument specified a nanosecond value less than zero or + // greater than or equal to 1000 million. + return HasReturnvaluesIF::RETURN_FAILED; + default: + return HasReturnvaluesIF::RETURN_FAILED; + } - } - return HasReturnvaluesIF::RETURN_OK; + } + return HasReturnvaluesIF::RETURN_OK; } void PosixThread::suspend() { - //Wait for SIGUSR1 - int caughtSig = 0; - sigset_t waitSignal; - sigemptyset(&waitSignal); - sigaddset(&waitSignal, SIGUSR1); - sigwait(&waitSignal, &caughtSig); - if (caughtSig != SIGUSR1) { + //Wait for SIGUSR1 + int caughtSig = 0; + sigset_t waitSignal; + sigemptyset(&waitSignal); + sigaddset(&waitSignal, SIGUSR1); + sigwait(&waitSignal, &caughtSig); + if (caughtSig != SIGUSR1) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "FixedTimeslotTask: Unknown Signal received: " << - caughtSig << std::endl; + sif::error << "FixedTimeslotTask: Unknown Signal received: " << + caughtSig << std::endl; #endif - } + } } void PosixThread::resume(){ - /* Signal the thread to start. Makes sense to call kill to start or? ;) - * - * According to Posix raise(signal) will call pthread_kill(pthread_self(), sig), - * but as the call must be done from the thread itsself this is not possible here - */ - pthread_kill(thread,SIGUSR1); + /* Signal the thread to start. Makes sense to call kill to start or? ;) + According to POSIX raise(signal) will call pthread_kill(pthread_self(), sig), + but as the call must be done from the thread itself this is not possible here */ + pthread_kill(thread,SIGUSR1); } bool PosixThread::delayUntil(uint64_t* const prevoiusWakeTime_ms, - const uint64_t delayTime_ms) { - uint64_t nextTimeToWake_ms; - bool shouldDelay = false; - //Get current Time - const uint64_t currentTime_ms = getCurrentMonotonicTimeMs(); - /* Generate the tick time at which the task wants to wake. */ - nextTimeToWake_ms = (*prevoiusWakeTime_ms) + delayTime_ms; + const uint64_t delayTime_ms) { + uint64_t nextTimeToWake_ms; + bool shouldDelay = false; + /* Get current Time */ + const uint64_t currentTime_ms = getCurrentMonotonicTimeMs(); + /* Generate the tick time at which the task wants to wake. */ + nextTimeToWake_ms = (*prevoiusWakeTime_ms) + delayTime_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 + 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. */ - if ((nextTimeToWake_ms < *prevoiusWakeTime_ms) - && (nextTimeToWake_ms > currentTime_ms)) { - shouldDelay = true; - } - } else { - /* The tick time has not overflowed. In this case we will + 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. */ - if ((nextTimeToWake_ms < *prevoiusWakeTime_ms) - || (nextTimeToWake_ms > currentTime_ms)) { - shouldDelay = true; - } - } + if ((nextTimeToWake_ms < *prevoiusWakeTime_ms) + || (nextTimeToWake_ms > currentTime_ms)) { + shouldDelay = true; + } + } - /* Update the wake time ready for the next call. */ + /* Update the wake time ready for the next call. */ - (*prevoiusWakeTime_ms) = nextTimeToWake_ms; + (*prevoiusWakeTime_ms) = nextTimeToWake_ms; - if (shouldDelay) { - uint64_t sleepTime = nextTimeToWake_ms - currentTime_ms; - PosixThread::sleep(sleepTime * 1000000ull); - return true; - } - //We are shifting the time in case the deadline was missed like rtems - (*prevoiusWakeTime_ms) = currentTime_ms; - return false; + if (shouldDelay) { + uint64_t sleepTime = nextTimeToWake_ms - currentTime_ms; + PosixThread::sleep(sleepTime * 1000000ull); + return true; + } + /* We are shifting the time in case the deadline was missed like RTEMS */ + (*prevoiusWakeTime_ms) = currentTime_ms; + return false; } uint64_t PosixThread::getCurrentMonotonicTimeMs(){ - timespec timeNow; - clock_gettime(CLOCK_MONOTONIC_RAW, &timeNow); - uint64_t currentTime_ms = (uint64_t) timeNow.tv_sec * 1000 - + timeNow.tv_nsec / 1000000; + timespec timeNow; + clock_gettime(CLOCK_MONOTONIC_RAW, &timeNow); + uint64_t currentTime_ms = (uint64_t) timeNow.tv_sec * 1000 + + timeNow.tv_nsec / 1000000; - return currentTime_ms; + return currentTime_ms; } void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - //sif::debug << "PosixThread::createTask" << std::endl; + //sif::debug << "PosixThread::createTask" << std::endl; #endif - /* - * The attr argument points to a pthread_attr_t structure whose contents - are used at thread creation time to determine attributes for the new - thread; this structure is initialized using pthread_attr_init(3) and - related functions. If attr is NULL, then the thread is created with - default attributes. - */ - pthread_attr_t attributes; - int status = pthread_attr_init(&attributes); - if(status != 0){ + /* + * The attr argument points to a pthread_attr_t structure whose contents + * are used at thread creation time to determine attributes for the new + * thread; this structure is initialized using pthread_attr_init(3) and + * related functions. If attr is NULL, then the thread is created with + * default attributes. + */ + pthread_attr_t attributes; + int status = pthread_attr_init(&attributes); + if(status != 0){ #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "Posix Thread attribute init failed with: " << - strerror(status) << std::endl; + sif::error << "Posix Thread attribute init failed with: " << + strerror(status) << std::endl; #endif - } - void* stackPointer; - status = posix_memalign(&stackPointer, sysconf(_SC_PAGESIZE), stackSize); - if(status != 0){ + } + void* stackPointer; + status = posix_memalign(&stackPointer, sysconf(_SC_PAGESIZE), stackSize); + if(status != 0){ #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PosixThread::createTask: Stack init failed with: " << - strerror(status) << std::endl; + sif::error << "PosixThread::createTask: Stack init failed with: " << + strerror(status) << std::endl; #endif - if(errno == ENOMEM) { - size_t stackMb = stackSize/10e6; + if(errno == ENOMEM) { + size_t stackMb = stackSize/10e6; #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PosixThread::createTask: Insufficient memory for" - " the requested " << stackMb << " MB" << std::endl; + sif::error << "PosixThread::createTask: Insufficient memory for" + " the requested " << stackMb << " MB" << std::endl; #else - sif::printError("PosixThread::createTask: Insufficient memory for " - "the requested %lu MB\n", static_cast(stackMb)); + sif::printError("PosixThread::createTask: Insufficient memory for " + "the requested %lu MB\n", static_cast(stackMb)); #endif - } - else if(errno == EINVAL) { + } + else if(errno == EINVAL) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PosixThread::createTask: Wrong alignment argument!" - << std::endl; + sif::error << "PosixThread::createTask: Wrong alignment argument!" + << std::endl; #else - sif::printError("PosixThread::createTask: " - "Wrong alignment argument!\n"); + sif::printError("PosixThread::createTask: " + "Wrong alignment argument!\n"); #endif - } - return; - } + } + return; + } - status = pthread_attr_setstack(&attributes, stackPointer, stackSize); - if(status != 0){ + status = pthread_attr_setstack(&attributes, stackPointer, stackSize); + if(status != 0){ #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PosixThread::createTask: pthread_attr_setstack " - " failed with: " << strerror(status) << std::endl; - sif::error << "Make sure the specified stack size is valid and is " - "larger than the minimum allowed stack size." << std::endl; + sif::error << "PosixThread::createTask: pthread_attr_setstack " + " failed with: " << strerror(status) << std::endl; + sif::error << "Make sure the specified stack size is valid and is " + "larger than the minimum allowed stack size." << std::endl; #endif - } + } - status = pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED); - if(status != 0){ + status = pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED); + if(status != 0){ #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "Posix Thread attribute setinheritsched failed with: " << - strerror(status) << std::endl; + sif::error << "Posix Thread attribute setinheritsched failed with: " << + strerror(status) << std::endl; #endif - } + } - // TODO FIFO -> This needs root privileges for the process - status = pthread_attr_setschedpolicy(&attributes,SCHED_FIFO); - if(status != 0){ + // TODO FIFO -> This needs root privileges for the process + status = pthread_attr_setschedpolicy(&attributes,SCHED_FIFO); + if(status != 0){ #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "Posix Thread attribute schedule policy failed with: " << - strerror(status) << std::endl; + sif::error << "Posix Thread attribute schedule policy failed with: " << + strerror(status) << std::endl; #endif - } + } - sched_param scheduleParams; - scheduleParams.__sched_priority = priority; - status = pthread_attr_setschedparam(&attributes, &scheduleParams); - if(status != 0){ + sched_param scheduleParams; + scheduleParams.__sched_priority = priority; + status = pthread_attr_setschedparam(&attributes, &scheduleParams); + if(status != 0){ #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "Posix Thread attribute schedule params failed with: " << - strerror(status) << std::endl; + sif::error << "Posix Thread attribute schedule params failed with: " << + strerror(status) << std::endl; #endif - } + } - //Set Signal Mask for suspend until startTask is called - sigset_t waitSignal; - sigemptyset(&waitSignal); - sigaddset(&waitSignal, SIGUSR1); - status = pthread_sigmask(SIG_BLOCK, &waitSignal, NULL); - if(status != 0){ + //Set Signal Mask for suspend until startTask is called + sigset_t waitSignal; + sigemptyset(&waitSignal); + sigaddset(&waitSignal, SIGUSR1); + status = pthread_sigmask(SIG_BLOCK, &waitSignal, NULL); + if(status != 0){ #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "Posix Thread sigmask failed failed with: " << - strerror(status) << " errno: " << strerror(errno) << std::endl; + sif::error << "Posix Thread sigmask failed failed with: " << + strerror(status) << " errno: " << strerror(errno) << std::endl; #endif - } + } - status = pthread_create(&thread,&attributes,fnc_,arg_); - if(status != 0){ + status = pthread_create(&thread,&attributes,fnc_,arg_); + if(status != 0){ #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "Posix Thread create failed with: " << - strerror(status) << std::endl; + sif::error << "Posix Thread create failed with: " << + strerror(status) << std::endl; #endif - } + } - status = pthread_setname_np(thread,name); - if(status != 0){ + status = pthread_setname_np(thread,name); + if(status != 0){ #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PosixThread::createTask: setname failed with: " << - strerror(status) << std::endl; + sif::error << "PosixThread::createTask: setname failed with: " << + strerror(status) << std::endl; #endif - if(status == ERANGE) { + if(status == ERANGE) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PosixThread::createTask: Task name length longer" - " than 16 chars. Truncating.." << std::endl; + sif::error << "PosixThread::createTask: Task name length longer" + " than 16 chars. Truncating.." << std::endl; #endif - name[15] = '\0'; - status = pthread_setname_np(thread,name); - if(status != 0){ + name[15] = '\0'; + status = pthread_setname_np(thread,name); + if(status != 0){ #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PosixThread::createTask: Setting name" - " did not work.." << std::endl; + sif::error << "PosixThread::createTask: Setting name" + " did not work.." << std::endl; #endif - } - } - } + } + } + } - status = pthread_attr_destroy(&attributes); - if(status!=0){ + status = pthread_attr_destroy(&attributes); + if(status!=0){ #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "Posix Thread attribute destroy failed with: " << - strerror(status) << std::endl; + sif::error << "Posix Thread attribute destroy failed with: " << + strerror(status) << std::endl; #endif - } + } } From e7cd7c8dc30aaa87cf4a411cf1849c6424c1b2b2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 7 Mar 2021 01:35:55 +0100 Subject: [PATCH 04/80] 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 89b76388a..7af636b67 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 a5867222b..6504e20c5 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 e5ea15983..2d70712b2 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 3d3fe17f3..530b3e450 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 4fd88c937..f9b3753e6 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 50d39d25f..063a783e1 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 69a48f3ee..ac8901985 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 04f8658ea..778d2b71f 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 659b68530..68b07c329 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 6a6664853..55d492543 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 05/80] 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 95ba012eb..b5b8c6601 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 f069819bc..d5d43933b 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 06/80] typo --- pus/Service3Housekeeping.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pus/Service3Housekeeping.cpp b/pus/Service3Housekeeping.cpp index 5456764d0..c4f80c2a5 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 07/80] removed obsolete comment --- storagemanager/LocalPool.h | 1 - 1 file changed, 1 deletion(-) diff --git a/storagemanager/LocalPool.h b/storagemanager/LocalPool.h index 55d492543..6a6664853 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 08/80] 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 b6e76d6a3..889ea3396 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 000000000..aebc0bee1 --- /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 000000000..3a17336aa --- /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 f9b3753e6..32c217001 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 063a783e1..8a9cf51f6 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 ac8901985..dce88bb22 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 8188039c0..b51c8c7ac 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 09/80] 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 dce88bb22..07fedd024 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 10/80] 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 aebc0bee1..756e77767 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 3a17336aa..4f53dda42 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 07fedd024..375e45e7c 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 b51c8c7ac..143541398 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 11/80] 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 756e77767..d090df459 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 4f53dda42..45d92ff80 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 375e45e7c..d4467e441 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 12/80] 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 d090df459..1cf7ed1da 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 45d92ff80..7b679106e 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 32c217001..06e75bd5b 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 13/80] 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 1cf7ed1da..f85147f04 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 7b679106e..f8aebc530 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 14/80] 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 2b8b67127..98af5fb8a 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 bc744d3f9..f0c955094 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 69a48f3ee..94805cdca 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 4e8014fd3..eec849078 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 15/80] 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 1681325d0..5e20bb6fe 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 43ab6e8fe..66a119ab0 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 72873d993..0c44ab7e5 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 ff6edb95d..d06cf2c6a 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 5b2089b39..044b8fa72 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 98af5fb8a..5d720b191 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 f0c955094..7eee47b5e 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 5786a2252..4dde3a23f 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 16/80] 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 778d2b71f..9ea84dadb 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 68b07c329..ce45f142b 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 17/80] corrections --- power/PowerComponent.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/power/PowerComponent.h b/power/PowerComponent.h index ce45f142b..6b9778a59 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 18/80] 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 7eee47b5e..4ad23012c 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 0af1fc68b..7f110114d 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 19/80] 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 4ad23012c..9ee68c81f 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 dfc045e8d..fe7b8c08e 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 2a54f8134..b50d62dcf 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 aef71fe15..b80786f74 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 36bb9ad3e..d0de33d3c 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 20/80] 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 7eee47b5e..00baa2da2 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 dfc045e8d..fe7b8c08e 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 2a54f8134..b50d62dcf 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 aef71fe15..b80786f74 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 94805cdca..d0de33d3c 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 21/80] 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 00baa2da2..9ee68c81f 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 0af1fc68b..7f110114d 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 22/80] 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 935646477..80bf47b7c 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 561345951..920bbda22 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 a10b44999..cd3be9426 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 5c277850f..8e6b07b00 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 23/80] 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 a7adfc82d..d8bd58c99 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 2bc47568f..db76fc00e 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 24/80] 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 404509ae5..b9946aaf5 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 920bbda22..101116cb2 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 25/80] 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 000000000..c5c470788 --- /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 26/80] 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 7b810b41f..31146d34a 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 27/80] 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 5c277850f..03b0d190c 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 28/80] 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 101116cb2..eb587e3f9 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 e5a5d3645..980ffda19 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 29/80] 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 0c44ab7e5..f572dc026 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 30/80] 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 f572dc026..5c702f1b6 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 31/80] 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 365f00048..e73456777 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 eb587e3f9..9b4509e96 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 32/80] 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 9b4509e96..4def46bec 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 cd3be9426..fd2c78d70 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 8e6b07b00..58ca445cf 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 33/80] 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 5c702f1b6..a9668a32f 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 fd2c78d70..685016ed5 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 58ca445cf..f74c47b5b 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 34/80] 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 a9668a32f..9f0eb779f 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 35/80] 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 d52c72b6c..ec25f082c 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 9f0eb779f..83e30e824 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 2d70712b2..3abbf0dd2 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 b9946aaf5..39ea9f1ac 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 d9803ef65..58f8551d9 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 e73456777..b0dd8522f 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 d96eae1d4..3e8d030e6 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 685016ed5..1ab871519 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 f74c47b5b..20c565ffc 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 36/80] format improvements --- housekeeping/PeriodicHousekeepingHelper.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/housekeeping/PeriodicHousekeepingHelper.cpp b/housekeeping/PeriodicHousekeepingHelper.cpp index b0dd8522f..5152706fa 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 37/80] 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 1ab871519..4457e85bc 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 20c565ffc..eb6d8a5d8 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 38/80] 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 4def46bec..c11c66c22 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 39/80] 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 f196a080a..1c98e7dc2 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 4457e85bc..cce55e1a5 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 000000000..7abbd4542 --- /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 eb6d8a5d8..fc009544f 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 40/80] 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 dd1bdcc40..9915628ea 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 83f2a72f1..bbb47da49 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 c11c66c22..30b5bb059 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 cce55e1a5..2d7294efa 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 7abbd4542..0e2703a77 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 fc009544f..7915eeb4d 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 41/80] 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 bdca22c3d..73ec4bd70 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 b8d98794d..da21f9cfc 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 3abbf0dd2..d93b926d2 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 9915628ea..abcf7da96 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 bbb47da49..8d12610a8 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 30b5bb059..ecc1921f1 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 7915eeb4d..9a7639f84 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 42/80] 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 9151f2f8e..f905cc4d7 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 da21f9cfc..4d23f87f5 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 ecc1921f1..06964d266 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 9a7639f84..f08b9eb94 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 43/80] added addtional nullptr check --- datapoollocal/LocalDataPoolManager.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/datapoollocal/LocalDataPoolManager.h b/datapoollocal/LocalDataPoolManager.h index d06cf2c6a..2ec81f1cf 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 44/80] 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 83e30e824..cad54094e 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 d93b926d2..2a2444c48 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 39ea9f1ac..ab67dc3f9 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 7a34e9c8e..f81428cd1 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 5152706fa..892eb354a 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 3e8d030e6..3256fbffa 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 2d7294efa..c152078d9 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 0e2703a77..7ccceb063 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 f08b9eb94..c045b6d39 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 31146d34a..3000f7fb5 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 45/80] 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 ec25f082c..54856fac3 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 cad54094e..e9bb57c48 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 58f8551d9..90ca73c8c 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 c152078d9..883327192 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 7ccceb063..991314a9d 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 c045b6d39..8d2073b0e 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 46/80] 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 54856fac3..74e372c9e 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 47/80] 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 e9bb57c48..94ee9c264 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 af8ce7115..daab8b9c0 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 7dc056b08..20a64f5b6 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 883327192..a98db6103 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 48/80] 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 73ec4bd70..60f08b88c 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 abcf7da96..84c2d1c37 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 06964d266..ce4d9d437 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 49/80] 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 889ea3396..a3a719e0a 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 f85147f04..000000000 --- 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 f8aebc530..000000000 --- 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 50/80] 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 50afd4af5..45b40d379 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 a98db6103..4df735cd2 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 51/80] 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 a3a719e0a..889ea3396 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 000000000..f85147f04 --- /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 000000000..f8aebc530 --- /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 52/80] 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 4df735cd2..52485b011 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 53/80] 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 ce4d9d437..d0b13e86f 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 54/80] 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 bf7707d11..f3b98fd1d 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 f85147f04..3cdd1d3fd 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 06e75bd5b..c86fd03a9 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 03daa6d7b..eb5db0b3f 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 143541398..e32854b67 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 55/80] 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 c86fd03a9..38633388f 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 eb5db0b3f..1a624355a 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 12d163d16..228bf4f5d 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 56/80] 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 38633388f..502b798fa 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 1a624355a..346abcd44 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 e32854b67..b433f6f1e 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 57/80] 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 889ea3396..a2b316880 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 3cdd1d3fd..49c278c5c 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 f8aebc530..bd9f35765 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 502b798fa..324547faf 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 8a9cf51f6..707ad2824 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 346abcd44..204be0377 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 b433f6f1e..b381e2cc5 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 000000000..3ad4bc825 --- /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 000000000..a88b0479a --- /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 58/80] 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 204be0377..e4952f359 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 b381e2cc5..989b4f7b8 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 59/80] 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 474e548bf..6c3778448 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 000000000..7d25752d1 --- /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 000000000..269a10368 --- /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 60/80] 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 7f110114d..ae1ad781c 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 ae6f6adca..c45672b66 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 e4952f359..b857ba671 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 989b4f7b8..762849f8b 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 61/80] 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 02ff24057..e4f1de7c7 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 000000000..b77985fbd --- /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 000000000..9a5e4647c --- /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 000000000..b59981ed3 --- /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 11ed7fee6..71557069e 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 cc0325616..39ee0914d 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 ae1ad781c..856985608 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 c45672b66..f5e671388 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 7d25752d1..1c3807696 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 269a10368..6b337c62d 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 b857ba671..113c98fb9 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 3ad4bc825..ef07f5ca8 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 a88b0479a..01f009b93 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 62/80] 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 856985608..c8dc612cc 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 63/80] 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 c8dc612cc..8de62cabc 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 f5e671388..26b6f0f75 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 113c98fb9..d2b2b2ec1 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 762849f8b..5cae308de 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 64/80] 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 8de62cabc..cf3c80ecf 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 65/80] 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 d2b2b2ec1..8b19b59ee 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 5cae308de..603f2b08d 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 66/80] 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 8b19b59ee..2dd5699bc 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 603f2b08d..51dcfe99b 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 67/80] 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 b59981ed3..9b38c9fba 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 71557069e..37dadb765 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 cf3c80ecf..2f620849b 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 26b6f0f75..3ab2118cc 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 2dd5699bc..ca0fe2d1d 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 68/80] 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 324547faf..ce77deb94 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 707ad2824..35e3a701e 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 ca0fe2d1d..c4c26e686 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 69/80] 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 ce77deb94..980404f9d 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 c4c26e686..f9c97caaa 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 70/80] 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 2a2444c48..16c6857d9 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 71/80] msc stuff --- datapoollocal/LocalPoolDataSetBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datapoollocal/LocalPoolDataSetBase.cpp b/datapoollocal/LocalPoolDataSetBase.cpp index 16c6857d9..6aa66f829 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 72/80] 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 2d70712b2..6aa66f829 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 404509ae5..ab67dc3f9 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 73/80] 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 f9c97caaa..fd289ed8d 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 74/80] smaller tweak --- datapoollocal/LocalPoolDataSetBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datapoollocal/LocalPoolDataSetBase.cpp b/datapoollocal/LocalPoolDataSetBase.cpp index 6aa66f829..99c7a1cd2 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 75/80] 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 99c7a1cd2..d78940488 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 49c278c5c..f68edfba6 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 51dcfe99b..c2f7d6aaa 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 76/80] more explicit --- datapoollocal/LocalPoolDataSetBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datapoollocal/LocalPoolDataSetBase.cpp b/datapoollocal/LocalPoolDataSetBase.cpp index d78940488..7f181c930 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 aa849894c65309a269475dca704b6bddb07702b7 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 18 Mar 2021 20:09:19 +0100 Subject: [PATCH 77/80] 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 7f181c930..a72e9db11 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 78/80] 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 fd289ed8d..8755c84a2 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 79/80] 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 2f620849b..fa7913ea6 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 83d0db824289b28dbad81cce0c80276c4fc839c8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 20 Mar 2021 15:53:43 +0100 Subject: [PATCH 80/80] 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 fa7913ea6..767c3cfea 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 3ab2118cc..c39c43f73 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;