From 537a30a4de78bd0f86a60a4b73cb861cd38c1a7e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 13 Jun 2021 12:34:06 +0200 Subject: [PATCH 1/4] added pus a tc --- FSFW.h | 7 ++++++ tmtcpacket/pus/CMakeLists.txt | 3 ++- tmtcpacket/pus/TcPacketBase.h | 25 --------------------- tmtcpacket/pus/TcPacketPusA.cpp | 3 +++ tmtcpacket/pus/TcPacketPusA.h | 40 +++++++++++++++++++++++++++++++++ tmtcpacket/pus/TcPacketPusC.cpp | 4 ++++ tmtcpacket/pus/TcPacketPusC.h | 8 +++++++ 7 files changed, 64 insertions(+), 26 deletions(-) create mode 100644 FSFW.h create mode 100644 tmtcpacket/pus/TcPacketPusA.cpp create mode 100644 tmtcpacket/pus/TcPacketPusA.h create mode 100644 tmtcpacket/pus/TcPacketPusC.cpp create mode 100644 tmtcpacket/pus/TcPacketPusC.h diff --git a/FSFW.h b/FSFW.h new file mode 100644 index 000000000..df06ff3df --- /dev/null +++ b/FSFW.h @@ -0,0 +1,7 @@ +#ifndef FSFW_FSFW_H_ +#define FSFW_FSFW_H_ + +#include "FSFWConfig.h" + + +#endif /* FSFW_FSFW_H_ */ diff --git a/tmtcpacket/pus/CMakeLists.txt b/tmtcpacket/pus/CMakeLists.txt index cd4f49f17..2d22cb668 100644 --- a/tmtcpacket/pus/CMakeLists.txt +++ b/tmtcpacket/pus/CMakeLists.txt @@ -1,6 +1,7 @@ target_sources(${LIB_FSFW_NAME} - PRIVATE + PRIVATE TcPacketBase.cpp + TcPacketPusA.cpp TcPacketStored.cpp TmPacketBase.cpp TmPacketMinimal.cpp diff --git a/tmtcpacket/pus/TcPacketBase.h b/tmtcpacket/pus/TcPacketBase.h index 582a22140..451f9c3aa 100644 --- a/tmtcpacket/pus/TcPacketBase.h +++ b/tmtcpacket/pus/TcPacketBase.h @@ -4,31 +4,6 @@ #include "../../tmtcpacket/SpacePacketBase.h" #include - -/** - * This struct defines a byte-wise structured PUS TC Data Field Header. - * Any optional fields in the header must be added or removed here. - * Currently, the Source Id field is present with one byte. - * @ingroup tmtcpackets - */ -struct PUSTcDataFieldHeader { - uint8_t version_type_ack; - uint8_t service_type; - uint8_t service_subtype; - uint8_t source_id; -}; - -/** - * This struct defines the data structure of a PUS Telecommand Packet when - * accessed via a pointer. - * @ingroup tmtcpackets - */ -struct TcPacketPointer { - CCSDSPrimaryHeader primary; - PUSTcDataFieldHeader dataField; - uint8_t appData; -}; - /** * This class is the basic data handler for any ECSS PUS Telecommand packet. * diff --git a/tmtcpacket/pus/TcPacketPusA.cpp b/tmtcpacket/pus/TcPacketPusA.cpp new file mode 100644 index 000000000..c9af38a63 --- /dev/null +++ b/tmtcpacket/pus/TcPacketPusA.cpp @@ -0,0 +1,3 @@ +#include "TcPacketPusA.h" + + diff --git a/tmtcpacket/pus/TcPacketPusA.h b/tmtcpacket/pus/TcPacketPusA.h new file mode 100644 index 000000000..9254ad32f --- /dev/null +++ b/tmtcpacket/pus/TcPacketPusA.h @@ -0,0 +1,40 @@ +#ifndef FSFW_TMTCPACKET_PUS_TCPACKETPUSA_H_ +#define FSFW_TMTCPACKET_PUS_TCPACKETPUSA_H_ + +#include "ccsds_header.h" +#include "TcPacketBase.h" + +#include + +/** + * This struct defines a byte-wise structured PUS TC A Data Field Header. + * Any optional fields in the header must be added or removed here. + * Currently, the Source Id field is present with one byte. + * @ingroup tmtcpackets + */ +struct PUSTcDataFieldHeader { + uint8_t version_type_ack; + uint8_t service_type; + uint8_t service_subtype; + uint8_t source_id; +}; + +/** + * This struct defines the data structure of a PUS Telecommand A packet when + * accessed via a pointer. + * @ingroup tmtcpackets + */ +struct TcPacketPointer { + CCSDSPrimaryHeader primary; + PUSTcDataFieldHeader dataField; + uint8_t appData; +}; + + +class TcPacketPusA: public TcPacketBase { +public: +private: +}; + + +#endif /* FSFW_TMTCPACKET_PUS_TCPACKETPUSA_H_ */ diff --git a/tmtcpacket/pus/TcPacketPusC.cpp b/tmtcpacket/pus/TcPacketPusC.cpp new file mode 100644 index 000000000..1f2946a85 --- /dev/null +++ b/tmtcpacket/pus/TcPacketPusC.cpp @@ -0,0 +1,4 @@ +#include "TcPacketPusC.h" + + + diff --git a/tmtcpacket/pus/TcPacketPusC.h b/tmtcpacket/pus/TcPacketPusC.h new file mode 100644 index 000000000..e965e752d --- /dev/null +++ b/tmtcpacket/pus/TcPacketPusC.h @@ -0,0 +1,8 @@ +#ifndef FSFW_TMTCPACKET_PUS_TCPACKETPUSC_H_ +#define FSFW_TMTCPACKET_PUS_TCPACKETPUSC_H_ + + + + + +#endif /* FSFW_TMTCPACKET_PUS_TCPACKETPUSC_H_ */ From d0f37b851b4de0fd71521cec5ff19ded413c2d3e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 13 Jun 2021 16:29:13 +0200 Subject: [PATCH 2/4] added pus c support for tc --- defaultcfg/fsfwconfig/FSFWConfig.h | 21 +++-- tcdistribution/CMakeLists.txt | 11 +-- tcdistribution/PUSDistributor.cpp | 7 +- tcdistribution/PUSDistributor.h | 8 +- tcdistribution/TcPacketCheck.cpp | 58 ++++++------ tcdistribution/TcPacketCheck.h | 84 ++++++++--------- tmtcpacket/CMakeLists.txt | 7 +- tmtcpacket/pus/CMakeLists.txt | 25 ++--- tmtcpacket/pus/TcPacketBase.cpp | 82 ++-------------- tmtcpacket/pus/TcPacketBase.h | 53 ++++------- tmtcpacket/pus/TcPacketPusA.cpp | 72 ++++++++++++++ tmtcpacket/pus/TcPacketPusA.h | 47 +++++++++- tmtcpacket/pus/TcPacketStored.cpp | 124 ------------------------- tmtcpacket/pus/TcPacketStored.h | 122 ++---------------------- tmtcpacket/pus/TcPacketStoredBase.cpp | 72 ++++++++++++++ tmtcpacket/pus/TcPacketStoredBase.h | 90 ++++++++++++++++++ tmtcpacket/pus/TcPacketStoredIF.h | 38 ++++++++ tmtcpacket/pus/TcPacketStoredPusA.cpp | 77 +++++++++++++++ tmtcpacket/pus/TcPacketStoredPusA.h | 53 +++++++++++ tmtcpacket/pus/TcPacketStoredPusC.cpp | 10 ++ tmtcpacket/pus/TmPacketBase.cpp | 15 +-- tmtcservices/CommandingServiceBase.cpp | 44 +++++---- tmtcservices/CommandingServiceBase.h | 7 +- tmtcservices/PusServiceBase.h | 6 +- tmtcservices/VerificationReporter.cpp | 22 +++-- 25 files changed, 667 insertions(+), 488 deletions(-) delete mode 100644 tmtcpacket/pus/TcPacketStored.cpp create mode 100644 tmtcpacket/pus/TcPacketStoredBase.cpp create mode 100644 tmtcpacket/pus/TcPacketStoredBase.h create mode 100644 tmtcpacket/pus/TcPacketStoredIF.h create mode 100644 tmtcpacket/pus/TcPacketStoredPusA.cpp create mode 100644 tmtcpacket/pus/TcPacketStoredPusA.h create mode 100644 tmtcpacket/pus/TcPacketStoredPusC.cpp diff --git a/defaultcfg/fsfwconfig/FSFWConfig.h b/defaultcfg/fsfwconfig/FSFWConfig.h index 1abdab4cd..5518e33c1 100644 --- a/defaultcfg/fsfwconfig/FSFWConfig.h +++ b/defaultcfg/fsfwconfig/FSFWConfig.h @@ -7,29 +7,30 @@ //! Used to determine whether C++ ostreams are used which can increase //! the binary size significantly. If this is disabled, //! the C stdio functions can be used alternatively -#define FSFW_CPP_OSTREAM_ENABLED 1 +#define FSFW_CPP_OSTREAM_ENABLED 1 //! More FSFW related printouts depending on level. Useful for development. -#define FSFW_VERBOSE_LEVEL 1 +#define FSFW_VERBOSE_LEVEL 1 //! Can be used to completely disable printouts, even the C stdio ones. #if FSFW_CPP_OSTREAM_ENABLED == 0 && FSFW_VERBOSE_LEVEL == 0 - #define FSFW_DISABLE_PRINTOUT 0 + #define FSFW_DISABLE_PRINTOUT 0 #endif -#define FSFW_USE_PUS_C_TELEMETRY 1 +#define FSFW_USE_PUS_C_TELEMETRY 1 +#define FSFW_USE_PUS_C_TELECOMMANDS 1 //! Can be used to disable the ANSI color sequences for C stdio. -#define FSFW_COLORED_OUTPUT 1 +#define FSFW_COLORED_OUTPUT 1 //! If FSFW_OBJ_EVENT_TRANSLATION is set to one, //! additional output which requires the translation files translateObjects //! and translateEvents (and their compiled source files) -#define FSFW_OBJ_EVENT_TRANSLATION 0 +#define FSFW_OBJ_EVENT_TRANSLATION 0 #if FSFW_OBJ_EVENT_TRANSLATION == 1 //! Specify whether info events are printed too. -#define FSFW_DEBUG_INFO 1 +#define FSFW_DEBUG_INFO 1 #include "objects/translateObjects.h" #include "events/translateEvents.h" #else @@ -37,17 +38,17 @@ //! When using the newlib nano library, C99 support for stdio facilities //! will not be provided. This define should be set to 1 if this is the case. -#define FSFW_NO_C99_IO 1 +#define FSFW_NO_C99_IO 1 //! Specify whether a special mode store is used for Subsystem components. -#define FSFW_USE_MODESTORE 0 +#define FSFW_USE_MODESTORE 0 //! Defines if the real time scheduler for linux should be used. //! If set to 0, this will also disable priority settings for linux //! as most systems will not allow to set nice values without privileges //! For embedded linux system set this to 1. //! If set to 1 the binary needs "cap_sys_nice=eip" privileges to run -#define FSFW_USE_REALTIME_FOR_LINUX 1 +#define FSFW_USE_REALTIME_FOR_LINUX 1 namespace fsfwconfig { diff --git a/tcdistribution/CMakeLists.txt b/tcdistribution/CMakeLists.txt index 17dc186c3..6f2370761 100644 --- a/tcdistribution/CMakeLists.txt +++ b/tcdistribution/CMakeLists.txt @@ -1,7 +1,6 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - CCSDSDistributor.cpp - PUSDistributor.cpp - TcDistributor.cpp - TcPacketCheck.cpp +target_sources(${LIB_FSFW_NAME} PRIVATE + CCSDSDistributor.cpp + PUSDistributor.cpp + TcDistributor.cpp + TcPacketCheck.cpp ) diff --git a/tcdistribution/PUSDistributor.cpp b/tcdistribution/PUSDistributor.cpp index 0fac9ba09..5c2f734b0 100644 --- a/tcdistribution/PUSDistributor.cpp +++ b/tcdistribution/PUSDistributor.cpp @@ -3,7 +3,6 @@ #include "../objectmanager/ObjectManager.h" #include "../serviceinterface/ServiceInterface.h" -#include "../tmtcpacket/pus/TcPacketStored.h" #include "../tmtcservices/PusVerificationReport.h" #define PUS_DISTRIBUTOR_DEBUGGING 0 @@ -119,7 +118,11 @@ uint16_t PUSDistributor::getIdentifier() { } ReturnValue_t PUSDistributor::initialize() { - currentPacket = new TcPacketStored(); +#if FSFW_USE_PUS_C_TELECOMMANDS == 1 + currentPacket = new TcPacketStoredPusC(); +#else + currentPacket = new TcPacketStoredPusA(); +#endif if(currentPacket == nullptr) { // Should not happen, memory allocation failed! return ObjectManagerIF::CHILD_INIT_FAILED; diff --git a/tcdistribution/PUSDistributor.h b/tcdistribution/PUSDistributor.h index be3804ef2..0c2884519 100644 --- a/tcdistribution/PUSDistributor.h +++ b/tcdistribution/PUSDistributor.h @@ -5,6 +5,7 @@ #include "TcDistributor.h" #include "TcPacketCheck.h" +#include "../tmtcpacket/pus/TcPacketStored.h" #include "../returnvalues/HasReturnvaluesIF.h" #include "../tmtcservices/AcceptsTelecommandsIF.h" #include "../tmtcservices/VerificationReporter.h" @@ -51,7 +52,12 @@ protected: /** * The currently handled packet is stored here. */ - TcPacketStored* currentPacket = nullptr; +#if FSFW_USE_PUS_C_TELECOMMANDS == 1 + TcPacketStoredPusC* currentPacket = nullptr; +#else + TcPacketStoredPusA* currentPacket = nullptr; +#endif + /** * With this variable, the current check status is stored to generate * acceptance messages later. diff --git a/tcdistribution/TcPacketCheck.cpp b/tcdistribution/TcPacketCheck.cpp index 38ed04aaf..e88305cce 100644 --- a/tcdistribution/TcPacketCheck.cpp +++ b/tcdistribution/TcPacketCheck.cpp @@ -1,39 +1,45 @@ #include "TcPacketCheck.h" #include "../globalfunctions/CRC.h" -#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../tmtcpacket/pus/TcPacketBase.h" +#include "../tmtcpacket/pus/TcPacketStoredBase.h" +#include "../serviceinterface/ServiceInterface.h" #include "../storagemanager/StorageManagerIF.h" #include "../tmtcservices/VerificationCodes.h" -TcPacketCheck::TcPacketCheck( uint16_t setApid ) : apid(setApid) { +TcPacketCheck::TcPacketCheck(uint16_t setApid): apid(setApid) { } -ReturnValue_t TcPacketCheck::checkPacket( TcPacketStored* currentPacket ) { - uint16_t calculated_crc = CRC::crc16ccitt( currentPacket->getWholeData(), - currentPacket->getFullSize() ); - if ( calculated_crc != 0 ) { - return INCORRECT_CHECKSUM; - } - bool condition = (not currentPacket->hasSecondaryHeader()) or - (currentPacket->getPacketVersionNumber() != CCSDS_VERSION_NUMBER) or - (not currentPacket->isTelecommand()); - if ( condition ) { - return INCORRECT_PRIMARY_HEADER; - } - if ( currentPacket->getAPID() != this->apid ) - return ILLEGAL_APID; +ReturnValue_t TcPacketCheck::checkPacket(TcPacketStoredBase* currentPacket) { + TcPacketBase* tcPacketBase = currentPacket->getPacketBase(); + if(tcPacketBase == nullptr) { + return RETURN_FAILED; + } + uint16_t calculated_crc = CRC::crc16ccitt(tcPacketBase->getWholeData(), + tcPacketBase->getFullSize()); + if (calculated_crc != 0) { + return INCORRECT_CHECKSUM; + } + bool condition = (not tcPacketBase->hasSecondaryHeader()) or + (tcPacketBase->getPacketVersionNumber() != CCSDS_VERSION_NUMBER) or + (not tcPacketBase->isTelecommand()); + if (condition) { + return INCORRECT_PRIMARY_HEADER; + } + if (tcPacketBase->getAPID() != this->apid) + return ILLEGAL_APID; - if ( not currentPacket->isSizeCorrect() ) { - return INCOMPLETE_PACKET; - } - condition = (currentPacket->getSecondaryHeaderFlag() != CCSDS_SECONDARY_HEADER_FLAG) || - (currentPacket->getPusVersionNumber() != PUS_VERSION_NUMBER); - if ( condition ) { - return INCORRECT_SECONDARY_HEADER; - } - return RETURN_OK; + if (not currentPacket->isSizeCorrect()) { + return INCOMPLETE_PACKET; + } + condition = (tcPacketBase->getSecondaryHeaderFlag() != CCSDS_SECONDARY_HEADER_FLAG) || + (tcPacketBase->getPusVersionNumber() != PUS_VERSION_NUMBER); + if (condition) { + return INCORRECT_SECONDARY_HEADER; + } + return RETURN_OK; } uint16_t TcPacketCheck::getApid() const { - return apid; + return apid; } diff --git a/tcdistribution/TcPacketCheck.h b/tcdistribution/TcPacketCheck.h index 703bb1bb5..f7422c192 100644 --- a/tcdistribution/TcPacketCheck.h +++ b/tcdistribution/TcPacketCheck.h @@ -2,9 +2,10 @@ #define FSFW_TCDISTRIBUTION_TCPACKETCHECK_H_ #include "../returnvalues/HasReturnvaluesIF.h" -#include "../tmtcpacket/pus/TcPacketStored.h" #include "../tmtcservices/PusVerificationReport.h" +class TcPacketStoredBase; + /** * This class performs a formal packet check for incoming PUS Telecommand Packets. * Currently, it only checks if the APID and CRC are correct. @@ -12,49 +13,48 @@ */ class TcPacketCheck : public HasReturnvaluesIF { protected: - /** - * Describes the version number a packet must have to pass. - */ - static constexpr uint8_t CCSDS_VERSION_NUMBER = 0; - /** - * Describes the secondary header a packet must have to pass. - */ - static constexpr uint8_t CCSDS_SECONDARY_HEADER_FLAG = 0; - /** - * Describes the TC Packet PUS Version Number a packet must have to pass. - */ - static constexpr uint8_t PUS_VERSION_NUMBER = 1; - /** - * The packet id each correct packet should have. - * It is composed of the APID and some static fields. - */ - uint16_t apid; + /** + * Describes the version number a packet must have to pass. + */ + static constexpr uint8_t CCSDS_VERSION_NUMBER = 0; + /** + * Describes the secondary header a packet must have to pass. + */ + static constexpr uint8_t CCSDS_SECONDARY_HEADER_FLAG = 0; + /** + * Describes the TC Packet PUS Version Number a packet must have to pass. + */ + static constexpr uint8_t PUS_VERSION_NUMBER = 1; + /** + * The packet id each correct packet should have. + * It is composed of the APID and some static fields. + */ + uint16_t apid; public: - static const uint8_t INTERFACE_ID = CLASS_ID::TC_PACKET_CHECK; - static const ReturnValue_t ILLEGAL_APID = MAKE_RETURN_CODE( 0 ); - static const ReturnValue_t INCOMPLETE_PACKET = MAKE_RETURN_CODE( 1 ); - static const ReturnValue_t INCORRECT_CHECKSUM = MAKE_RETURN_CODE( 2 ); - static const ReturnValue_t ILLEGAL_PACKET_TYPE = MAKE_RETURN_CODE( 3 ); - static const ReturnValue_t ILLEGAL_PACKET_SUBTYPE = MAKE_RETURN_CODE( 4 ); - static const ReturnValue_t INCORRECT_PRIMARY_HEADER = MAKE_RETURN_CODE( 5 ); - static const ReturnValue_t INCORRECT_SECONDARY_HEADER = MAKE_RETURN_CODE( 6 ); - /** - * The constructor only sets the APID attribute. - * @param set_apid The APID to set. - */ - TcPacketCheck( uint16_t setApid ); - /** - * This is the actual method to formally check a certain Telecommand Packet. - * The packet's Application Data can not be checked here. - * @param current_packet The packt to check - * @return - @c RETURN_OK on success. - * - @c INCORRECT_CHECKSUM if checksum is invalid. - * - @c ILLEGAL_APID if APID does not match. - */ - ReturnValue_t checkPacket( TcPacketStored* currentPacket ); + static const uint8_t INTERFACE_ID = CLASS_ID::TC_PACKET_CHECK; + static const ReturnValue_t ILLEGAL_APID = MAKE_RETURN_CODE( 0 ); + static const ReturnValue_t INCOMPLETE_PACKET = MAKE_RETURN_CODE( 1 ); + static const ReturnValue_t INCORRECT_CHECKSUM = MAKE_RETURN_CODE( 2 ); + static const ReturnValue_t ILLEGAL_PACKET_TYPE = MAKE_RETURN_CODE( 3 ); + static const ReturnValue_t ILLEGAL_PACKET_SUBTYPE = MAKE_RETURN_CODE( 4 ); + static const ReturnValue_t INCORRECT_PRIMARY_HEADER = MAKE_RETURN_CODE( 5 ); + static const ReturnValue_t INCORRECT_SECONDARY_HEADER = MAKE_RETURN_CODE( 6 ); + /** + * The constructor only sets the APID attribute. + * @param set_apid The APID to set. + */ + TcPacketCheck(uint16_t setApid); + /** + * This is the actual method to formally check a certain Telecommand Packet. + * The packet's Application Data can not be checked here. + * @param current_packet The packt to check + * @return - @c RETURN_OK on success. + * - @c INCORRECT_CHECKSUM if checksum is invalid. + * - @c ILLEGAL_APID if APID does not match. + */ + ReturnValue_t checkPacket(TcPacketStoredBase* currentPacket); - uint16_t getApid() const; + uint16_t getApid() const; }; - #endif /* FSFW_TCDISTRIBUTION_TCPACKETCHECK_H_ */ diff --git a/tmtcpacket/CMakeLists.txt b/tmtcpacket/CMakeLists.txt index fe3d2a4d2..fdc884ec5 100644 --- a/tmtcpacket/CMakeLists.txt +++ b/tmtcpacket/CMakeLists.txt @@ -1,7 +1,6 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - SpacePacket.cpp - SpacePacketBase.cpp +target_sources(${LIB_FSFW_NAME} PRIVATE + SpacePacket.cpp + SpacePacketBase.cpp ) add_subdirectory(packetmatcher) diff --git a/tmtcpacket/pus/CMakeLists.txt b/tmtcpacket/pus/CMakeLists.txt index 2d22cb668..9340e3b1f 100644 --- a/tmtcpacket/pus/CMakeLists.txt +++ b/tmtcpacket/pus/CMakeLists.txt @@ -1,13 +1,14 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - TcPacketBase.cpp - TcPacketPusA.cpp - TcPacketStored.cpp - TmPacketBase.cpp - TmPacketMinimal.cpp - TmPacketStoredPusA.cpp - TmPacketStoredPusC.cpp - TmPacketPusA.cpp - TmPacketPusC.cpp - TmPacketStoredBase.cpp +target_sources(${LIB_FSFW_NAME} PRIVATE + TcPacketBase.cpp + TcPacketPusA.cpp + TcPacketStoredBase.cpp + TcPacketStoredPusA.cpp + + TmPacketBase.cpp + TmPacketMinimal.cpp + TmPacketStoredPusA.cpp + TmPacketStoredPusC.cpp + TmPacketPusA.cpp + TmPacketPusC.cpp + TmPacketStoredBase.cpp ) diff --git a/tmtcpacket/pus/TcPacketBase.cpp b/tmtcpacket/pus/TcPacketBase.cpp index ca3e2a99a..a5b6f9ce0 100644 --- a/tmtcpacket/pus/TcPacketBase.cpp +++ b/tmtcpacket/pus/TcPacketBase.cpp @@ -2,87 +2,19 @@ #include "../../globalfunctions/CRC.h" #include "../../globalfunctions/arrayprinter.h" -#include "../../serviceinterface/ServiceInterfaceStream.h" +#include "../../serviceinterface/ServiceInterface.h" #include -TcPacketBase::TcPacketBase(const uint8_t* setData) : - SpacePacketBase(setData) { - tcData = reinterpret_cast(const_cast(setData)); -} +TcPacketBase::TcPacketBase(const uint8_t* setData): SpacePacketBase(setData) {} -TcPacketBase::~TcPacketBase() { - //Nothing to do. -} - -uint8_t TcPacketBase::getService() { - return tcData->dataField.service_type; -} - -uint8_t TcPacketBase::getSubService() { - return tcData->dataField.service_subtype; -} - -uint8_t TcPacketBase::getAcknowledgeFlags() { - return tcData->dataField.version_type_ack & 0b00001111; -} - -const uint8_t* TcPacketBase::getApplicationData() const { - return &tcData->appData; -} - -uint16_t TcPacketBase::getApplicationDataSize() { - return getPacketDataLength() - sizeof(tcData->dataField) - CRC_SIZE + 1; -} - -uint16_t TcPacketBase::getErrorControl() { - uint16_t size = getApplicationDataSize() + CRC_SIZE; - uint8_t* p_to_buffer = &tcData->appData; - return (p_to_buffer[size - 2] << 8) + p_to_buffer[size - 1]; -} - -void TcPacketBase::setErrorControl() { - uint32_t full_size = getFullSize(); - uint16_t crc = CRC::crc16ccitt(getWholeData(), full_size - CRC_SIZE); - uint32_t size = getApplicationDataSize(); - (&tcData->appData)[size] = (crc & 0XFF00) >> 8; // CRCH - (&tcData->appData)[size + 1] = (crc) & 0X00FF; // CRCL -} - -void TcPacketBase::setData(const uint8_t* pData) { - SpacePacketBase::setData(pData); - tcData = (TcPacketPointer*) pData; -} - -uint8_t TcPacketBase::getSecondaryHeaderFlag() { - return (tcData->dataField.version_type_ack & 0b10000000) >> 7; -} - -uint8_t TcPacketBase::getPusVersionNumber() { - return (tcData->dataField.version_type_ack & 0b01110000) >> 4; -} +TcPacketBase::~TcPacketBase() {} void TcPacketBase::print() { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::debug << "TcPacketBase::print: " << std::endl; + sif::info << "TcPacketBase::print:" << std::endl; +#else + sif::printInfo("TcPacketBase::print:\n"); #endif - arrayprinter::print(getWholeData(), getFullSize()); -} - -void TcPacketBase::initializeTcPacket(uint16_t apid, uint16_t sequenceCount, - uint8_t ack, uint8_t service, uint8_t subservice) { - initSpacePacketHeader(true, true, apid, sequenceCount); - std::memset(&tcData->dataField, 0, sizeof(tcData->dataField)); - setPacketDataLength(sizeof(PUSTcDataFieldHeader) + CRC_SIZE - 1); - //Data Field Header: - //Set CCSDS_secondary_header_flag to 0 and version number to 001 - tcData->dataField.version_type_ack = 0b00010000; - tcData->dataField.version_type_ack |= (ack & 0x0F); - tcData->dataField.service_type = service; - tcData->dataField.service_subtype = subservice; -} - -size_t TcPacketBase::calculateFullPacketLength(size_t appDataLen) { - return sizeof(CCSDSPrimaryHeader) + sizeof(PUSTcDataFieldHeader) + - appDataLen + TcPacketBase::CRC_SIZE; + arrayprinter::print(getWholeData(), getFullSize()); } diff --git a/tmtcpacket/pus/TcPacketBase.h b/tmtcpacket/pus/TcPacketBase.h index 451f9c3aa..80f9e5055 100644 --- a/tmtcpacket/pus/TcPacketBase.h +++ b/tmtcpacket/pus/TcPacketBase.h @@ -16,9 +16,8 @@ * @ingroup tmtcpackets */ class TcPacketBase : public SpacePacketBase { + friend class TcPacketStoredBase; public: - static const uint16_t TC_PACKET_MIN_SIZE = (sizeof(CCSDSPrimaryHeader) + - sizeof(PUSTcDataFieldHeader) + 2); enum AckField { //! No acknowledgements are expected. @@ -54,7 +53,7 @@ public: * highest bit of the first byte of the Data Field Header. * @return the CCSDS Secondary Header Flag */ - uint8_t getSecondaryHeaderFlag(); + virtual uint8_t getSecondaryHeaderFlag() = 0; /** * This command returns the TC Packet PUS Version Number. * The version number of ECSS PUS 2003 is 1. @@ -62,7 +61,7 @@ public: * first byte. * @return */ - uint8_t getPusVersionNumber(); + virtual uint8_t getPusVersionNumber() = 0; /** * This is a getter for the packet's Ack field, which are the lowest four * bits of the first byte of the Data Field Header. @@ -70,19 +69,19 @@ public: * It is packed in a uint8_t variable. * @return The packet's PUS Ack field. */ - uint8_t getAcknowledgeFlags(); + virtual uint8_t getAcknowledgeFlags() = 0; /** * This is a getter for the packet's PUS Service ID, which is the second * byte of the Data Field Header. * @return The packet's PUS Service ID. */ - uint8_t getService(); + virtual uint8_t getService() const = 0; /** * This is a getter for the packet's PUS Service Subtype, which is the * third byte of the Data Field Header. * @return The packet's PUS Service Subtype. */ - uint8_t getSubService(); + virtual uint8_t getSubService() = 0; /** * This is a getter for a pointer to the packet's Application data. * @@ -90,7 +89,7 @@ public: * the packet's application data. * @return A pointer to the PUS Application Data. */ - const uint8_t* getApplicationData() const; + virtual const uint8_t* getApplicationData() const = 0; /** * This method calculates the size of the PUS Application data field. * @@ -99,7 +98,7 @@ public: * @return The size of the PUS Application Data (without Error Control * field) */ - uint16_t getApplicationDataSize(); + virtual uint16_t getApplicationDataSize() = 0; /** * This getter returns the Error Control Field of the packet. * @@ -108,44 +107,26 @@ public: * supposed to be a 16bit-CRC. * @return The PUS Error Control */ - uint16_t getErrorControl(); + virtual uint16_t getErrorControl() = 0; /** * With this method, the Error Control Field is updated to match the * current content of the packet. */ - void setErrorControl(); + virtual void setErrorControl() = 0; - /** - * This is a debugging helper method that prints the whole packet content - * to the screen. - */ - void print(); /** * Calculate full packet length from application data length. * @param appDataLen * @return */ - static size_t calculateFullPacketLength(size_t appDataLen); + virtual size_t calculateFullPacketLength(size_t appDataLen) = 0; + /** + * This is a debugging helper method that prints the whole packet content + * to the screen. + */ + void print(); protected: - /** - * A pointer to a structure which defines the data structure of - * the packet's data. - * - * To be hardware-safe, all elements are of byte size. - */ - TcPacketPointer* tcData; - - /** - * Initializes the Tc Packet header. - * @param apid APID used. - * @param sequenceCount Sequence Count in the primary header. - * @param ack Which acknowledeges are expected from the receiver. - * @param service PUS Service - * @param subservice PUS Subservice - */ - void initializeTcPacket(uint16_t apid, uint16_t sequenceCount, uint8_t ack, - uint8_t service, uint8_t subservice); /** * With this method, the packet data pointer can be redirected to another @@ -155,7 +136,7 @@ protected: * * @param p_data A pointer to another PUS Telecommand Packet. */ - void setData( const uint8_t* pData ); + void setData( const uint8_t* pData ) = 0; }; diff --git a/tmtcpacket/pus/TcPacketPusA.cpp b/tmtcpacket/pus/TcPacketPusA.cpp index c9af38a63..0ce767b47 100644 --- a/tmtcpacket/pus/TcPacketPusA.cpp +++ b/tmtcpacket/pus/TcPacketPusA.cpp @@ -1,3 +1,75 @@ #include "TcPacketPusA.h" +#include "../../globalfunctions/CRC.h" +#include +TcPacketPusA::TcPacketPusA(const uint8_t *setData): TcPacketBase(setData) { + tcData = reinterpret_cast(const_cast(setData)); +} + +uint8_t TcPacketPusA::getService() const { + return tcData->dataField.service_type; +} + +uint8_t TcPacketPusA::getSubService() { + return tcData->dataField.service_subtype; +} + +uint8_t TcPacketPusA::getAcknowledgeFlags() { + return tcData->dataField.version_type_ack & 0b00001111; +} + +const uint8_t* TcPacketPusA::getApplicationData() const { + return &tcData->appData; +} + +uint16_t TcPacketPusA::getApplicationDataSize() { + return getPacketDataLength() - sizeof(tcData->dataField) - CRC_SIZE + 1; +} + +uint16_t TcPacketPusA::getErrorControl() { + uint16_t size = getApplicationDataSize() + CRC_SIZE; + uint8_t* p_to_buffer = &tcData->appData; + return (p_to_buffer[size - 2] << 8) + p_to_buffer[size - 1]; +} + +void TcPacketPusA::setErrorControl() { + uint32_t full_size = getFullSize(); + uint16_t crc = CRC::crc16ccitt(getWholeData(), full_size - CRC_SIZE); + uint32_t size = getApplicationDataSize(); + (&tcData->appData)[size] = (crc & 0XFF00) >> 8; // CRCH + (&tcData->appData)[size + 1] = (crc) & 0X00FF; // CRCL +} + +void TcPacketPusA::setData(const uint8_t* pData) { + SpacePacketBase::setData(pData); + // This function is const-correct, but it was decided to keep the pointer non-const + // for convenience. Therefore, cast aways constness here and then cast to packet type. + tcData = reinterpret_cast(const_cast(pData)); +} + +uint8_t TcPacketPusA::getSecondaryHeaderFlag() { + return (tcData->dataField.version_type_ack & 0b10000000) >> 7; +} + +uint8_t TcPacketPusA::getPusVersionNumber() { + return (tcData->dataField.version_type_ack & 0b01110000) >> 4; +} + +void TcPacketPusA::initializeTcPacket(uint16_t apid, uint16_t sequenceCount, + uint8_t ack, uint8_t service, uint8_t subservice) { + initSpacePacketHeader(true, true, apid, sequenceCount); + std::memset(&tcData->dataField, 0, sizeof(tcData->dataField)); + setPacketDataLength(sizeof(PUSTcDataFieldHeader) + CRC_SIZE - 1); + // Data Field Header: + // Set CCSDS_secondary_header_flag to 0 and version number to 001 + tcData->dataField.version_type_ack = 0b00010000; + tcData->dataField.version_type_ack |= (ack & 0x0F); + tcData->dataField.service_type = service; + tcData->dataField.service_subtype = subservice; +} + +size_t TcPacketPusA::calculateFullPacketLength(size_t appDataLen) { + return sizeof(CCSDSPrimaryHeader) + sizeof(PUSTcDataFieldHeader) + + appDataLen + TcPacketBase::CRC_SIZE; +} diff --git a/tmtcpacket/pus/TcPacketPusA.h b/tmtcpacket/pus/TcPacketPusA.h index 9254ad32f..0e61d829f 100644 --- a/tmtcpacket/pus/TcPacketPusA.h +++ b/tmtcpacket/pus/TcPacketPusA.h @@ -1,7 +1,7 @@ #ifndef FSFW_TMTCPACKET_PUS_TCPACKETPUSA_H_ #define FSFW_TMTCPACKET_PUS_TCPACKETPUSA_H_ -#include "ccsds_header.h" +#include "../ccsds_header.h" #include "TcPacketBase.h" #include @@ -33,7 +33,50 @@ struct TcPacketPointer { class TcPacketPusA: public TcPacketBase { public: -private: + static const uint16_t TC_PACKET_MIN_SIZE = (sizeof(CCSDSPrimaryHeader) + + sizeof(PUSTcDataFieldHeader) + 2); + + /** + * Initialize a PUS A telecommand packet which already exists. You can also + * create an empty (invalid) object by passing nullptr as the data pointer + * @param setData + */ + TcPacketPusA(const uint8_t* setData); + + // Base class overrides + virtual uint8_t getSecondaryHeaderFlag() override; + virtual uint8_t getPusVersionNumber() override; + virtual uint8_t getAcknowledgeFlags() override; + virtual uint8_t getService() const override; + virtual uint8_t getSubService() override; + const uint8_t* getApplicationData() const override; + uint16_t getApplicationDataSize() override; + uint16_t getErrorControl() override; + void setErrorControl() override; + size_t calculateFullPacketLength(size_t appDataLen) override; + +protected: + + void setData(const uint8_t* pData) override; + + /** + * Initializes the Tc Packet header. + * @param apid APID used. + * @param sequenceCount Sequence Count in the primary header. + * @param ack Which acknowledeges are expected from the receiver. + * @param service PUS Service + * @param subservice PUS Subservice + */ + void initializeTcPacket(uint16_t apid, uint16_t sequenceCount, uint8_t ack, + uint8_t service, uint8_t subservice); + + /** + * A pointer to a structure which defines the data structure of + * the packet's data. + * + * To be hardware-safe, all elements are of byte size. + */ + TcPacketPointer* tcData = nullptr; }; diff --git a/tmtcpacket/pus/TcPacketStored.cpp b/tmtcpacket/pus/TcPacketStored.cpp deleted file mode 100644 index 36fa8d11f..000000000 --- a/tmtcpacket/pus/TcPacketStored.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include "TcPacketStored.h" - -#include "../../objectmanager/ObjectManager.h" -#include "../../serviceinterface/ServiceInterface.h" - -#include - -StorageManagerIF* TcPacketStored::store = nullptr; - -TcPacketStored::TcPacketStored(store_address_t setAddress) : - TcPacketBase(nullptr), storeAddress(setAddress) { - setStoreAddress(storeAddress); -} - -TcPacketStored::TcPacketStored(uint16_t apid, uint8_t service, - uint8_t subservice, uint8_t sequenceCount, const uint8_t* data, - size_t size, uint8_t ack) : - TcPacketBase(nullptr) { - this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; - if (not this->checkAndSetStore()) { - return; - } - uint8_t* pData = nullptr; - ReturnValue_t returnValue = this->store->getFreeElement(&this->storeAddress, - (TC_PACKET_MIN_SIZE + size), &pData); - if (returnValue != this->store->RETURN_OK) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "TcPacketStored: Could not get free element from store!" - << std::endl; -#endif - return; - } - this->setData(pData); - initializeTcPacket(apid, sequenceCount, ack, service, subservice); - memcpy(&tcData->appData, data, size); - this->setPacketDataLength( - size + sizeof(PUSTcDataFieldHeader) + CRC_SIZE - 1); - this->setErrorControl(); -} - -ReturnValue_t TcPacketStored::getData(const uint8_t ** dataPtr, - size_t* dataSize) { - auto result = this->store->getData(storeAddress, dataPtr, dataSize); - if(result != HasReturnvaluesIF::RETURN_OK) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "TcPacketStored: Could not get data!" << std::endl; -#endif - } - return result; -} - -TcPacketStored::TcPacketStored(): TcPacketBase(nullptr) { - this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; - this->checkAndSetStore(); - -} - -ReturnValue_t TcPacketStored::deletePacket() { - ReturnValue_t result = this->store->deleteData(this->storeAddress); - this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; - this->setData(nullptr); - return result; -} - -bool TcPacketStored::checkAndSetStore() { - if (this->store == nullptr) { - this->store = ObjectManager::instance()->get(objects::TC_STORE); - if (this->store == nullptr) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TcPacketStored::TcPacketStored: TC Store not found!" - << std::endl; -#endif - return false; - } - } - return true; -} - -void TcPacketStored::setStoreAddress(store_address_t setAddress) { - this->storeAddress = setAddress; - const uint8_t* tempData = nullptr; - size_t temp_size; - ReturnValue_t status = StorageManagerIF::RETURN_FAILED; - if (this->checkAndSetStore()) { - status = this->store->getData(this->storeAddress, &tempData, - &temp_size); - } - if (status == StorageManagerIF::RETURN_OK) { - this->setData(tempData); - } else { - this->setData(nullptr); - this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; - } -} - -store_address_t TcPacketStored::getStoreAddress() { - return this->storeAddress; -} - -bool TcPacketStored::isSizeCorrect() { - const uint8_t* temp_data = nullptr; - size_t temp_size; - ReturnValue_t status = this->store->getData(this->storeAddress, &temp_data, - &temp_size); - if (status == StorageManagerIF::RETURN_OK) { - if (this->getFullSize() == temp_size) { - return true; - } - } - return false; -} - -TcPacketStored::TcPacketStored(const uint8_t* data, uint32_t size) : - TcPacketBase(data) { - if (getFullSize() != size) { - return; - } - if (this->checkAndSetStore()) { - ReturnValue_t status = store->addData(&storeAddress, data, size); - if (status != HasReturnvaluesIF::RETURN_OK) { - this->setData(nullptr); - } - } -} diff --git a/tmtcpacket/pus/TcPacketStored.h b/tmtcpacket/pus/TcPacketStored.h index 1666107b7..0b6ff0f4c 100644 --- a/tmtcpacket/pus/TcPacketStored.h +++ b/tmtcpacket/pus/TcPacketStored.h @@ -1,117 +1,13 @@ -#ifndef TMTCPACKET_PUS_TCPACKETSTORED_H_ -#define TMTCPACKET_PUS_TCPACKETSTORED_H_ +#ifndef FSFW_TMTCPACKET_PUS_TCPACKETSTORED_H_ +#define FSFW_TMTCPACKET_PUS_TCPACKETSTORED_H_ -#include "TcPacketBase.h" -#include "../../storagemanager/StorageManagerIF.h" +#include -/** - * This class generates a ECSS PUS Telecommand packet within a given - * intermediate storage. - * As most packets are passed between tasks with the help of a storage - * anyway, it seems logical to create a Packet-In-Storage access class - * which saves the user almost all storage handling operation. - * Packets can both be newly created with the class and be "linked" to - * packets in a store with the help of a storeAddress. - * @ingroup tmtcpackets - */ -class TcPacketStored : public TcPacketBase { -public: - /** - * This is a default constructor which does not set the data pointer. - * However, it does try to set the packet store. - */ - TcPacketStored(); - /** - * With this constructor, the class instance is linked to an existing - * packet in the packet store. - * The packet content is neither checked nor changed with this call. If - * the packet could not be found, the data pointer is set to NULL. - */ - TcPacketStored( store_address_t setAddress ); - /** - * With this constructor, new space is allocated in the packet store and - * a new PUS Telecommand Packet is created there. - * Packet Application Data passed in data is copied into the packet. - * @param apid Sets the packet's APID field. - * @param service Sets the packet's Service ID field. - * This specifies the destination service. - * @param subservice Sets the packet's Service Subtype field. - * This specifies the destination sub-service. - * @param sequence_count Sets the packet's Source Sequence Count field. - * @param data The data to be copied to the Application Data Field. - * @param size The amount of data to be copied. - * @param ack Set's the packet's Ack field, which specifies - * number of verification packets returned - * for this command. - */ - TcPacketStored(uint16_t apid, uint8_t service, uint8_t subservice, - uint8_t sequence_count = 0, const uint8_t* data = nullptr, - size_t size = 0, uint8_t ack = TcPacketBase::ACK_ALL); - /** - * Another constructor to create a TcPacket from a raw packet stream. - * Takes the data and adds it unchecked to the TcStore. - * @param data Pointer to the complete TC Space Packet. - * @param Size size of the packet. - */ - TcPacketStored( const uint8_t* data, uint32_t size); - - /** - * Getter function for the raw data. - * @param dataPtr [out] Pointer to the data pointer to set - * @param dataSize [out] Address of size to set. - * @return -@c RETURN_OK if data was retrieved successfully. - */ - ReturnValue_t getData(const uint8_t ** dataPtr, - size_t* dataSize); - /** - * This is a getter for the current store address of the packet. - * @return The current store address. The (raw) value is - * @c StorageManagerIF::INVALID_ADDRESS if the packet is not linked. - */ - store_address_t getStoreAddress(); - /** - * With this call, the packet is deleted. - * It removes itself from the store and sets its data pointer to NULL. - * @return returncode from deleting the data. - */ - ReturnValue_t deletePacket(); - /** - * With this call, a packet can be linked to another store. This is useful - * if the packet is a class member and used for more than one packet. - * @param setAddress The new packet id to link to. - */ - void setStoreAddress( store_address_t setAddress ); - /** - * This method performs a size check. - * It reads the stored size and compares it with the size entered in the - * packet header. This class is the optimal place for such a check as it - * has access to both the header data and the store. - * @return true if size is correct, false if packet is not registered in - * store or size is incorrect. - */ - bool isSizeCorrect(); - -private: - /** - * This is a pointer to the store all instances of the class use. - * If the store is not yet set (i.e. @c store is NULL), every constructor - * call tries to set it and throws an error message in case of failures. - * The default store is objects::TC_STORE. - */ - static StorageManagerIF* store; - /** - * The address where the packet data of the object instance is stored. - */ - store_address_t storeAddress; - /** - * A helper method to check if a store is assigned to the class. - * If not, the method tries to retrieve the store from the global - * ObjectManager. - * @return @li @c true if the store is linked or could be created. - * @li @c false otherwise. - */ - bool checkAndSetStore(); -}; +#if FSFW_USE_PUS_C_TELECOMMANDS == 1 +#include "TcPacketStoredPusC.h" +#else +#include "TcPacketStoredPusA.h" +#endif -#endif /* TMTCPACKET_PUS_TCPACKETSTORED_H_ */ +#endif /* FSFW_TMTCPACKET_PUS_TCPACKETSTORED_H_ */ diff --git a/tmtcpacket/pus/TcPacketStoredBase.cpp b/tmtcpacket/pus/TcPacketStoredBase.cpp new file mode 100644 index 000000000..629562c01 --- /dev/null +++ b/tmtcpacket/pus/TcPacketStoredBase.cpp @@ -0,0 +1,72 @@ +#include "TcPacketStoredBase.h" + +#include "../../objectmanager/ObjectManager.h" +#include "../../serviceinterface/ServiceInterface.h" +#include "../../objectmanager/frameworkObjects.h" + +#include + +StorageManagerIF* TcPacketStoredBase::store = nullptr; + +TcPacketStoredBase::TcPacketStoredBase() { + this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; + this->checkAndSetStore(); + +} + +TcPacketStoredBase::~TcPacketStoredBase() { +} + +ReturnValue_t TcPacketStoredBase::getData(const uint8_t ** dataPtr, + size_t* dataSize) { + auto result = this->store->getData(storeAddress, dataPtr, dataSize); + if(result != HasReturnvaluesIF::RETURN_OK) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "TcPacketStoredBase: Could not get data!" << std::endl; +#else + sif::printWarning("TcPacketStoredBase: Could not get data!\n"); +#endif + } + return result; +} + + + +bool TcPacketStoredBase::checkAndSetStore() { + if (this->store == nullptr) { + this->store = ObjectManager::instance()->get(objects::TC_STORE); + if (this->store == nullptr) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "TcPacketStoredBase::TcPacketStoredBase: TC Store not found!" + << std::endl; +#endif + return false; + } + } + return true; +} + +void TcPacketStoredBase::setStoreAddress(store_address_t setAddress) { + this->storeAddress = setAddress; + const uint8_t* tempData = nullptr; + size_t tempSize; + ReturnValue_t status = StorageManagerIF::RETURN_FAILED; + if (this->checkAndSetStore()) { + status = this->store->getData(this->storeAddress, &tempData, &tempSize); + } + TcPacketBase* tcPacketBase = this->getPacketBase(); + if(tcPacketBase == nullptr) { + return; + } + if (status == StorageManagerIF::RETURN_OK) { + tcPacketBase->setData(tempData); + } + else { + tcPacketBase->setData(nullptr); + this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; + } +} + +store_address_t TcPacketStoredBase::getStoreAddress() { + return this->storeAddress; +} diff --git a/tmtcpacket/pus/TcPacketStoredBase.h b/tmtcpacket/pus/TcPacketStoredBase.h new file mode 100644 index 000000000..811123db4 --- /dev/null +++ b/tmtcpacket/pus/TcPacketStoredBase.h @@ -0,0 +1,90 @@ +#ifndef TMTCPACKET_PUS_TCPACKETSTORED_H_ +#define TMTCPACKET_PUS_TCPACKETSTORED_H_ + +#include +#include "../../storagemanager/StorageManagerIF.h" + +/** + * This class generates a ECSS PUS Telecommand packet within a given + * intermediate storage. + * As most packets are passed between tasks with the help of a storage + * anyway, it seems logical to create a Packet-In-Storage access class + * which saves the user almost all storage handling operation. + * Packets can both be newly created with the class and be "linked" to + * packets in a store with the help of a storeAddress. + * @ingroup tmtcpackets + */ +class TcPacketStoredBase: public TcPacketStoredIF { +public: + /** + * This is a default constructor which does not set the data pointer to initialize + * with an empty cached store address + */ + TcPacketStoredBase(); + /** + * Constructor to set to an existing store address. + * @param setAddress + */ + TcPacketStoredBase(store_address_t setAddress); + /** + * Another constructor to create a TcPacket from a raw packet stream. + * Takes the data and adds it unchecked to the TcStore. + * @param data Pointer to the complete TC Space Packet. + * @param Size size of the packet. + */ + TcPacketStoredBase(const uint8_t* data, uint32_t size); + + virtual~ TcPacketStoredBase(); + + /** + * Getter function for the raw data. + * @param dataPtr [out] Pointer to the data pointer to set + * @param dataSize [out] Address of size to set. + * @return -@c RETURN_OK if data was retrieved successfully. + */ + ReturnValue_t getData(const uint8_t ** dataPtr, size_t* dataSize) override; + + void setStoreAddress(store_address_t setAddress) override; + store_address_t getStoreAddress() override; + + /** + * With this call, the packet is deleted. + * It removes itself from the store and sets its data pointer to NULL. + * @return returncode from deleting the data. + */ + virtual ReturnValue_t deletePacket() = 0; + + /** + * This method performs a size check. + * It reads the stored size and compares it with the size entered in the + * packet header. This class is the optimal place for such a check as it + * has access to both the header data and the store. + * @return true if size is correct, false if packet is not registered in + * store or size is incorrect. + */ + virtual bool isSizeCorrect() = 0; + +protected: + /** + * This is a pointer to the store all instances of the class use. + * If the store is not yet set (i.e. @c store is NULL), every constructor + * call tries to set it and throws an error message in case of failures. + * The default store is objects::TC_STORE. + */ + static StorageManagerIF* store; + /** + * The address where the packet data of the object instance is stored. + */ + store_address_t storeAddress; + /** + * A helper method to check if a store is assigned to the class. + * If not, the method tries to retrieve the store from the global + * ObjectManager. + * @return @li @c true if the store is linked or could be created. + * @li @c false otherwise. + */ + bool checkAndSetStore(); +}; + + +#endif /* TMTCPACKET_PUS_TcPacketStoredBase_H_ */ diff --git a/tmtcpacket/pus/TcPacketStoredIF.h b/tmtcpacket/pus/TcPacketStoredIF.h new file mode 100644 index 000000000..8eb23004f --- /dev/null +++ b/tmtcpacket/pus/TcPacketStoredIF.h @@ -0,0 +1,38 @@ +#ifndef FSFW_TMTCPACKET_PUS_TCPACKETSTOREDIF_H_ +#define FSFW_TMTCPACKET_PUS_TCPACKETSTOREDIF_H_ + +#include "../../tmtcpacket/pus/TcPacketBase.h" +#include "../../storagemanager/storeAddress.h" +#include "../../returnvalues/HasReturnvaluesIF.h" + +class TcPacketStoredIF { +public: + virtual~TcPacketStoredIF() {}; + + /** + * With this call, the stored packet can be set to another packet in a store. This is useful + * if the packet is a class member and used for more than one packet. + * @param setAddress The new packet id to link to. + */ + virtual void setStoreAddress(store_address_t setAddress) = 0; + + virtual store_address_t getStoreAddress() = 0; + + /** + * Getter function for the raw data. + * @param dataPtr [out] Pointer to the data pointer to set + * @param dataSize [out] Address of size to set. + * @return -@c RETURN_OK if data was retrieved successfully. + */ + virtual ReturnValue_t getData(const uint8_t ** dataPtr, size_t* dataSize) = 0; + + /** + * Get packet base pointer which can be used to get access to PUS packet fields + * @return + */ + virtual TcPacketBase* getPacketBase() = 0; +}; + + + +#endif /* FSFW_TMTCPACKET_PUS_TCPACKETSTOREDIF_H_ */ diff --git a/tmtcpacket/pus/TcPacketStoredPusA.cpp b/tmtcpacket/pus/TcPacketStoredPusA.cpp new file mode 100644 index 000000000..7c706a1a4 --- /dev/null +++ b/tmtcpacket/pus/TcPacketStoredPusA.cpp @@ -0,0 +1,77 @@ +#include "TcPacketStoredPusA.h" + +#include + +TcPacketStoredPusA::TcPacketStoredPusA(uint16_t apid, uint8_t service, + uint8_t subservice, uint8_t sequenceCount, const uint8_t* data, + size_t size, uint8_t ack) : + TcPacketPusA(nullptr) { + this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; + if (not this->checkAndSetStore()) { + return; + } + uint8_t* pData = nullptr; + ReturnValue_t returnValue = this->store->getFreeElement(&this->storeAddress, + (TC_PACKET_MIN_SIZE + size), &pData); + if (returnValue != this->store->RETURN_OK) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "TcPacketStoredBase: Could not get free element from store!" + << std::endl; +#endif + return; + } + this->setData(pData); + initializeTcPacket(apid, sequenceCount, ack, service, subservice); + std::memcpy(&tcData->appData, data, size); + this->setPacketDataLength( + size + sizeof(PUSTcDataFieldHeader) + CRC_SIZE - 1); + this->setErrorControl(); +} + +TcPacketStoredPusA::TcPacketStoredPusA(): TcPacketStoredBase(), TcPacketPusA(nullptr) { +} + +TcPacketStoredPusA::TcPacketStoredPusA(store_address_t setAddress): TcPacketPusA(nullptr) { + TcPacketStoredBase::setStoreAddress(setAddress); +} + +TcPacketStoredPusA::TcPacketStoredPusA(const uint8_t* data, size_t size): TcPacketPusA(data) { + if (this->getFullSize() != size) { + return; + } + if (this->checkAndSetStore()) { + ReturnValue_t status = store->addData(&storeAddress, data, size); + if (status != HasReturnvaluesIF::RETURN_OK) { + this->setData(nullptr); + } + const uint8_t* storePtr = nullptr; + // Repoint base data pointer to the data in the store. + store->getData(storeAddress, &storePtr, &size); + this->setData(storePtr); + } +} + +ReturnValue_t TcPacketStoredPusA::deletePacket() { + ReturnValue_t result = this->store->deleteData(this->storeAddress); + this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; + this->setData(nullptr); + return result; +} + +TcPacketBase* TcPacketStoredPusA::getPacketBase() { + return this; +} + + +bool TcPacketStoredPusA::isSizeCorrect() { + const uint8_t* temp_data = nullptr; + size_t temp_size; + ReturnValue_t status = this->store->getData(this->storeAddress, &temp_data, + &temp_size); + if (status == StorageManagerIF::RETURN_OK) { + if (this->getFullSize() == temp_size) { + return true; + } + } + return false; +} diff --git a/tmtcpacket/pus/TcPacketStoredPusA.h b/tmtcpacket/pus/TcPacketStoredPusA.h new file mode 100644 index 000000000..fe1f64f7a --- /dev/null +++ b/tmtcpacket/pus/TcPacketStoredPusA.h @@ -0,0 +1,53 @@ +#ifndef FSFW_TMTCPACKET_PUS_TCPACKETSTOREDPUSA_H_ +#define FSFW_TMTCPACKET_PUS_TCPACKETSTOREDPUSA_H_ + +#include "TcPacketStoredBase.h" +#include "TcPacketPusA.h" + +class TcPacketStoredPusA: + public TcPacketStoredBase, + public TcPacketPusA { +public: + /** + * With this constructor, new space is allocated in the packet store and + * a new PUS Telecommand Packet is created there. + * Packet Application Data passed in data is copied into the packet. + * @param apid Sets the packet's APID field. + * @param service Sets the packet's Service ID field. + * This specifies the destination service. + * @param subservice Sets the packet's Service Subtype field. + * This specifies the destination sub-service. + * @param sequence_count Sets the packet's Source Sequence Count field. + * @param data The data to be copied to the Application Data Field. + * @param size The amount of data to be copied. + * @param ack Set's the packet's Ack field, which specifies + * number of verification packets returned + * for this command. + */ + TcPacketStoredPusA(uint16_t apid, uint8_t service, uint8_t subservice, + uint8_t sequence_count = 0, const uint8_t* data = nullptr, + size_t size = 0, uint8_t ack = TcPacketBase::ACK_ALL); + /** + * Create stored packet with existing data. + * @param data + * @param size + */ + TcPacketStoredPusA(const uint8_t* data, size_t size); + /** + * Create stored packet from existing packet in store + * @param setAddress + */ + TcPacketStoredPusA(store_address_t setAddress); + TcPacketStoredPusA(); + + ReturnValue_t deletePacket() override; + TcPacketBase* getPacketBase() override; + +private: + + bool isSizeCorrect() override; +}; + + + +#endif /* FSFW_TMTCPACKET_PUS_TCPACKETSTOREDPUSA_H_ */ diff --git a/tmtcpacket/pus/TcPacketStoredPusC.cpp b/tmtcpacket/pus/TcPacketStoredPusC.cpp new file mode 100644 index 000000000..f568d1390 --- /dev/null +++ b/tmtcpacket/pus/TcPacketStoredPusC.cpp @@ -0,0 +1,10 @@ +/* + * TcPacketStoredPusC.cpp + * + * Created on: Jun 13, 2021 + * Author: rmueller + */ + + + + diff --git a/tmtcpacket/pus/TmPacketBase.cpp b/tmtcpacket/pus/TmPacketBase.cpp index acd69b650..b144db1bd 100644 --- a/tmtcpacket/pus/TmPacketBase.cpp +++ b/tmtcpacket/pus/TmPacketBase.cpp @@ -44,13 +44,6 @@ ReturnValue_t TmPacketBase::getPacketTime(timeval* timestamp) const { &tempSize, getTimestampSize()); } -void TmPacketBase::print() { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::debug << "TmPacketBase::print: " << std::endl; -#endif - arrayprinter::print(getWholeData(), getFullSize()); -} - bool TmPacketBase::checkAndSetStamper() { if (timeStamper == NULL) { timeStamper = ObjectManager::instance()->get(timeStamperId); @@ -66,3 +59,11 @@ bool TmPacketBase::checkAndSetStamper() { return true; } +void TmPacketBase::print() { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "TmPacketBase::print:" << std::endl; +#else + sif::printInfo("TmPacketBase::print:\n"); +#endif + arrayprinter::print(getWholeData(), getFullSize()); +} diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index 863cba4fb..0ede27dc1 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -246,7 +246,11 @@ void CommandingServiceBase::handleRequestQueue() { TmTcMessage message; ReturnValue_t result; store_address_t address; - TcPacketStored packet; +#if FSFW_USE_PUS_C_TELECOMMANDS == 1 + TcPacketStoredPusC packet; +#else + TcPacketStoredPusA packet; +#endif MessageQueueId_t queue; object_id_t objectId; for (result = requestQueue->receiveMessage(&message); result == RETURN_OK; @@ -351,14 +355,18 @@ ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice, } -void CommandingServiceBase::startExecution(TcPacketStored *storedPacket, +void CommandingServiceBase::startExecution(TcPacketStoredBase *storedPacket, CommandMapIter iter) { ReturnValue_t result = RETURN_OK; CommandMessage command; - iter->second.subservice = storedPacket->getSubService(); + TcPacketBase* tcPacketBase = storedPacket->getPacketBase(); + if(tcPacketBase == nullptr) { + return; + } + iter->second.subservice = tcPacketBase->getSubService(); result = prepareCommand(&command, iter->second.subservice, - storedPacket->getApplicationData(), - storedPacket->getApplicationDataSize(), &iter->second.state, + tcPacketBase->getApplicationData(), + tcPacketBase->getApplicationDataSize(), &iter->second.state, iter->second.objectId); ReturnValue_t sendResult = RETURN_OK; @@ -371,12 +379,12 @@ void CommandingServiceBase::startExecution(TcPacketStored *storedPacket, if (sendResult == RETURN_OK) { Clock::getUptime(&iter->second.uptimeOfStart); iter->second.step = 0; - iter->second.subservice = storedPacket->getSubService(); + iter->second.subservice = tcPacketBase->getSubService(); iter->second.command = command.getCommand(); - iter->second.tcInfo.ackFlags = storedPacket->getAcknowledgeFlags(); - iter->second.tcInfo.tcPacketId = storedPacket->getPacketId(); + iter->second.tcInfo.ackFlags = tcPacketBase->getAcknowledgeFlags(); + iter->second.tcInfo.tcPacketId = tcPacketBase->getPacketId(); iter->second.tcInfo.tcSequenceControl = - storedPacket->getPacketSequenceControl(); + tcPacketBase->getPacketSequenceControl(); acceptPacket(tc_verification::START_SUCCESS, storedPacket); } else { command.clearCommandMessage(); @@ -392,7 +400,7 @@ void CommandingServiceBase::startExecution(TcPacketStored *storedPacket, } if (sendResult == RETURN_OK) { verificationReporter.sendSuccessReport(tc_verification::START_SUCCESS, - storedPacket); + storedPacket->getPacketBase()); acceptPacket(tc_verification::COMPLETION_SUCCESS, storedPacket); checkAndExecuteFifo(iter); } else { @@ -409,16 +417,16 @@ void CommandingServiceBase::startExecution(TcPacketStored *storedPacket, } -void CommandingServiceBase::rejectPacket(uint8_t report_id, - TcPacketStored* packet, ReturnValue_t error_code) { - verificationReporter.sendFailureReport(report_id, packet, error_code); +void CommandingServiceBase::rejectPacket(uint8_t reportId, + TcPacketStoredBase* packet, ReturnValue_t errorCode) { + verificationReporter.sendFailureReport(reportId, packet->getPacketBase(), errorCode); packet->deletePacket(); } void CommandingServiceBase::acceptPacket(uint8_t reportId, - TcPacketStored* packet) { - verificationReporter.sendSuccessReport(reportId, packet); + TcPacketStoredBase* packet) { + verificationReporter.sendSuccessReport(reportId, packet->getPacketBase()); packet->deletePacket(); } @@ -428,7 +436,11 @@ void CommandingServiceBase::checkAndExecuteFifo(CommandMapIter& iter) { if (iter->second.fifo.retrieve(&address) != RETURN_OK) { commandMap.erase(&iter); } else { - TcPacketStored newPacket(address); +#if FSFW_USE_PUS_C_TELECOMMANDS == 1 + TcPacketStoredPusC newPacket(address); +#else + TcPacketStoredPusA newPacket(address); +#endif startExecution(&newPacket, iter); } } diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index e10f2ddd2..46191bd5e 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -1,6 +1,7 @@ #ifndef FSFW_TMTCSERVICES_COMMANDINGSERVICEBASE_H_ #define FSFW_TMTCSERVICES_COMMANDINGSERVICEBASE_H_ +#include #include "AcceptsTelecommandsIF.h" #include "VerificationReporter.h" @@ -351,12 +352,12 @@ private: */ void handleRequestQueue(); - void rejectPacket(uint8_t reportId, TcPacketStored* packet, + void rejectPacket(uint8_t reportId, TcPacketStoredBase* packet, ReturnValue_t errorCode); - void acceptPacket(uint8_t reportId, TcPacketStored* packet); + void acceptPacket(uint8_t reportId, TcPacketStoredBase* packet); - void startExecution(TcPacketStored *storedPacket, CommandMapIter iter); + void startExecution(TcPacketStoredBase *storedPacket, CommandMapIter iter); void handleCommandMessage(CommandMessage* reply); void handleReplyHandlerResult(ReturnValue_t result, CommandMapIter iter, diff --git a/tmtcservices/PusServiceBase.h b/tmtcservices/PusServiceBase.h index 4d3d99bc4..f48612b12 100644 --- a/tmtcservices/PusServiceBase.h +++ b/tmtcservices/PusServiceBase.h @@ -141,7 +141,11 @@ protected: * The current Telecommand to be processed. * It is deleted after handleRequest was executed. */ - TcPacketStored currentPacket; +#if FSFW_USE_PUS_C_TELECOMMANDS == 1 + TcPacketStoredPusC currentPacket; +#else + TcPacketStoredPusA currentPacket; +#endif static object_id_t packetSource; diff --git a/tmtcservices/VerificationReporter.cpp b/tmtcservices/VerificationReporter.cpp index 998cbfb6c..74e0719c8 100644 --- a/tmtcservices/VerificationReporter.cpp +++ b/tmtcservices/VerificationReporter.cpp @@ -17,14 +17,17 @@ VerificationReporter::VerificationReporter() : VerificationReporter::~VerificationReporter() {} void VerificationReporter::sendSuccessReport(uint8_t set_report_id, - TcPacketBase* current_packet, uint8_t set_step) { + TcPacketBase* currentPacket, uint8_t set_step) { if (acknowledgeQueue == MessageQueueIF::NO_QUEUE) { this->initialize(); } + if(currentPacket == nullptr) { + return; + } PusVerificationMessage message(set_report_id, - current_packet->getAcknowledgeFlags(), - current_packet->getPacketId(), - current_packet->getPacketSequenceControl(), 0, set_step); + currentPacket->getAcknowledgeFlags(), + currentPacket->getPacketId(), + currentPacket->getPacketSequenceControl(), 0, set_step); ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, &message); if (status != HasReturnvaluesIF::RETURN_OK) { @@ -56,15 +59,18 @@ void VerificationReporter::sendSuccessReport(uint8_t set_report_id, } void VerificationReporter::sendFailureReport(uint8_t report_id, - TcPacketBase* current_packet, ReturnValue_t error_code, uint8_t step, + TcPacketBase* currentPacket, ReturnValue_t error_code, uint8_t step, uint32_t parameter1, uint32_t parameter2) { if (acknowledgeQueue == MessageQueueIF::NO_QUEUE) { this->initialize(); } + if(currentPacket == nullptr) { + return; + } PusVerificationMessage message(report_id, - current_packet->getAcknowledgeFlags(), - current_packet->getPacketId(), - current_packet->getPacketSequenceControl(), error_code, step, + currentPacket->getAcknowledgeFlags(), + currentPacket->getPacketId(), + currentPacket->getPacketSequenceControl(), error_code, step, parameter1, parameter2); ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, &message); From 8dc66784a8aacff57bf6bb45f8061b1730e4a20d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 13 Jun 2021 16:59:28 +0200 Subject: [PATCH 3/4] tiny changes --- tmtcpacket/pus/TcPacketStoredPusC.cpp | 10 +--------- tmtcpacket/pus/TcPacketStoredPusC.h | 8 ++++++++ 2 files changed, 9 insertions(+), 9 deletions(-) create mode 100644 tmtcpacket/pus/TcPacketStoredPusC.h diff --git a/tmtcpacket/pus/TcPacketStoredPusC.cpp b/tmtcpacket/pus/TcPacketStoredPusC.cpp index f568d1390..0ff2376a5 100644 --- a/tmtcpacket/pus/TcPacketStoredPusC.cpp +++ b/tmtcpacket/pus/TcPacketStoredPusC.cpp @@ -1,10 +1,2 @@ -/* - * TcPacketStoredPusC.cpp - * - * Created on: Jun 13, 2021 - * Author: rmueller - */ - - - +#include "TcPacketStoredPusC.h" diff --git a/tmtcpacket/pus/TcPacketStoredPusC.h b/tmtcpacket/pus/TcPacketStoredPusC.h new file mode 100644 index 000000000..e8ced948d --- /dev/null +++ b/tmtcpacket/pus/TcPacketStoredPusC.h @@ -0,0 +1,8 @@ +#ifndef FSFW_TMTCPACKET_PUS_TCPACKETSTOREDPUSC_H_ +#define FSFW_TMTCPACKET_PUS_TCPACKETSTOREDPUSC_H_ + + + + + +#endif /* FSFW_TMTCPACKET_PUS_TCPACKETSTOREDPUSC_H_ */ From 40a8c9a495f8f0a51f029dbd673defb6f6822d4f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 13 Jun 2021 17:58:44 +0200 Subject: [PATCH 4/4] srv 20 fixes --- pus/Service20ParameterManagement.cpp | 3 +++ pus/servicepackets/Service20Packets.h | 7 +++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pus/Service20ParameterManagement.cpp b/pus/Service20ParameterManagement.cpp index 8ebc6db02..c4e4b5eb1 100644 --- a/pus/Service20ParameterManagement.cpp +++ b/pus/Service20ParameterManagement.cpp @@ -133,6 +133,9 @@ ReturnValue_t Service20ParameterManagement::prepareLoadCommand( store_address_t storeAddress; size_t parameterDataLen = tcDataLen - sizeof(object_id_t) - sizeof(ParameterId_t) - sizeof(uint32_t); + if(parameterDataLen == 0) { + return CommandingServiceBase::INVALID_TC; + } ReturnValue_t result = IPCStore->getFreeElement(&storeAddress, parameterDataLen, &storePointer); if(result != HasReturnvaluesIF::RETURN_OK) { diff --git a/pus/servicepackets/Service20Packets.h b/pus/servicepackets/Service20Packets.h index 33bd153dd..6c7eb6f5c 100644 --- a/pus/servicepackets/Service20Packets.h +++ b/pus/servicepackets/Service20Packets.h @@ -27,12 +27,11 @@ public: ParameterCommand(uint8_t* storePointer, size_t parameterDataLen): parameterBuffer(storePointer, parameterDataLen) { #if FSFW_VERBOSE_LEVEL >= 1 - if(parameterDataLen < sizeof(object_id_t) + sizeof(ParameterId_t) + 4) { + if(parameterDataLen == 0) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "ParameterCommand: Parameter data length is less than 12!" - << std::endl; + sif::warning << "ParameterCommand: Parameter data length is 0" << std::endl; #else - sif::printWarning("ParameterCommand: Parameter data length is less than 12!\n"); + sif::printWarning("ParameterCommand: Parameter data length is 0!\n"); #endif } #endif /* FSFW_VERBOSE_LEVEL >= 1 */