diff --git a/CHANGELOG b/CHANGELOG index add8e1a5..09b8db6a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,16 @@ +## Changes from ASTP 1.0.0 to 1.1.0 + +### PUS + +- Added PUS C support + +### Configuration + +- Additional configuration option fsfwconfig::FSFW_MAX_TM_PACKET_SIZE which + need to be specified in FSFWConfig.h + + + ## Changes from ASTP 0.0.1 to 1.0.0 ### Host OSAL diff --git a/FSFW.h b/FSFW.h new file mode 100644 index 00000000..df06ff3d --- /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/defaultcfg/fsfwconfig/FSFWConfig.h b/defaultcfg/fsfwconfig/FSFWConfig.h index 1abdab4c..adf9912f 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 { @@ -67,6 +68,8 @@ static constexpr uint8_t FSFW_CSB_FIFO_DEPTH = 6; static constexpr size_t FSFW_PRINT_BUFFER_SIZE = 124; +static constexpr size_t FSFW_MAX_TM_PACKET_SIZE = 2048; + } #endif /* CONFIG_FSFWCONFIG_H_ */ diff --git a/pus/Service17Test.cpp b/pus/Service17Test.cpp index daed987a..37258cc1 100644 --- a/pus/Service17Test.cpp +++ b/pus/Service17Test.cpp @@ -3,7 +3,7 @@ #include "../serviceinterface/ServiceInterface.h" #include "../objectmanager/SystemObject.h" -#include "../tmtcpacket/pus/TmPacketStored.h" +#include "../tmtcpacket/pus/tm/TmPacketStored.h" Service17Test::Service17Test(object_id_t objectId, diff --git a/pus/Service1TelecommandVerification.cpp b/pus/Service1TelecommandVerification.cpp index bef7b6b1..8aec6902 100644 --- a/pus/Service1TelecommandVerification.cpp +++ b/pus/Service1TelecommandVerification.cpp @@ -4,7 +4,7 @@ #include "../ipc/QueueFactory.h" #include "../objectmanager/ObjectManager.h" #include "../tmtcservices/PusVerificationReport.h" -#include "../tmtcpacket/pus/TmPacketStored.h" +#include "../tmtcpacket/pus/tm/TmPacketStored.h" #include "../serviceinterface/ServiceInterfaceStream.h" #include "../tmtcservices/AcceptsTelemetryIF.h" diff --git a/pus/Service20ParameterManagement.cpp b/pus/Service20ParameterManagement.cpp index 8ebc6db0..c4e4b5eb 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/Service5EventReporting.cpp b/pus/Service5EventReporting.cpp index 272cc203..0c139f3a 100644 --- a/pus/Service5EventReporting.cpp +++ b/pus/Service5EventReporting.cpp @@ -5,7 +5,7 @@ #include "../objectmanager/ObjectManager.h" #include "../events/EventManagerIF.h" #include "../ipc/QueueFactory.h" -#include "../tmtcpacket/pus/TmPacketStored.h" +#include "../tmtcpacket/pus/tm/TmPacketStored.h" Service5EventReporting::Service5EventReporting(object_id_t objectId, diff --git a/pus/servicepackets/Service20Packets.h b/pus/servicepackets/Service20Packets.h index 33bd153d..6c7eb6f5 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 */ diff --git a/tcdistribution/CMakeLists.txt b/tcdistribution/CMakeLists.txt index 17dc186c..6f237076 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 0fac9ba0..955a8093 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,7 @@ uint16_t PUSDistributor::getIdentifier() { } ReturnValue_t PUSDistributor::initialize() { - currentPacket = new TcPacketStored(); + currentPacket = new TcPacketStoredPus(); 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 be3804ef..c6f863f0 100644 --- a/tcdistribution/PUSDistributor.h +++ b/tcdistribution/PUSDistributor.h @@ -5,6 +5,7 @@ #include "TcDistributor.h" #include "TcPacketCheck.h" +#include "../tmtcpacket/pus/tc.h" #include "../returnvalues/HasReturnvaluesIF.h" #include "../tmtcservices/AcceptsTelecommandsIF.h" #include "../tmtcservices/VerificationReporter.h" @@ -51,7 +52,8 @@ protected: /** * The currently handled packet is stored here. */ - TcPacketStored* currentPacket = nullptr; + TcPacketStoredPus* currentPacket = nullptr; + /** * 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 38ed04aa..b3a025a4 100644 --- a/tcdistribution/TcPacketCheck.cpp +++ b/tcdistribution/TcPacketCheck.cpp @@ -1,39 +1,46 @@ #include "TcPacketCheck.h" #include "../globalfunctions/CRC.h" -#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../tmtcpacket/pus/tc/TcPacketBase.h" +#include "../tmtcpacket/pus/tc/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 703bb1bb..7106b7e4 100644 --- a/tcdistribution/TcPacketCheck.h +++ b/tcdistribution/TcPacketCheck.h @@ -1,10 +1,12 @@ #ifndef FSFW_TCDISTRIBUTION_TCPACKETCHECK_H_ #define FSFW_TCDISTRIBUTION_TCPACKETCHECK_H_ +#include "../FSFW.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 +14,53 @@ */ 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; -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 ); + /** + * 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. + */ +#if FSFW_USE_PUS_C_TELECOMMANDS == 1 + static constexpr uint8_t PUS_VERSION_NUMBER = 2; +#else + static constexpr uint8_t PUS_VERSION_NUMBER = 1; +#endif - uint16_t getApid() const; + /** + * 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(TcPacketStoredBase* currentPacket); + + uint16_t getApid() const; }; - #endif /* FSFW_TCDISTRIBUTION_TCPACKETCHECK_H_ */ diff --git a/tmstorage/TmStorePackets.h b/tmstorage/TmStorePackets.h index 3abd0c1c..53a5d8d6 100644 --- a/tmstorage/TmStorePackets.h +++ b/tmstorage/TmStorePackets.h @@ -5,7 +5,7 @@ #include "../serialize/SerializeElement.h" #include "../serialize/SerialLinkedListAdapter.h" #include "../serialize/SerialBufferAdapter.h" -#include "../tmtcpacket/pus/TmPacketMinimal.h" +#include "../tmtcpacket/pus/tm/TmPacketMinimal.h" #include "../timemanager/TimeStamperIF.h" #include "../timemanager/CCSDSTime.h" #include "../globalfunctions/timevalOperations.h" diff --git a/tmtcpacket/CMakeLists.txt b/tmtcpacket/CMakeLists.txt index fe3d2a4d..fdc884ec 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/SpacePacketBase.cpp b/tmtcpacket/SpacePacketBase.cpp index e13af8d0..14198027 100644 --- a/tmtcpacket/SpacePacketBase.cpp +++ b/tmtcpacket/SpacePacketBase.cpp @@ -72,7 +72,7 @@ void SpacePacketBase::setPacketSequenceCount( uint16_t new_count) { this->data->header.sequence_control_l = ( (new_count%LIMIT_SEQUENCE_COUNT) & 0x00FF ); } -uint16_t SpacePacketBase::getPacketDataLength( void ) { +uint16_t SpacePacketBase::getPacketDataLength() const { return ( (this->data->header.packet_length_h) << 8 ) + this->data->header.packet_length_l; } diff --git a/tmtcpacket/SpacePacketBase.h b/tmtcpacket/SpacePacketBase.h index 19cbd074..13cb3130 100644 --- a/tmtcpacket/SpacePacketBase.h +++ b/tmtcpacket/SpacePacketBase.h @@ -138,9 +138,11 @@ public: * Returns the packet data length, which is the fifth and sixth byte of the * CCSDS Primary Header. The packet data length is the size of every kind * of data \b after the CCSDS Primary Header \b -1. - * @return The CCSDS packet data length. + * @return + * The CCSDS packet data length. uint16_t is sufficient, + * because this is limit in CCSDS standard */ - uint16_t getPacketDataLength( void ); //uint16_t is sufficient, because this is limit in CCSDS standard + uint16_t getPacketDataLength(void) const; /** * Sets the packet data length, which is the fifth and sixth byte of the * CCSDS Primary Header. diff --git a/tmtcpacket/packetmatcher/ApidMatcher.h b/tmtcpacket/packetmatcher/ApidMatcher.h index 4f196ac9..33db7151 100644 --- a/tmtcpacket/packetmatcher/ApidMatcher.h +++ b/tmtcpacket/packetmatcher/ApidMatcher.h @@ -1,38 +1,38 @@ -#ifndef FRAMEWORK_TMTCPACKET_PACKETMATCHER_APIDMATCHER_H_ -#define FRAMEWORK_TMTCPACKET_PACKETMATCHER_APIDMATCHER_H_ +#ifndef FSFW_TMTCPACKET_PACKETMATCHER_APIDMATCHER_H_ +#define FSFW_TMTCPACKET_PACKETMATCHER_APIDMATCHER_H_ #include "../../globalfunctions/matching/SerializeableMatcherIF.h" #include "../../serialize/SerializeAdapter.h" -#include "../../tmtcpacket/pus/TmPacketMinimal.h" +#include "../../tmtcpacket/pus/tm/TmPacketMinimal.h" class ApidMatcher: public SerializeableMatcherIF { private: - uint16_t apid; + uint16_t apid; public: - ApidMatcher(uint16_t setApid) : - apid(setApid) { - } - ApidMatcher(TmPacketMinimal* test) : - apid(test->getAPID()) { - } - bool match(TmPacketMinimal* packet) { - if (packet->getAPID() == apid) { - return true; - } else { - return false; - } - } - ReturnValue_t serialize(uint8_t** buffer, size_t* size, - size_t maxSize, Endianness streamEndianness) const { - return SerializeAdapter::serialize(&apid, buffer, size, maxSize, streamEndianness); - } - size_t getSerializedSize() const { - return SerializeAdapter::getSerializedSize(&apid); - } - ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, - Endianness streamEndianness) { - return SerializeAdapter::deSerialize(&apid, buffer, size, streamEndianness); - } + ApidMatcher(uint16_t setApid) : + apid(setApid) { + } + ApidMatcher(TmPacketMinimal* test) : + apid(test->getAPID()) { + } + bool match(TmPacketMinimal* packet) { + if (packet->getAPID() == apid) { + return true; + } else { + return false; + } + } + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + return SerializeAdapter::serialize(&apid, buffer, size, maxSize, streamEndianness); + } + size_t getSerializedSize() const { + return SerializeAdapter::getSerializedSize(&apid); + } + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { + return SerializeAdapter::deSerialize(&apid, buffer, size, streamEndianness); + } }; diff --git a/tmtcpacket/packetmatcher/PacketMatchTree.cpp b/tmtcpacket/packetmatcher/PacketMatchTree.cpp index ac72b3e7..05e176ef 100644 --- a/tmtcpacket/packetmatcher/PacketMatchTree.cpp +++ b/tmtcpacket/packetmatcher/PacketMatchTree.cpp @@ -5,197 +5,194 @@ // This should be configurable.. const LocalPool::LocalPoolConfig PacketMatchTree::poolConfig = { - {10, sizeof(ServiceMatcher)}, - {20, sizeof(SubServiceMatcher)}, - {2, sizeof(ApidMatcher)}, - {40, sizeof(PacketMatchTree::Node)} + {10, sizeof(ServiceMatcher)}, + {20, sizeof(SubServiceMatcher)}, + {2, sizeof(ApidMatcher)}, + {40, sizeof(PacketMatchTree::Node)} }; -PacketMatchTree::PacketMatchTree(Node* root) : - MatchTree(root, 2), - factoryBackend(0, poolConfig, false, true), - factory(&factoryBackend) { +PacketMatchTree::PacketMatchTree(Node* root): MatchTree(root, 2), + factoryBackend(0, poolConfig, false, true), + factory(&factoryBackend) { } -PacketMatchTree::PacketMatchTree(iterator root) : - MatchTree(root.element, 2), - factoryBackend(0, poolConfig, false, true), - factory(&factoryBackend) { +PacketMatchTree::PacketMatchTree(iterator root): MatchTree(root.element, 2), + factoryBackend(0, poolConfig, false, true), + factory(&factoryBackend) { } -PacketMatchTree::PacketMatchTree() : - MatchTree((Node*) NULL, 2), - factoryBackend(0, poolConfig, false, true), - factory(&factoryBackend) { +PacketMatchTree::PacketMatchTree(): MatchTree((Node*) NULL, 2), + factoryBackend(0, poolConfig, false, true), + factory(&factoryBackend) { } PacketMatchTree::~PacketMatchTree() { } ReturnValue_t PacketMatchTree::addMatch(uint16_t apid, uint8_t type, - uint8_t subtype) { - //We assume adding APID is always requested. - TmPacketMinimal::TmPacketMinimalPointer data; - data.data_field.service_type = type; - data.data_field.service_subtype = subtype; - TmPacketMinimal testPacket((uint8_t*) &data); - testPacket.setAPID(apid); - iterator lastTest; - iterator rollback; - ReturnValue_t result = findOrInsertMatch( - this->begin(), &testPacket, &lastTest); - if (result == NEW_NODE_CREATED) { - rollback = lastTest; - } else if (result != RETURN_OK) { - return result; - } - if (type == 0) { - //Check if lastTest has no children, otherwise, delete them, - //as a more general check is requested. - if (lastTest.left() != this->end()) { - removeElementAndAllChildren(lastTest.left()); - } - return RETURN_OK; - } - //Type insertion required. - result = findOrInsertMatch( - lastTest.left(), &testPacket, &lastTest); - if (result == NEW_NODE_CREATED) { - if (rollback == this->end()) { - rollback = lastTest; - } - } else if (result != RETURN_OK) { - if (rollback != this->end()) { - removeElementAndAllChildren(rollback); - } - return result; - } - if (subtype == 0) { - if (lastTest.left() != this->end()) { - //See above - removeElementAndAllChildren(lastTest.left()); - } - return RETURN_OK; - } - //Subtype insertion required. - result = findOrInsertMatch( - lastTest.left(), &testPacket, &lastTest); - if (result == NEW_NODE_CREATED) { - return RETURN_OK; - } else if (result != RETURN_OK) { - if (rollback != this->end()) { - removeElementAndAllChildren(rollback); - } - return result; - } - return RETURN_OK; + uint8_t subtype) { + //We assume adding APID is always requested. + TmPacketMinimal::TmPacketMinimalPointer data; + data.data_field.service_type = type; + data.data_field.service_subtype = subtype; + TmPacketMinimal testPacket((uint8_t*) &data); + testPacket.setAPID(apid); + iterator lastTest; + iterator rollback; + ReturnValue_t result = findOrInsertMatch( + this->begin(), &testPacket, &lastTest); + if (result == NEW_NODE_CREATED) { + rollback = lastTest; + } else if (result != RETURN_OK) { + return result; + } + if (type == 0) { + //Check if lastTest has no children, otherwise, delete them, + //as a more general check is requested. + if (lastTest.left() != this->end()) { + removeElementAndAllChildren(lastTest.left()); + } + return RETURN_OK; + } + //Type insertion required. + result = findOrInsertMatch( + lastTest.left(), &testPacket, &lastTest); + if (result == NEW_NODE_CREATED) { + if (rollback == this->end()) { + rollback = lastTest; + } + } else if (result != RETURN_OK) { + if (rollback != this->end()) { + removeElementAndAllChildren(rollback); + } + return result; + } + if (subtype == 0) { + if (lastTest.left() != this->end()) { + //See above + removeElementAndAllChildren(lastTest.left()); + } + return RETURN_OK; + } + //Subtype insertion required. + result = findOrInsertMatch( + lastTest.left(), &testPacket, &lastTest); + if (result == NEW_NODE_CREATED) { + return RETURN_OK; + } else if (result != RETURN_OK) { + if (rollback != this->end()) { + removeElementAndAllChildren(rollback); + } + return result; + } + return RETURN_OK; } template ReturnValue_t PacketMatchTree::findOrInsertMatch(iterator startAt, VALUE_T test, - iterator* lastTest) { - bool attachToBranch = AND; - iterator iter = startAt; - while (iter != this->end()) { - bool isMatch = iter->match(test); - attachToBranch = OR; - *lastTest = iter; - if (isMatch) { - return RETURN_OK; - } else { - //Go down OR branch. - iter = iter.right(); - } - } - //Only reached if nothing was found. - SerializeableMatcherIF* newContent = factory.generate( - test); - if (newContent == NULL) { - return FULL; - } - Node* newNode = factory.generate(newContent); - if (newNode == NULL) { - //Need to make sure partially generated content is deleted, otherwise, that's a leak. - factory.destroy(static_cast(newContent)); - return FULL; - } - *lastTest = insert(attachToBranch, *lastTest, newNode); - if (*lastTest == end()) { - //This actaully never fails, so creating a dedicated returncode seems an overshoot. - return RETURN_FAILED; - } - return NEW_NODE_CREATED; + iterator* lastTest) { + bool attachToBranch = AND; + iterator iter = startAt; + while (iter != this->end()) { + bool isMatch = iter->match(test); + attachToBranch = OR; + *lastTest = iter; + if (isMatch) { + return RETURN_OK; + } else { + //Go down OR branch. + iter = iter.right(); + } + } + //Only reached if nothing was found. + SerializeableMatcherIF* newContent = factory.generate( + test); + if (newContent == NULL) { + return FULL; + } + Node* newNode = factory.generate(newContent); + if (newNode == NULL) { + //Need to make sure partially generated content is deleted, otherwise, that's a leak. + factory.destroy(static_cast(newContent)); + return FULL; + } + *lastTest = insert(attachToBranch, *lastTest, newNode); + if (*lastTest == end()) { + //This actaully never fails, so creating a dedicated returncode seems an overshoot. + return RETURN_FAILED; + } + return NEW_NODE_CREATED; } ReturnValue_t PacketMatchTree::removeMatch(uint16_t apid, uint8_t type, - uint8_t subtype) { - TmPacketMinimal::TmPacketMinimalPointer data; - data.data_field.service_type = type; - data.data_field.service_subtype = subtype; - TmPacketMinimal testPacket((uint8_t*) &data); - testPacket.setAPID(apid); - iterator foundElement = findMatch(begin(), &testPacket); - if (foundElement == this->end()) { - return NO_MATCH; - } - if (type == 0) { - if (foundElement.left() == end()) { - return removeElementAndReconnectChildren(foundElement); - } else { - return TOO_GENERAL_REQUEST; - } - } - //Go down AND branch. Will abort if empty. - foundElement = findMatch(foundElement.left(), &testPacket); - if (foundElement == this->end()) { - return NO_MATCH; - } - if (subtype == 0) { - if (foundElement.left() == end()) { - return removeElementAndReconnectChildren(foundElement); - } else { - return TOO_GENERAL_REQUEST; - } - } - //Again, go down AND branch. - foundElement = findMatch(foundElement.left(), &testPacket); - if (foundElement == end()) { - return NO_MATCH; - } - return removeElementAndReconnectChildren(foundElement); + uint8_t subtype) { + TmPacketMinimal::TmPacketMinimalPointer data; + data.data_field.service_type = type; + data.data_field.service_subtype = subtype; + TmPacketMinimal testPacket((uint8_t*) &data); + testPacket.setAPID(apid); + iterator foundElement = findMatch(begin(), &testPacket); + if (foundElement == this->end()) { + return NO_MATCH; + } + if (type == 0) { + if (foundElement.left() == end()) { + return removeElementAndReconnectChildren(foundElement); + } else { + return TOO_GENERAL_REQUEST; + } + } + //Go down AND branch. Will abort if empty. + foundElement = findMatch(foundElement.left(), &testPacket); + if (foundElement == this->end()) { + return NO_MATCH; + } + if (subtype == 0) { + if (foundElement.left() == end()) { + return removeElementAndReconnectChildren(foundElement); + } else { + return TOO_GENERAL_REQUEST; + } + } + //Again, go down AND branch. + foundElement = findMatch(foundElement.left(), &testPacket); + if (foundElement == end()) { + return NO_MATCH; + } + return removeElementAndReconnectChildren(foundElement); } PacketMatchTree::iterator PacketMatchTree::findMatch(iterator startAt, - TmPacketMinimal* test) { - iterator iter = startAt; - while (iter != end()) { - bool isMatch = iter->match(test); - if (isMatch) { - break; - } else { - iter = iter.right(); //next OR element - } - } - return iter; + TmPacketMinimal* test) { + iterator iter = startAt; + while (iter != end()) { + bool isMatch = iter->match(test); + if (isMatch) { + break; + } else { + iter = iter.right(); //next OR element + } + } + return iter; } ReturnValue_t PacketMatchTree::initialize() { - return factoryBackend.initialize(); + return factoryBackend.initialize(); } ReturnValue_t PacketMatchTree::changeMatch(bool addToMatch, uint16_t apid, - uint8_t type, uint8_t subtype) { - if (addToMatch) { - return addMatch(apid, type, subtype); - } else { - return removeMatch(apid, type, subtype); - } + uint8_t type, uint8_t subtype) { + if (addToMatch) { + return addMatch(apid, type, subtype); + } else { + return removeMatch(apid, type, subtype); + } } ReturnValue_t PacketMatchTree::cleanUpElement(iterator position) { - factory.destroy(position.element->value); - //Go on anyway, there's nothing we can do. - //SHOULDDO: Throw event, or write debug message? - return factory.destroy(position.element); + factory.destroy(position.element->value); + //Go on anyway, there's nothing we can do. + //SHOULDDO: Throw event, or write debug message? + return factory.destroy(position.element); } diff --git a/tmtcpacket/packetmatcher/PacketMatchTree.h b/tmtcpacket/packetmatcher/PacketMatchTree.h index 54fc856c..a40b5099 100644 --- a/tmtcpacket/packetmatcher/PacketMatchTree.h +++ b/tmtcpacket/packetmatcher/PacketMatchTree.h @@ -1,36 +1,36 @@ -#ifndef FRAMEWORK_TMTCPACKET_PACKETMATCHER_PACKETMATCHTREE_H_ -#define FRAMEWORK_TMTCPACKET_PACKETMATCHER_PACKETMATCHTREE_H_ +#ifndef FSFW_TMTCPACKET_PACKETMATCHER_PACKETMATCHTREE_H_ +#define FSFW_TMTCPACKET_PACKETMATCHER_PACKETMATCHTREE_H_ #include "../../container/PlacementFactory.h" #include "../../globalfunctions/matching/MatchTree.h" #include "../../storagemanager/LocalPool.h" -#include "../../tmtcpacket/pus/TmPacketMinimal.h" +#include "../../tmtcpacket/pus/tm/TmPacketMinimal.h" class PacketMatchTree: public MatchTree, public HasReturnvaluesIF { public: - PacketMatchTree(Node* root); - PacketMatchTree(iterator root); - PacketMatchTree(); - virtual ~PacketMatchTree(); - ReturnValue_t changeMatch(bool addToMatch, uint16_t apid, uint8_t type = 0, - uint8_t subtype = 0); - ReturnValue_t addMatch(uint16_t apid, uint8_t type = 0, - uint8_t subtype = 0); - ReturnValue_t removeMatch(uint16_t apid, uint8_t type = 0, - uint8_t subtype = 0); - ReturnValue_t initialize(); + PacketMatchTree(Node* root); + PacketMatchTree(iterator root); + PacketMatchTree(); + virtual ~PacketMatchTree(); + ReturnValue_t changeMatch(bool addToMatch, uint16_t apid, uint8_t type = 0, + uint8_t subtype = 0); + ReturnValue_t addMatch(uint16_t apid, uint8_t type = 0, + uint8_t subtype = 0); + ReturnValue_t removeMatch(uint16_t apid, uint8_t type = 0, + uint8_t subtype = 0); + ReturnValue_t initialize(); protected: - ReturnValue_t cleanUpElement(iterator position); + ReturnValue_t cleanUpElement(iterator position); private: - static const uint8_t N_POOLS = 4; - LocalPool factoryBackend; - PlacementFactory factory; - static const LocalPool::LocalPoolConfig poolConfig; - static const uint16_t POOL_SIZES[N_POOLS]; - static const uint16_t N_ELEMENTS[N_POOLS]; - template - ReturnValue_t findOrInsertMatch(iterator startAt, VALUE_T test, iterator* lastTest); - iterator findMatch(iterator startAt, TmPacketMinimal* test); + static const uint8_t N_POOLS = 4; + LocalPool factoryBackend; + PlacementFactory factory; + static const LocalPool::LocalPoolConfig poolConfig; + static const uint16_t POOL_SIZES[N_POOLS]; + static const uint16_t N_ELEMENTS[N_POOLS]; + template + ReturnValue_t findOrInsertMatch(iterator startAt, VALUE_T test, iterator* lastTest); + iterator findMatch(iterator startAt, TmPacketMinimal* test); }; #endif /* FRAMEWORK_TMTCPACKET_PACKETMATCHER_PACKETMATCHTREE_H_ */ diff --git a/tmtcpacket/packetmatcher/ServiceMatcher.h b/tmtcpacket/packetmatcher/ServiceMatcher.h index eba23d75..67d09d2b 100644 --- a/tmtcpacket/packetmatcher/ServiceMatcher.h +++ b/tmtcpacket/packetmatcher/ServiceMatcher.h @@ -3,36 +3,36 @@ #include "../../globalfunctions/matching/SerializeableMatcherIF.h" #include "../../serialize/SerializeAdapter.h" -#include "../../tmtcpacket/pus/TmPacketMinimal.h" +#include "../pus/tm/TmPacketMinimal.h" class ServiceMatcher: public SerializeableMatcherIF { private: - uint8_t service; + uint8_t service; public: - ServiceMatcher(uint8_t setService) : - service(setService) { - } - ServiceMatcher(TmPacketMinimal* test) : - service(test->getService()) { - } - bool match(TmPacketMinimal* packet) { - if (packet->getService() == service) { - return true; - } else { - return false; - } - } - ReturnValue_t serialize(uint8_t** buffer, size_t* size, - size_t maxSize, Endianness streamEndianness) const { - return SerializeAdapter::serialize(&service, buffer, size, maxSize, streamEndianness); - } - size_t getSerializedSize() const { - return SerializeAdapter::getSerializedSize(&service); - } - ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, - Endianness streamEndianness) { - return SerializeAdapter::deSerialize(&service, buffer, size, streamEndianness); - } + ServiceMatcher(uint8_t setService) : + service(setService) { + } + ServiceMatcher(TmPacketMinimal* test) : + service(test->getService()) { + } + bool match(TmPacketMinimal* packet) { + if (packet->getService() == service) { + return true; + } else { + return false; + } + } + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + return SerializeAdapter::serialize(&service, buffer, size, maxSize, streamEndianness); + } + size_t getSerializedSize() const { + return SerializeAdapter::getSerializedSize(&service); + } + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { + return SerializeAdapter::deSerialize(&service, buffer, size, streamEndianness); + } }; diff --git a/tmtcpacket/packetmatcher/SubserviceMatcher.h b/tmtcpacket/packetmatcher/SubserviceMatcher.h index a9b6def8..e570b452 100644 --- a/tmtcpacket/packetmatcher/SubserviceMatcher.h +++ b/tmtcpacket/packetmatcher/SubserviceMatcher.h @@ -1,38 +1,38 @@ -#ifndef FRAMEWORK_TMTCPACKET_PACKETMATCHER_SUBSERVICEMATCHER_H_ -#define FRAMEWORK_TMTCPACKET_PACKETMATCHER_SUBSERVICEMATCHER_H_ +#ifndef FSFW_TMTCPACKET_PACKETMATCHER_SUBSERVICEMATCHER_H_ +#define FSFW_TMTCPACKET_PACKETMATCHER_SUBSERVICEMATCHER_H_ #include "../../globalfunctions/matching/SerializeableMatcherIF.h" #include "../../serialize/SerializeAdapter.h" -#include "../../tmtcpacket/pus/TmPacketMinimal.h" +#include "../pus/tm/TmPacketMinimal.h" class SubServiceMatcher: public SerializeableMatcherIF { public: - SubServiceMatcher(uint8_t subService) : - subService(subService) { - } - SubServiceMatcher(TmPacketMinimal* test) : - subService(test->getSubService()) { - } - bool match(TmPacketMinimal* packet) { - if (packet->getSubService() == subService) { - return true; - } else { - return false; - } - } - ReturnValue_t serialize(uint8_t** buffer, size_t* size, - size_t maxSize, Endianness streamEndianness) const { - return SerializeAdapter::serialize(&subService, buffer, size, maxSize, streamEndianness); - } - size_t getSerializedSize() const { - return SerializeAdapter::getSerializedSize(&subService); - } - ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, - Endianness streamEndianness) { - return SerializeAdapter::deSerialize(&subService, buffer, size, streamEndianness); - } + SubServiceMatcher(uint8_t subService) : + subService(subService) { + } + SubServiceMatcher(TmPacketMinimal* test) : + subService(test->getSubService()) { + } + bool match(TmPacketMinimal* packet) { + if (packet->getSubService() == subService) { + return true; + } else { + return false; + } + } + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + return SerializeAdapter::serialize(&subService, buffer, size, maxSize, streamEndianness); + } + size_t getSerializedSize() const { + return SerializeAdapter::getSerializedSize(&subService); + } + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { + return SerializeAdapter::deSerialize(&subService, buffer, size, streamEndianness); + } private: - uint8_t subService; + uint8_t subService; }; diff --git a/tmtcpacket/pus/CMakeLists.txt b/tmtcpacket/pus/CMakeLists.txt index cd4f49f1..32c80dd3 100644 --- a/tmtcpacket/pus/CMakeLists.txt +++ b/tmtcpacket/pus/CMakeLists.txt @@ -1,12 +1,2 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - TcPacketBase.cpp - TcPacketStored.cpp - TmPacketBase.cpp - TmPacketMinimal.cpp - TmPacketStoredPusA.cpp - TmPacketStoredPusC.cpp - TmPacketPusA.cpp - TmPacketPusC.cpp - TmPacketStoredBase.cpp -) +add_subdirectory(tm) +add_subdirectory(tc) diff --git a/tmtcpacket/pus/TcPacketBase.cpp b/tmtcpacket/pus/TcPacketBase.cpp deleted file mode 100644 index ca3e2a99..00000000 --- a/tmtcpacket/pus/TcPacketBase.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include "TcPacketBase.h" - -#include "../../globalfunctions/CRC.h" -#include "../../globalfunctions/arrayprinter.h" -#include "../../serviceinterface/ServiceInterfaceStream.h" - -#include - -TcPacketBase::TcPacketBase(const uint8_t* setData) : - SpacePacketBase(setData) { - tcData = reinterpret_cast(const_cast(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; -} - -void TcPacketBase::print() { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::debug << "TcPacketBase::print: " << std::endl; -#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; -} diff --git a/tmtcpacket/pus/TcPacketBase.h b/tmtcpacket/pus/TcPacketBase.h deleted file mode 100644 index 582a2214..00000000 --- a/tmtcpacket/pus/TcPacketBase.h +++ /dev/null @@ -1,187 +0,0 @@ -#ifndef TMTCPACKET_PUS_TCPACKETBASE_H_ -#define TMTCPACKET_PUS_TCPACKETBASE_H_ - -#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. - * - * In addition to #SpacePacketBase, the class provides methods to handle - * the standardized entries of the PUS TC Packet Data Field Header. - * It does not contain the packet data itself but a pointer to the - * data must be set on instantiation. An invalid pointer may cause - * damage, as no getter method checks data validity. Anyway, a NULL - * check can be performed by making use of the getWholeData method. - * @ingroup tmtcpackets - */ -class TcPacketBase : public SpacePacketBase { -public: - static const uint16_t TC_PACKET_MIN_SIZE = (sizeof(CCSDSPrimaryHeader) + - sizeof(PUSTcDataFieldHeader) + 2); - - enum AckField { - //! No acknowledgements are expected. - ACK_NONE = 0b0000, - //! Acknowledgements on acceptance are expected. - ACK_ACCEPTANCE = 0b0001, - //! Acknowledgements on start are expected. - ACK_START = 0b0010, - //! Acknowledgements on step are expected. - ACK_STEP = 0b0100, - //! Acknowledfgement on completion are expected. - ACK_COMPLETION = 0b1000 - }; - - static constexpr uint8_t ACK_ALL = ACK_ACCEPTANCE | ACK_START | ACK_STEP | - ACK_COMPLETION; - - /** - * This is the default constructor. - * It sets its internal data pointer to the address passed and also - * forwards the data pointer to the parent SpacePacketBase class. - * @param setData The position where the packet data lies. - */ - TcPacketBase( const uint8_t* setData ); - /** - * This is the empty default destructor. - */ - virtual ~TcPacketBase(); - - /** - * This command returns the CCSDS Secondary Header Flag. - * It shall always be zero for PUS Packets. This is the - * highest bit of the first byte of the Data Field Header. - * @return the CCSDS Secondary Header Flag - */ - uint8_t getSecondaryHeaderFlag(); - /** - * This command returns the TC Packet PUS Version Number. - * The version number of ECSS PUS 2003 is 1. - * It consists of the second to fourth highest bits of the - * first byte. - * @return - */ - uint8_t getPusVersionNumber(); - /** - * 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. - * - * It is packed in a uint8_t variable. - * @return The packet's PUS Ack field. - */ - uint8_t getAcknowledgeFlags(); - /** - * This is a getter for the packet's PUS Service ID, which is the second - * byte of the Data Field Header. - * @return The packet's PUS Service ID. - */ - uint8_t getService(); - /** - * This is a getter for the packet's PUS Service Subtype, which is the - * third byte of the Data Field Header. - * @return The packet's PUS Service Subtype. - */ - uint8_t getSubService(); - /** - * This is a getter for a pointer to the packet's Application data. - * - * These are the bytes that follow after the Data Field Header. They form - * the packet's application data. - * @return A pointer to the PUS Application Data. - */ - const uint8_t* getApplicationData() const; - /** - * This method calculates the size of the PUS Application data field. - * - * It takes the information stored in the CCSDS Packet Data Length field - * and subtracts the Data Field Header size and the CRC size. - * @return The size of the PUS Application Data (without Error Control - * field) - */ - uint16_t getApplicationDataSize(); - /** - * This getter returns the Error Control Field of the packet. - * - * The field is placed after any possible Application Data. If no - * Application Data is present there's still an Error Control field. It is - * supposed to be a 16bit-CRC. - * @return The PUS Error Control - */ - uint16_t getErrorControl(); - /** - * With this method, the Error Control Field is updated to match the - * current content of the packet. - */ - void setErrorControl(); - - /** - * 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); - -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 - * location. - * This call overwrites the parent's setData method to set both its - * @c tc_data pointer and the parent's @c data pointer. - * - * @param p_data A pointer to another PUS Telecommand Packet. - */ - void setData( const uint8_t* pData ); -}; - - -#endif /* TMTCPACKET_PUS_TCPACKETBASE_H_ */ diff --git a/tmtcpacket/pus/TcPacketStored.cpp b/tmtcpacket/pus/TcPacketStored.cpp deleted file mode 100644 index 36fa8d11..00000000 --- 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 deleted file mode 100644 index 1666107b..00000000 --- a/tmtcpacket/pus/TcPacketStored.h +++ /dev/null @@ -1,117 +0,0 @@ -#ifndef TMTCPACKET_PUS_TCPACKETSTORED_H_ -#define TMTCPACKET_PUS_TCPACKETSTORED_H_ - -#include "TcPacketBase.h" -#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 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(); -}; - - -#endif /* TMTCPACKET_PUS_TCPACKETSTORED_H_ */ diff --git a/tmtcpacket/pus/tc.h b/tmtcpacket/pus/tc.h new file mode 100644 index 00000000..156e49fe --- /dev/null +++ b/tmtcpacket/pus/tc.h @@ -0,0 +1,7 @@ +#ifndef FSFW_TMTCPACKET_PUS_TC_H_ +#define FSFW_TMTCPACKET_PUS_TC_H_ + +#include "tc/TcPacketStoredPus.h" +#include "tc/TcPacketPus.h" + +#endif /* FSFW_TMTCPACKET_PUS_TC_H_ */ diff --git a/tmtcpacket/pus/tc/CMakeLists.txt b/tmtcpacket/pus/tc/CMakeLists.txt new file mode 100644 index 00000000..723b7943 --- /dev/null +++ b/tmtcpacket/pus/tc/CMakeLists.txt @@ -0,0 +1,6 @@ +target_sources(${LIB_FSFW_NAME} PRIVATE + TcPacketBase.cpp + TcPacketPus.cpp + TcPacketStoredBase.cpp + TcPacketStoredPus.cpp +) diff --git a/tmtcpacket/pus/tc/TcPacketBase.cpp b/tmtcpacket/pus/tc/TcPacketBase.cpp new file mode 100644 index 00000000..dd576fec --- /dev/null +++ b/tmtcpacket/pus/tc/TcPacketBase.cpp @@ -0,0 +1,20 @@ +#include "TcPacketBase.h" + +#include "../../../globalfunctions/CRC.h" +#include "../../../globalfunctions/arrayprinter.h" +#include "../../../serviceinterface/ServiceInterface.h" + +#include + +TcPacketBase::TcPacketBase(const uint8_t* setData): SpacePacketBase(setData) {} + +TcPacketBase::~TcPacketBase() {} + +void TcPacketBase::print() { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "TcPacketBase::print:" << std::endl; +#else + sif::printInfo("TcPacketBase::print:\n"); +#endif + arrayprinter::print(getWholeData(), getFullSize()); +} diff --git a/tmtcpacket/pus/tc/TcPacketBase.h b/tmtcpacket/pus/tc/TcPacketBase.h new file mode 100644 index 00000000..e2872246 --- /dev/null +++ b/tmtcpacket/pus/tc/TcPacketBase.h @@ -0,0 +1,150 @@ +#ifndef TMTCPACKET_PUS_TCPACKETBASE_H_ +#define TMTCPACKET_PUS_TCPACKETBASE_H_ + +#include "../../../tmtcpacket/SpacePacketBase.h" +#include + +/** + * This class is the basic data handler for any ECSS PUS Telecommand packet. + * + * In addition to #SpacePacketBase, the class provides methods to handle + * the standardized entries of the PUS TC Packet Data Field Header. + * It does not contain the packet data itself but a pointer to the + * data must be set on instantiation. An invalid pointer may cause + * damage, as no getter method checks data validity. Anyway, a NULL + * check can be performed by making use of the getWholeData method. + * @ingroup tmtcpackets + */ +class TcPacketBase : public SpacePacketBase { + friend class TcPacketStoredBase; +public: + + enum AckField { + //! No acknowledgements are expected. + ACK_NONE = 0b0000, + //! Acknowledgements on acceptance are expected. + ACK_ACCEPTANCE = 0b0001, + //! Acknowledgements on start are expected. + ACK_START = 0b0010, + //! Acknowledgements on step are expected. + ACK_STEP = 0b0100, + //! Acknowledfgement on completion are expected. + ACK_COMPLETION = 0b1000 + }; + + static constexpr uint8_t ACK_ALL = ACK_ACCEPTANCE | ACK_START | ACK_STEP | + ACK_COMPLETION; + + /** + * This is the default constructor. + * It sets its internal data pointer to the address passed and also + * forwards the data pointer to the parent SpacePacketBase class. + * @param setData The position where the packet data lies. + */ + TcPacketBase( const uint8_t* setData ); + /** + * This is the empty default destructor. + */ + virtual ~TcPacketBase(); + + /** + * This command returns the CCSDS Secondary Header Flag. + * It shall always be zero for PUS Packets. This is the + * highest bit of the first byte of the Data Field Header. + * @return the CCSDS Secondary Header Flag + */ + virtual uint8_t getSecondaryHeaderFlag() const = 0; + /** + * This command returns the TC Packet PUS Version Number. + * The version number of ECSS PUS 2003 is 1. + * It consists of the second to fourth highest bits of the + * first byte. + * @return + */ + virtual uint8_t getPusVersionNumber() const = 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. + * + * It is packed in a uint8_t variable. + * @return The packet's PUS Ack field. + */ + virtual uint8_t getAcknowledgeFlags() const = 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. + */ + 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. + */ + virtual uint8_t getSubService() const = 0; + /** + * The source ID can be used to have an additional identifier, e.g. for different ground + * station. + * @return + */ + virtual uint16_t getSourceId() const = 0; + + /** + * This is a getter for a pointer to the packet's Application data. + * + * These are the bytes that follow after the Data Field Header. They form + * the packet's application data. + * @return A pointer to the PUS Application Data. + */ + virtual const uint8_t* getApplicationData() const = 0; + /** + * This method calculates the size of the PUS Application data field. + * + * It takes the information stored in the CCSDS Packet Data Length field + * and subtracts the Data Field Header size and the CRC size. + * @return The size of the PUS Application Data (without Error Control + * field) + */ + virtual uint16_t getApplicationDataSize() const = 0; + /** + * This getter returns the Error Control Field of the packet. + * + * The field is placed after any possible Application Data. If no + * Application Data is present there's still an Error Control field. It is + * supposed to be a 16bit-CRC. + * @return The PUS Error Control + */ + virtual uint16_t getErrorControl() const = 0; + /** + * With this method, the Error Control Field is updated to match the + * current content of the packet. + */ + virtual void setErrorControl() = 0; + + /** + * Calculate full packet length from application data length. + * @param appDataLen + * @return + */ + virtual size_t calculateFullPacketLength(size_t appDataLen) const = 0; + + /** + * This is a debugging helper method that prints the whole packet content + * to the screen. + */ + void print(); +protected: + + /** + * With this method, the packet data pointer can be redirected to another + * location. + * This call overwrites the parent's setData method to set both its + * @c tc_data pointer and the parent's @c data pointer. + * + * @param p_data A pointer to another PUS Telecommand Packet. + */ + void setData( const uint8_t* pData ) = 0; +}; + + +#endif /* TMTCPACKET_PUS_TCPACKETBASE_H_ */ diff --git a/tmtcpacket/pus/tc/TcPacketPus.cpp b/tmtcpacket/pus/tc/TcPacketPus.cpp new file mode 100644 index 00000000..334da4e7 --- /dev/null +++ b/tmtcpacket/pus/tc/TcPacketPus.cpp @@ -0,0 +1,92 @@ +#include "TcPacketPus.h" +#include "../../../globalfunctions/CRC.h" + +#include + +TcPacketPus::TcPacketPus(const uint8_t *setData): TcPacketBase(setData) { + tcData = reinterpret_cast(const_cast(setData)); +} + +void TcPacketPus::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.versionTypeAck = 0b00010000; + tcData->dataField.versionTypeAck |= (ack & 0x0F); + tcData->dataField.serviceType = service; + tcData->dataField.serviceSubtype = subservice; +} + +uint8_t TcPacketPus::getService() const { + return tcData->dataField.serviceType; +} + +uint8_t TcPacketPus::getSubService() const { + return tcData->dataField.serviceSubtype; +} + +uint8_t TcPacketPus::getAcknowledgeFlags() const { + return tcData->dataField.versionTypeAck & 0b00001111; +} + +const uint8_t* TcPacketPus::getApplicationData() const { + return &tcData->appData; +} + +uint16_t TcPacketPus::getApplicationDataSize() const { + return getPacketDataLength() - sizeof(tcData->dataField) - CRC_SIZE + 1; +} + +uint16_t TcPacketPus::getErrorControl() const { + 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 TcPacketPus::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 TcPacketPus::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 TcPacketPus::getSecondaryHeaderFlag() const { +#if FSFW_USE_PUS_C_TELECOMMANDS == 1 + // Does not exist for PUS C + return 0; +#else + return (tcData->dataField.versionTypeAck & 0b10000000) >> 7; +#endif +} + +uint8_t TcPacketPus::getPusVersionNumber() const { +#if FSFW_USE_PUS_C_TELECOMMANDS == 1 + return (tcData->dataField.versionTypeAck & 0b11110000) >> 4; +#else + return (tcData->dataField.versionTypeAck & 0b01110000) >> 4; +#endif +} + +uint16_t TcPacketPus::getSourceId() const { +#if FSFW_USE_PUS_C_TELECOMMANDS == 1 + return (tcData->dataField.sourceIdH << 8) | tcData->dataField.sourceIdL; +#else + return tcData->dataField.sourceId; +#endif +} + +size_t TcPacketPus::calculateFullPacketLength(size_t appDataLen) const { + return sizeof(CCSDSPrimaryHeader) + sizeof(PUSTcDataFieldHeader) + + appDataLen + TcPacketBase::CRC_SIZE; +} diff --git a/tmtcpacket/pus/tc/TcPacketPus.h b/tmtcpacket/pus/tc/TcPacketPus.h new file mode 100644 index 00000000..b50b868d --- /dev/null +++ b/tmtcpacket/pus/tc/TcPacketPus.h @@ -0,0 +1,90 @@ +#ifndef FSFW_TMTCPACKET_PUS_TCPACKETPUSA_H_ +#define FSFW_TMTCPACKET_PUS_TCPACKETPUSA_H_ + +#include "../../../FSFW.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 versionTypeAck; + uint8_t serviceType; + uint8_t serviceSubtype; +#if FSFW_USE_PUS_C_TELECOMMANDS == 1 + uint8_t sourceIdH; + uint8_t sourceIdL; +#else + uint8_t sourceId; +#endif +}; + +/** + * 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 TcPacketPus: public TcPacketBase { +public: + 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 + */ + TcPacketPus(const uint8_t* setData); + + // Base class overrides + uint8_t getSecondaryHeaderFlag() const override; + uint8_t getPusVersionNumber() const override; + uint8_t getAcknowledgeFlags() const override; + uint8_t getService() const override; + uint8_t getSubService() const override; + uint16_t getSourceId() const override; + const uint8_t* getApplicationData() const override; + uint16_t getApplicationDataSize() const override; + uint16_t getErrorControl() const override; + void setErrorControl() override; + size_t calculateFullPacketLength(size_t appDataLen) const 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; +}; + + +#endif /* FSFW_TMTCPACKET_PUS_TCPACKETPUSA_H_ */ diff --git a/tmtcpacket/pus/tc/TcPacketStoredBase.cpp b/tmtcpacket/pus/tc/TcPacketStoredBase.cpp new file mode 100644 index 00000000..cf980e68 --- /dev/null +++ b/tmtcpacket/pus/tc/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/tc/TcPacketStoredBase.h b/tmtcpacket/pus/tc/TcPacketStoredBase.h new file mode 100644 index 00000000..1e1681f6 --- /dev/null +++ b/tmtcpacket/pus/tc/TcPacketStoredBase.h @@ -0,0 +1,90 @@ +#ifndef TMTCPACKET_PUS_TCPACKETSTORED_H_ +#define TMTCPACKET_PUS_TCPACKETSTORED_H_ + +#include "TcPacketStoredIF.h" +#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/tc/TcPacketStoredIF.h b/tmtcpacket/pus/tc/TcPacketStoredIF.h new file mode 100644 index 00000000..3d356725 --- /dev/null +++ b/tmtcpacket/pus/tc/TcPacketStoredIF.h @@ -0,0 +1,38 @@ +#ifndef FSFW_TMTCPACKET_PUS_TCPACKETSTOREDIF_H_ +#define FSFW_TMTCPACKET_PUS_TCPACKETSTOREDIF_H_ + +#include "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/tc/TcPacketStoredPus.cpp b/tmtcpacket/pus/tc/TcPacketStoredPus.cpp new file mode 100644 index 00000000..f098ce2b --- /dev/null +++ b/tmtcpacket/pus/tc/TcPacketStoredPus.cpp @@ -0,0 +1,77 @@ +#include "TcPacketStoredPus.h" + +#include + +TcPacketStoredPus::TcPacketStoredPus(uint16_t apid, uint8_t service, + uint8_t subservice, uint8_t sequenceCount, const uint8_t* data, + size_t size, uint8_t ack) : + TcPacketPus(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(); +} + +TcPacketStoredPus::TcPacketStoredPus(): TcPacketStoredBase(), TcPacketPus(nullptr) { +} + +TcPacketStoredPus::TcPacketStoredPus(store_address_t setAddress): TcPacketPus(nullptr) { + TcPacketStoredBase::setStoreAddress(setAddress); +} + +TcPacketStoredPus::TcPacketStoredPus(const uint8_t* data, size_t size): TcPacketPus(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 TcPacketStoredPus::deletePacket() { + ReturnValue_t result = this->store->deleteData(this->storeAddress); + this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; + this->setData(nullptr); + return result; +} + +TcPacketBase* TcPacketStoredPus::getPacketBase() { + return this; +} + + +bool TcPacketStoredPus::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/tc/TcPacketStoredPus.h b/tmtcpacket/pus/tc/TcPacketStoredPus.h new file mode 100644 index 00000000..8b318733 --- /dev/null +++ b/tmtcpacket/pus/tc/TcPacketStoredPus.h @@ -0,0 +1,53 @@ +#ifndef FSFW_TMTCPACKET_PUS_TCPACKETSTOREDPUSA_H_ +#define FSFW_TMTCPACKET_PUS_TCPACKETSTOREDPUSA_H_ + +#include "TcPacketStoredBase.h" +#include "TcPacketPus.h" + +class TcPacketStoredPus: + public TcPacketStoredBase, + public TcPacketPus { +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. + */ + TcPacketStoredPus(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 + */ + TcPacketStoredPus(const uint8_t* data, size_t size); + /** + * Create stored packet from existing packet in store + * @param setAddress + */ + TcPacketStoredPus(store_address_t setAddress); + TcPacketStoredPus(); + + ReturnValue_t deletePacket() override; + TcPacketBase* getPacketBase() override; + +private: + + bool isSizeCorrect() override; +}; + + + +#endif /* FSFW_TMTCPACKET_PUS_TCPACKETSTOREDPUSA_H_ */ diff --git a/tmtcpacket/pus/tm.h b/tmtcpacket/pus/tm.h new file mode 100644 index 00000000..591ada7c --- /dev/null +++ b/tmtcpacket/pus/tm.h @@ -0,0 +1,16 @@ +#ifndef FSFW_TMTCPACKET_PUS_TM_H_ +#define FSFW_TMTCPACKET_PUS_TM_H_ + +#include "../../FSFW.h" + +#if FSFW_USE_PUS_C_TELEMETRY == 1 +#include "tm/TmPacketPusC.h" +#include "tm/TmPacketStoredPusC.h" +#else +#include "tm/TmPacketPusA.h" +#include "tm/TmPacketStoredPusA.h" +#endif + +#include "tm/TmPacketMinimal.h" + +#endif /* FSFW_TMTCPACKET_PUS_TM_H_ */ diff --git a/tmtcpacket/pus/tm/CMakeLists.txt b/tmtcpacket/pus/tm/CMakeLists.txt new file mode 100644 index 00000000..ace87820 --- /dev/null +++ b/tmtcpacket/pus/tm/CMakeLists.txt @@ -0,0 +1,9 @@ +target_sources(${LIB_FSFW_NAME} PRIVATE + TmPacketStoredPusA.cpp + TmPacketStoredPusC.cpp + TmPacketPusA.cpp + TmPacketPusC.cpp + TmPacketStoredBase.cpp + TmPacketBase.cpp + TmPacketMinimal.cpp +) diff --git a/tmtcpacket/pus/TmPacketBase.cpp b/tmtcpacket/pus/tm/TmPacketBase.cpp similarity index 79% rename from tmtcpacket/pus/TmPacketBase.cpp rename to tmtcpacket/pus/tm/TmPacketBase.cpp index acd69b65..3dd1749f 100644 --- a/tmtcpacket/pus/TmPacketBase.cpp +++ b/tmtcpacket/pus/tm/TmPacketBase.cpp @@ -1,19 +1,17 @@ #include "TmPacketBase.h" -#include "../../globalfunctions/CRC.h" -#include "../../globalfunctions/arrayprinter.h" -#include "../../objectmanager/ObjectManager.h" -#include "../../serviceinterface/ServiceInterface.h" -#include "../../timemanager/CCSDSTime.h" +#include "../../../globalfunctions/CRC.h" +#include "../../../globalfunctions/arrayprinter.h" +#include "../../../objectmanager/ObjectManager.h" +#include "../../../serviceinterface/ServiceInterface.h" +#include "../../../timemanager/CCSDSTime.h" #include TimeStamperIF* TmPacketBase::timeStamper = nullptr; object_id_t TmPacketBase::timeStamperId = objects::NO_OBJECT; -TmPacketBase::TmPacketBase(uint8_t* setData): - SpacePacketBase(setData) { -} +TmPacketBase::TmPacketBase(uint8_t* setData): SpacePacketBase(setData) {} TmPacketBase::~TmPacketBase() { //Nothing to do. @@ -44,13 +42,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 +57,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/tmtcpacket/pus/TmPacketBase.h b/tmtcpacket/pus/tm/TmPacketBase.h similarity index 96% rename from tmtcpacket/pus/TmPacketBase.h rename to tmtcpacket/pus/tm/TmPacketBase.h index 6925e99b..9f534f29 100644 --- a/tmtcpacket/pus/TmPacketBase.h +++ b/tmtcpacket/pus/tm/TmPacketBase.h @@ -1,10 +1,10 @@ #ifndef TMTCPACKET_PUS_TMPACKETBASE_H_ #define TMTCPACKET_PUS_TMPACKETBASE_H_ -#include "../SpacePacketBase.h" -#include "../../timemanager/TimeStamperIF.h" -#include "../../timemanager/Clock.h" -#include "../../objectmanager/SystemObjectIF.h" +#include "../../SpacePacketBase.h" +#include "../../../timemanager/TimeStamperIF.h" +#include "../../../timemanager/Clock.h" +#include "../../../objectmanager/SystemObjectIF.h" namespace Factory{ void setStaticFrameworkObjectIds(); diff --git a/tmtcpacket/pus/TmPacketMinimal.cpp b/tmtcpacket/pus/tm/TmPacketMinimal.cpp similarity index 93% rename from tmtcpacket/pus/TmPacketMinimal.cpp rename to tmtcpacket/pus/tm/TmPacketMinimal.cpp index 18e9dda1..3f785cde 100644 --- a/tmtcpacket/pus/TmPacketMinimal.cpp +++ b/tmtcpacket/pus/tm/TmPacketMinimal.cpp @@ -1,7 +1,8 @@ #include "TmPacketMinimal.h" -#include -#include -#include "PacketTimestampInterpreterIF.h" +#include "../PacketTimestampInterpreterIF.h" + +#include +#include TmPacketMinimal::TmPacketMinimal(const uint8_t* set_data) : SpacePacketBase( set_data ) { this->tm_data = (TmPacketMinimalPointer*)set_data; diff --git a/tmtcpacket/pus/TmPacketMinimal.h b/tmtcpacket/pus/tm/TmPacketMinimal.h similarity index 96% rename from tmtcpacket/pus/TmPacketMinimal.h rename to tmtcpacket/pus/tm/TmPacketMinimal.h index 728acb15..08daa584 100644 --- a/tmtcpacket/pus/TmPacketMinimal.h +++ b/tmtcpacket/pus/tm/TmPacketMinimal.h @@ -2,8 +2,8 @@ #define FRAMEWORK_TMTCPACKET_PUS_TMPACKETMINIMAL_H_ -#include "../../tmtcpacket/SpacePacketBase.h" -#include "../../returnvalues/HasReturnvaluesIF.h" +#include "../../SpacePacketBase.h" +#include "../../../returnvalues/HasReturnvaluesIF.h" struct timeval; class PacketTimestampInterpreterIF; diff --git a/tmtcpacket/pus/TmPacketPusA.cpp b/tmtcpacket/pus/tm/TmPacketPusA.cpp similarity index 90% rename from tmtcpacket/pus/TmPacketPusA.cpp rename to tmtcpacket/pus/tm/TmPacketPusA.cpp index d96f6aa7..bdc0a815 100644 --- a/tmtcpacket/pus/TmPacketPusA.cpp +++ b/tmtcpacket/pus/tm/TmPacketPusA.cpp @@ -1,11 +1,11 @@ #include "TmPacketPusA.h" #include "TmPacketBase.h" -#include "../../globalfunctions/CRC.h" -#include "../../globalfunctions/arrayprinter.h" -#include "../../objectmanager/ObjectManagerIF.h" -#include "../../serviceinterface/ServiceInterfaceStream.h" -#include "../../timemanager/CCSDSTime.h" +#include "../../../globalfunctions/CRC.h" +#include "../../../globalfunctions/arrayprinter.h" +#include "../../../objectmanager/ObjectManagerIF.h" +#include "../../../serviceinterface/ServiceInterfaceStream.h" +#include "../../../timemanager/CCSDSTime.h" #include diff --git a/tmtcpacket/pus/TmPacketPusA.h b/tmtcpacket/pus/tm/TmPacketPusA.h similarity index 92% rename from tmtcpacket/pus/TmPacketPusA.h rename to tmtcpacket/pus/tm/TmPacketPusA.h index dd9a5d09..49f26b34 100644 --- a/tmtcpacket/pus/TmPacketPusA.h +++ b/tmtcpacket/pus/tm/TmPacketPusA.h @@ -2,10 +2,10 @@ #define FSFW_TMTCPACKET_PUS_TMPACKETPUSA_H_ #include "TmPacketBase.h" -#include "../SpacePacketBase.h" -#include "../../timemanager/TimeStamperIF.h" -#include "../../timemanager/Clock.h" -#include "../../objectmanager/SystemObjectIF.h" +#include "../../SpacePacketBase.h" +#include "../../../timemanager/TimeStamperIF.h" +#include "../../../timemanager/Clock.h" +#include "../../../objectmanager/SystemObjectIF.h" namespace Factory{ void setStaticFrameworkObjectIds(); @@ -23,7 +23,7 @@ struct PUSTmDataFieldHeaderPusA { uint8_t service_type; uint8_t service_subtype; uint8_t subcounter; -// uint8_t destination; + // uint8_t destination; uint8_t time[TimeStamperIF::MISSION_TIMESTAMP_SIZE]; }; @@ -51,8 +51,7 @@ public: static const uint32_t TM_PACKET_MIN_SIZE = (sizeof(CCSDSPrimaryHeader) + sizeof(PUSTmDataFieldHeaderPusA) + 2); //! Maximum size of a TM Packet in this mission. - //! TODO: Make this dependant on a config variable. - static const uint32_t MISSION_TM_PACKET_MAX_SIZE = 2048; + static const uint32_t MISSION_TM_PACKET_MAX_SIZE = fsfwconfig::FSFW_MAX_TM_PACKET_SIZE; /** * This is the default constructor. diff --git a/tmtcpacket/pus/TmPacketPusC.cpp b/tmtcpacket/pus/tm/TmPacketPusC.cpp similarity index 90% rename from tmtcpacket/pus/TmPacketPusC.cpp rename to tmtcpacket/pus/tm/TmPacketPusC.cpp index ca2bccdb..5090aaeb 100644 --- a/tmtcpacket/pus/TmPacketPusC.cpp +++ b/tmtcpacket/pus/tm/TmPacketPusC.cpp @@ -1,11 +1,11 @@ #include "TmPacketPusC.h" #include "TmPacketBase.h" -#include "../../globalfunctions/CRC.h" -#include "../../globalfunctions/arrayprinter.h" -#include "../../objectmanager/ObjectManagerIF.h" -#include "../../serviceinterface/ServiceInterfaceStream.h" -#include "../../timemanager/CCSDSTime.h" +#include "../../../globalfunctions/CRC.h" +#include "../../../globalfunctions/arrayprinter.h" +#include "../../../objectmanager/ObjectManagerIF.h" +#include "../../../serviceinterface/ServiceInterfaceStream.h" +#include "../../../timemanager/CCSDSTime.h" #include diff --git a/tmtcpacket/pus/TmPacketPusC.h b/tmtcpacket/pus/tm/TmPacketPusC.h similarity index 92% rename from tmtcpacket/pus/TmPacketPusC.h rename to tmtcpacket/pus/tm/TmPacketPusC.h index fdc27548..2a6d3bf6 100644 --- a/tmtcpacket/pus/TmPacketPusC.h +++ b/tmtcpacket/pus/tm/TmPacketPusC.h @@ -2,10 +2,10 @@ #define FSFW_TMTCPACKET_PUS_TMPACKETPUSC_H_ #include "TmPacketBase.h" -#include "../SpacePacketBase.h" -#include "../../timemanager/TimeStamperIF.h" -#include "../../timemanager/Clock.h" -#include "../../objectmanager/SystemObjectIF.h" +#include "../../SpacePacketBase.h" +#include "../../../timemanager/TimeStamperIF.h" +#include "../../../timemanager/Clock.h" +#include "../../../objectmanager/SystemObjectIF.h" namespace Factory{ void setStaticFrameworkObjectIds(); @@ -53,8 +53,7 @@ public: static const uint32_t TM_PACKET_MIN_SIZE = (sizeof(CCSDSPrimaryHeader) + sizeof(PUSTmDataFieldHeaderPusC) + 2); //! Maximum size of a TM Packet in this mission. - //! TODO: Make this dependant on a config variable. - static const uint32_t MISSION_TM_PACKET_MAX_SIZE = 2048; + static const uint32_t MISSION_TM_PACKET_MAX_SIZE = fsfwconfig::FSFW_MAX_TM_PACKET_SIZE; /** * This is the default constructor. diff --git a/tmtcpacket/pus/TmPacketStored.h b/tmtcpacket/pus/tm/TmPacketStored.h similarity index 100% rename from tmtcpacket/pus/TmPacketStored.h rename to tmtcpacket/pus/tm/TmPacketStored.h diff --git a/tmtcpacket/pus/TmPacketStoredBase.cpp b/tmtcpacket/pus/tm/TmPacketStoredBase.cpp similarity index 94% rename from tmtcpacket/pus/TmPacketStoredBase.cpp rename to tmtcpacket/pus/tm/TmPacketStoredBase.cpp index eeaa938d..ba8b15d1 100644 --- a/tmtcpacket/pus/TmPacketStoredBase.cpp +++ b/tmtcpacket/pus/tm/TmPacketStoredBase.cpp @@ -1,8 +1,8 @@ #include "TmPacketStoredBase.h" -#include "../../objectmanager/ObjectManager.h" -#include "../../serviceinterface/ServiceInterface.h" -#include "../../tmtcservices/TmTcMessage.h" +#include "../../../objectmanager/ObjectManager.h" +#include "../../../serviceinterface/ServiceInterface.h" +#include "../../../tmtcservices/TmTcMessage.h" #include diff --git a/tmtcpacket/pus/TmPacketStoredBase.h b/tmtcpacket/pus/tm/TmPacketStoredBase.h similarity index 91% rename from tmtcpacket/pus/TmPacketStoredBase.h rename to tmtcpacket/pus/tm/TmPacketStoredBase.h index dd7e31eb..1bc092dd 100644 --- a/tmtcpacket/pus/TmPacketStoredBase.h +++ b/tmtcpacket/pus/tm/TmPacketStoredBase.h @@ -1,15 +1,15 @@ #ifndef FSFW_TMTCPACKET_PUS_TMPACKETSTOREDBASE_H_ #define FSFW_TMTCPACKET_PUS_TMPACKETSTOREDBASE_H_ +#include "../../../FSFW.h" #include "TmPacketBase.h" #include "TmPacketStoredBase.h" -#include +#include "TmPacketPusA.h" -#include "../../tmtcpacket/pus/TmPacketPusA.h" -#include "../../serialize/SerializeIF.h" -#include "../../storagemanager/StorageManagerIF.h" -#include "../../internalError/InternalErrorReporterIF.h" -#include "../../ipc/MessageQueueSenderIF.h" +#include "../../../serialize/SerializeIF.h" +#include "../../../storagemanager/StorageManagerIF.h" +#include "../../../internalError/InternalErrorReporterIF.h" +#include "../../../ipc/MessageQueueSenderIF.h" /** * This class generates a ECSS PUS Telemetry packet within a given diff --git a/tmtcpacket/pus/TmPacketStoredPusA.cpp b/tmtcpacket/pus/tm/TmPacketStoredPusA.cpp similarity index 95% rename from tmtcpacket/pus/TmPacketStoredPusA.cpp rename to tmtcpacket/pus/tm/TmPacketStoredPusA.cpp index 68102b62..02fb77ef 100644 --- a/tmtcpacket/pus/TmPacketStoredPusA.cpp +++ b/tmtcpacket/pus/tm/TmPacketStoredPusA.cpp @@ -1,7 +1,7 @@ #include "TmPacketStoredPusA.h" -#include "../../serviceinterface/ServiceInterface.h" -#include "../../tmtcservices/TmTcMessage.h" +#include "../../../serviceinterface/ServiceInterface.h" +#include "../../../tmtcservices/TmTcMessage.h" #include diff --git a/tmtcpacket/pus/TmPacketStoredPusA.h b/tmtcpacket/pus/tm/TmPacketStoredPusA.h similarity index 100% rename from tmtcpacket/pus/TmPacketStoredPusA.h rename to tmtcpacket/pus/tm/TmPacketStoredPusA.h diff --git a/tmtcpacket/pus/TmPacketStoredPusC.cpp b/tmtcpacket/pus/tm/TmPacketStoredPusC.cpp similarity index 96% rename from tmtcpacket/pus/TmPacketStoredPusC.cpp rename to tmtcpacket/pus/tm/TmPacketStoredPusC.cpp index 7f774411..6f8f7fa2 100644 --- a/tmtcpacket/pus/TmPacketStoredPusC.cpp +++ b/tmtcpacket/pus/tm/TmPacketStoredPusC.cpp @@ -1,7 +1,7 @@ #include "TmPacketStoredPusC.h" -#include "../../serviceinterface/ServiceInterface.h" -#include "../../tmtcservices/TmTcMessage.h" +#include "../../../serviceinterface/ServiceInterface.h" +#include "../../../tmtcservices/TmTcMessage.h" #include diff --git a/tmtcpacket/pus/TmPacketStoredPusC.h b/tmtcpacket/pus/tm/TmPacketStoredPusC.h similarity index 96% rename from tmtcpacket/pus/TmPacketStoredPusC.h rename to tmtcpacket/pus/tm/TmPacketStoredPusC.h index 883dc0ff..35c66083 100644 --- a/tmtcpacket/pus/TmPacketStoredPusC.h +++ b/tmtcpacket/pus/tm/TmPacketStoredPusC.h @@ -1,8 +1,8 @@ #ifndef FSFW_TMTCPACKET_PUS_TMPACKETSTOREDPUSC_H_ #define FSFW_TMTCPACKET_PUS_TMPACKETSTOREDPUSC_H_ -#include -#include +#include "TmPacketPusC.h" +#include "TmPacketStoredBase.h" /** * This class generates a ECSS PUS C Telemetry packet within a given diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index 863cba4f..307a2a98 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -6,8 +6,8 @@ #include "../tcdistribution/PUSDistributorIF.h" #include "../objectmanager/ObjectManager.h" #include "../ipc/QueueFactory.h" -#include "../tmtcpacket/pus/TcPacketStored.h" -#include "../tmtcpacket/pus/TmPacketStored.h" +#include "../tmtcpacket/pus/tc.h" +#include "../tmtcpacket/pus/tm.h" #include "../serviceinterface/ServiceInterface.h" object_id_t CommandingServiceBase::defaultPacketSource = objects::NO_OBJECT; @@ -246,7 +246,7 @@ void CommandingServiceBase::handleRequestQueue() { TmTcMessage message; ReturnValue_t result; store_address_t address; - TcPacketStored packet; + TcPacketStoredPus packet; MessageQueueId_t queue; object_id_t objectId; for (result = requestQueue->receiveMessage(&message); result == RETURN_OK; @@ -259,6 +259,7 @@ void CommandingServiceBase::handleRequestQueue() { rejectPacket(tc_verification::START_FAILURE, &packet, INVALID_SUBSERVICE); continue; } + result = getMessageQueueAndObject(packet.getSubService(), packet.getApplicationData(), packet.getApplicationDataSize(), &queue, &objectId); @@ -351,14 +352,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 +376,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 +397,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 +414,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 +433,7 @@ void CommandingServiceBase::checkAndExecuteFifo(CommandMapIter& iter) { if (iter->second.fifo.retrieve(&address) != RETURN_OK) { commandMap.erase(&iter); } else { - TcPacketStored newPacket(address); + TcPacketStoredPus newPacket(address); startExecution(&newPacket, iter); } } diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index e10f2ddd..4ee4a21a 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -16,6 +16,7 @@ #include class TcPacketStored; +class TcPacketStoredBase; namespace Factory{ void setStaticFrameworkObjectIds(); @@ -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 4d3d99bc..6cde6fb4 100644 --- a/tmtcservices/PusServiceBase.h +++ b/tmtcservices/PusServiceBase.h @@ -9,7 +9,7 @@ #include "../objectmanager/SystemObject.h" #include "../returnvalues/HasReturnvaluesIF.h" #include "../tasks/ExecutableObjectIF.h" -#include "../tmtcpacket/pus/TcPacketStored.h" +#include "../tmtcpacket/pus/tc.h" #include "../ipc/MessageQueueIF.h" namespace Factory{ @@ -141,7 +141,7 @@ protected: * The current Telecommand to be processed. * It is deleted after handleRequest was executed. */ - TcPacketStored currentPacket; + TcPacketStoredPus currentPacket; static object_id_t packetSource; diff --git a/tmtcservices/PusVerificationReport.h b/tmtcservices/PusVerificationReport.h index 9dce95ac..0e1732ef 100644 --- a/tmtcservices/PusVerificationReport.h +++ b/tmtcservices/PusVerificationReport.h @@ -4,7 +4,7 @@ #include "VerificationCodes.h" #include "../ipc/MessageQueueMessage.h" -#include "../tmtcpacket/pus/TcPacketBase.h" +#include "../tmtcpacket/pus/tc/TcPacketBase.h" #include "../returnvalues/HasReturnvaluesIF.h" class PusVerificationMessage: public MessageQueueMessage { diff --git a/tmtcservices/VerificationReporter.cpp b/tmtcservices/VerificationReporter.cpp index 998cbfb6..74e0719c 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);