diff --git a/timemanager/TimeStamperIF.h b/timemanager/TimeStamperIF.h index bdc5e7e3..96011088 100644 --- a/timemanager/TimeStamperIF.h +++ b/timemanager/TimeStamperIF.h @@ -14,8 +14,12 @@ public: static const uint8_t INTERFACE_ID = CLASS_ID::TIME_STAMPER_IF; static const ReturnValue_t BAD_TIMESTAMP = MAKE_RETURN_CODE(1); - static const uint8_t MISSION_TIMESTAMP_SIZE = 8; //!< This is a mission-specific constant and determines the total size reserved for timestamps. - virtual ReturnValue_t addTimeStamp(uint8_t* buffer, const uint8_t maxSize) = 0; + //! This is a mission-specific constant and determines the total + //! size reserved for timestamps. + //! TODO: Default define in FSFWConfig ? + static const uint8_t MISSION_TIMESTAMP_SIZE = 8; + virtual ReturnValue_t addTimeStamp(uint8_t* buffer, + const uint8_t maxSize) = 0; virtual ~TimeStamperIF() {} }; diff --git a/tmtcpacket/SpacePacketBase.cpp b/tmtcpacket/SpacePacketBase.cpp index a37e024b..e13af8d0 100644 --- a/tmtcpacket/SpacePacketBase.cpp +++ b/tmtcpacket/SpacePacketBase.cpp @@ -1,6 +1,6 @@ -#include "../serviceinterface/ServiceInterfaceStream.h" #include "SpacePacketBase.h" -#include +#include "../serviceinterface/ServiceInterfaceStream.h" +#include SpacePacketBase::SpacePacketBase( const uint8_t* set_address ) { this->data = (SpacePacketPointer*) set_address; @@ -14,7 +14,8 @@ uint8_t SpacePacketBase::getPacketVersionNumber( void ) { return (this->data->header.packet_id_h & 0b11100000) >> 5; } -void SpacePacketBase::initSpacePacketHeader(bool isTelecommand, bool hasSecondaryHeader, uint16_t apid, uint16_t sequenceCount) { +void SpacePacketBase::initSpacePacketHeader(bool isTelecommand, + bool hasSecondaryHeader, uint16_t apid, uint16_t sequenceCount) { //reset header to zero: memset(data,0, sizeof(this->data->header) ); //Set TC/TM bit. @@ -81,7 +82,7 @@ void SpacePacketBase::setPacketDataLength( uint16_t new_length) { this->data->header.packet_length_l = ( new_length & 0x00FF ); } -uint32_t SpacePacketBase::getFullSize() { +size_t SpacePacketBase::getFullSize() { //+1 is done because size in packet data length field is: size of data field -1 return this->getPacketDataLength() + sizeof(this->data->header) + 1; } diff --git a/tmtcpacket/SpacePacketBase.h b/tmtcpacket/SpacePacketBase.h index ef3ad79d..19cbd074 100644 --- a/tmtcpacket/SpacePacketBase.h +++ b/tmtcpacket/SpacePacketBase.h @@ -1,10 +1,11 @@ -#ifndef SPACEPACKETBASE_H_ -#define SPACEPACKETBASE_H_ +#ifndef FSFW_TMTCPACKET_SPACEPACKETBASE_H_ +#define FSFW_TMTCPACKET_SPACEPACKETBASE_H_ #include "ccsds_header.h" +#include /** - * \defgroup tmtcpackets Space Packets + * @defgroup tmtcpackets Space Packets * This is the group, where all classes associated with Telecommand and * Telemetry packets belong to. * The class hierarchy resembles the dependency between the different standards @@ -81,7 +82,8 @@ public: */ bool isTelecommand( void ); - void initSpacePacketHeader(bool isTelecommand, bool hasSecondaryHeader, uint16_t apid, uint16_t sequenceCount = 0); + void initSpacePacketHeader(bool isTelecommand, bool hasSecondaryHeader, + uint16_t apid, uint16_t sequenceCount = 0); /** * The CCSDS header provides a secondary header flag (the fifth-highest bit), * which is checked with this method. @@ -167,10 +169,10 @@ public: * This method returns the full raw packet size. * @return The full size of the packet in bytes. */ - uint32_t getFullSize(); + size_t getFullSize(); uint32_t getApidAndSequenceCount() const; }; -#endif /* SPACEPACKETBASE_H_ */ +#endif /* FSFW_TMTCPACKET_SPACEPACKETBASE_H_ */ diff --git a/tmtcpacket/pus/PacketTimestampInterpreterIF.h b/tmtcpacket/pus/PacketTimestampInterpreterIF.h index dd0c0328..40e7a2ea 100644 --- a/tmtcpacket/pus/PacketTimestampInterpreterIF.h +++ b/tmtcpacket/pus/PacketTimestampInterpreterIF.h @@ -7,7 +7,8 @@ class TmPacketMinimal; class PacketTimestampInterpreterIF { public: virtual ~PacketTimestampInterpreterIF() {} - virtual ReturnValue_t getPacketTime(TmPacketMinimal* packet, timeval* timestamp) const = 0; + virtual ReturnValue_t getPacketTime(TmPacketMinimal* packet, + timeval* timestamp) const = 0; virtual ReturnValue_t getPacketTimeRaw(TmPacketMinimal* packet, const uint8_t** timePtr, uint32_t* size) const = 0; }; diff --git a/tmtcpacket/pus/TcPacketBase.cpp b/tmtcpacket/pus/TcPacketBase.cpp index 3815eb20..eaa8416a 100644 --- a/tmtcpacket/pus/TcPacketBase.cpp +++ b/tmtcpacket/pus/TcPacketBase.cpp @@ -1,11 +1,14 @@ -#include "../../globalfunctions/CRC.h" -#include "../../serviceinterface/ServiceInterfaceStream.h" #include "TcPacketBase.h" -#include -TcPacketBase::TcPacketBase(const uint8_t* set_data) : - SpacePacketBase(set_data) { - tcData = (TcPacketPointer*) set_data; +#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() { @@ -13,28 +16,28 @@ TcPacketBase::~TcPacketBase() { } uint8_t TcPacketBase::getService() { - return tcData->data_field.service_type; + return tcData->dataField.service_type; } uint8_t TcPacketBase::getSubService() { - return tcData->data_field.service_subtype; + return tcData->dataField.service_subtype; } uint8_t TcPacketBase::getAcknowledgeFlags() { - return tcData->data_field.version_type_ack & 0b00001111; + return tcData->dataField.version_type_ack & 0b00001111; } const uint8_t* TcPacketBase::getApplicationData() const { - return &tcData->data; + return &tcData->appData; } uint16_t TcPacketBase::getApplicationDataSize() { - return getPacketDataLength() - sizeof(tcData->data_field) - CRC_SIZE + 1; + return getPacketDataLength() - sizeof(tcData->dataField) - CRC_SIZE + 1; } uint16_t TcPacketBase::getErrorControl() { uint16_t size = getApplicationDataSize() + CRC_SIZE; - uint8_t* p_to_buffer = &tcData->data; + uint8_t* p_to_buffer = &tcData->appData; return (p_to_buffer[size - 2] << 8) + p_to_buffer[size - 1]; } @@ -42,41 +45,42 @@ void TcPacketBase::setErrorControl() { uint32_t full_size = getFullSize(); uint16_t crc = CRC::crc16ccitt(getWholeData(), full_size - CRC_SIZE); uint32_t size = getApplicationDataSize(); - (&tcData->data)[size] = (crc & 0XFF00) >> 8; // CRCH - (&tcData->data)[size + 1] = (crc) & 0X00FF; // CRCL + (&tcData->appData)[size] = (crc & 0XFF00) >> 8; // CRCH + (&tcData->appData)[size + 1] = (crc) & 0X00FF; // CRCL } -void TcPacketBase::setData(const uint8_t* p_Data) { - SpacePacketBase::setData(p_Data); - tcData = (TcPacketPointer*) p_Data; +void TcPacketBase::setData(const uint8_t* pData) { + SpacePacketBase::setData(pData); + tcData = (TcPacketPointer*) pData; } uint8_t TcPacketBase::getSecondaryHeaderFlag() { - return (tcData->data_field.version_type_ack & 0b10000000) >> 7; + return (tcData->dataField.version_type_ack & 0b10000000) >> 7; } uint8_t TcPacketBase::getPusVersionNumber() { - return (tcData->data_field.version_type_ack & 0b01110000) >> 4; + return (tcData->dataField.version_type_ack & 0b01110000) >> 4; } void TcPacketBase::print() { - uint8_t * wholeData = getWholeData(); - sif::debug << "TcPacket contains: " << std::endl; - for (uint8_t count = 0; count < getFullSize(); ++count) { - sif::debug << std::hex << (uint16_t) wholeData[count] << " "; - } - sif::debug << std::dec << std::endl; + sif::debug << "TcPacketBase::print: " << std::endl; + arrayprinter::print(getWholeData(), getFullSize()); } void TcPacketBase::initializeTcPacket(uint16_t apid, uint16_t sequenceCount, - uint8_t ack, uint8_t service, uint8_t subservice) { + uint8_t ack, uint8_t service, uint8_t subservice) { initSpacePacketHeader(true, true, apid, sequenceCount); - memset(&tcData->data_field, 0, sizeof(tcData->data_field)); - setPacketDataLength(sizeof(tcData->data_field) + CRC_SIZE); + std::memset(&tcData->dataField, 0, sizeof(tcData->dataField)); + setPacketDataLength(sizeof(PUSTcDataFieldHeader) + CRC_SIZE - 1); //Data Field Header: - //Set CCSDS_secondary_header_flag to 0, version number to 001 and ack to 0000 - tcData->data_field.version_type_ack = 0b00010000; - tcData->data_field.version_type_ack |= (ack & 0x0F); - tcData->data_field.service_type = service; - tcData->data_field.service_subtype = subservice; + //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 index dd63d2be..582a2214 100644 --- a/tmtcpacket/pus/TcPacketBase.h +++ b/tmtcpacket/pus/TcPacketBase.h @@ -1,7 +1,9 @@ -#ifndef TCPACKETBASE_H_ -#define TCPACKETBASE_H_ +#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. @@ -23,14 +25,14 @@ struct PUSTcDataFieldHeader { */ struct TcPacketPointer { CCSDSPrimaryHeader primary; - PUSTcDataFieldHeader data_field; - uint8_t data; + 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 + * 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 @@ -39,67 +41,38 @@ struct TcPacketPointer { * @ingroup tmtcpackets */ class TcPacketBase : public SpacePacketBase { -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; public: - static const uint16_t TC_PACKET_MIN_SIZE = (sizeof(CCSDSPrimaryHeader) + sizeof(PUSTcDataFieldHeader) + 2); - /** - * With this constant for the acknowledge field responses on all levels are expected. - */ - static const uint8_t ACK_ALL = 0b1111; - /** - * With this constant for the acknowledge field a response on acceptance is expected. - */ - static const uint8_t ACK_ACCEPTANCE = 0b0001; - /** - * With this constant for the acknowledge field a response on start of execution is expected. - */ - static const uint8_t ACK_START = 0b0010; - /** - * With this constant for the acknowledge field responses on execution steps are expected. - */ - static const uint8_t ACK_STEP = 0b0100; - /** - * With this constant for the acknowledge field a response on completion is expected. - */ - static const uint8_t ACK_COMPLETION = 0b1000; - /** - * With this constant for the acknowledge field no responses are expected. - */ - static const uint8_t ACK_NONE = 0b000; + 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 set_address The position where the packet data lies. + * @param setData The position where the packet data lies. */ - TcPacketBase( const uint8_t* set_data ); + TcPacketBase( const uint8_t* setData ); /** * This is the empty default destructor. */ virtual ~TcPacketBase(); - /** - * Initializes the Tc Packet header. - * @param apid APID used. - * @param service PUS Service - * @param subservice PUS Subservice - * @param packetSubcounter Additional subcounter used. - */ - /** - * 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); + /** * This command returns the CCSDS Secondary Header Flag. * It shall always be zero for PUS Packets. This is the @@ -166,22 +139,49 @@ public: * current content of the packet. */ void setErrorControl(); - /** - * 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* p_data ); + /** * 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 /* TCPACKETBASE_H_ */ +#endif /* TMTCPACKET_PUS_TCPACKETBASE_H_ */ diff --git a/tmtcpacket/pus/TcPacketStored.cpp b/tmtcpacket/pus/TcPacketStored.cpp index 216f89c9..fffc86ae 100644 --- a/tmtcpacket/pus/TcPacketStored.cpp +++ b/tmtcpacket/pus/TcPacketStored.cpp @@ -1,37 +1,50 @@ +#include "TcPacketStored.h" #include "../../objectmanager/ObjectManagerIF.h" #include "../../serviceinterface/ServiceInterfaceStream.h" -#include "TcPacketStored.h" -#include + +#include + +StorageManagerIF* TcPacketStored::store = nullptr; TcPacketStored::TcPacketStored(store_address_t setAddress) : - TcPacketBase(NULL), storeAddress(setAddress) { - this->setStoreAddress(this->storeAddress); + TcPacketBase(nullptr), storeAddress(setAddress) { + setStoreAddress(storeAddress); } -TcPacketStored::TcPacketStored(uint16_t apid, uint8_t ack, uint8_t service, - uint8_t subservice, uint8_t sequence_count, const uint8_t* data, - uint32_t size) : - TcPacketBase(NULL) { +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 (!this->checkAndSetStore()) { + if (not this->checkAndSetStore()) { return; } - uint8_t* p_data = NULL; + uint8_t* pData = nullptr; ReturnValue_t returnValue = this->store->getFreeElement(&this->storeAddress, - (TC_PACKET_MIN_SIZE + size), &p_data); + (TC_PACKET_MIN_SIZE + size), &pData); if (returnValue != this->store->RETURN_OK) { + sif::warning << "TcPacketStored: Could not get free element from store!" + << std::endl; return; } - this->setData(p_data); - initializeTcPacket(apid, sequence_count, ack, service, subservice); - memcpy(&tcData->data, data, size); + this->setData(pData); + initializeTcPacket(apid, sequenceCount, ack, service, subservice); + memcpy(&tcData->appData, data, size); this->setPacketDataLength( size + sizeof(PUSTcDataFieldHeader) + CRC_SIZE - 1); this->setErrorControl(); } -TcPacketStored::TcPacketStored() : - TcPacketBase(NULL) { +ReturnValue_t TcPacketStored::getData(const uint8_t ** dataPtr, + size_t* dataSize) { + auto result = this->store->getData(storeAddress, dataPtr, dataSize); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "TcPacketStored: Could not get data!" << std::endl; + } + return result; +} + +TcPacketStored::TcPacketStored(): TcPacketBase(nullptr) { this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; this->checkAndSetStore(); @@ -40,14 +53,14 @@ TcPacketStored::TcPacketStored() : ReturnValue_t TcPacketStored::deletePacket() { ReturnValue_t result = this->store->deleteData(this->storeAddress); this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; - this->setData( NULL); + this->setData(nullptr); return result; } bool TcPacketStored::checkAndSetStore() { - if (this->store == NULL) { + if (this->store == nullptr) { this->store = objectManager->get(objects::TC_STORE); - if (this->store == NULL) { + if (this->store == nullptr) { sif::error << "TcPacketStored::TcPacketStored: TC Store not found!" << std::endl; return false; @@ -58,17 +71,17 @@ bool TcPacketStored::checkAndSetStore() { void TcPacketStored::setStoreAddress(store_address_t setAddress) { this->storeAddress = setAddress; - const uint8_t* temp_data = NULL; + const uint8_t* tempData = nullptr; size_t temp_size; ReturnValue_t status = StorageManagerIF::RETURN_FAILED; if (this->checkAndSetStore()) { - status = this->store->getData(this->storeAddress, &temp_data, + status = this->store->getData(this->storeAddress, &tempData, &temp_size); } if (status == StorageManagerIF::RETURN_OK) { - this->setData(temp_data); + this->setData(tempData); } else { - this->setData(NULL); + this->setData(nullptr); this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; } } @@ -78,7 +91,7 @@ store_address_t TcPacketStored::getStoreAddress() { } bool TcPacketStored::isSizeCorrect() { - const uint8_t* temp_data = NULL; + const uint8_t* temp_data = nullptr; size_t temp_size; ReturnValue_t status = this->store->getData(this->storeAddress, &temp_data, &temp_size); @@ -90,8 +103,6 @@ bool TcPacketStored::isSizeCorrect() { return false; } -StorageManagerIF* TcPacketStored::store = NULL; - TcPacketStored::TcPacketStored(const uint8_t* data, uint32_t size) : TcPacketBase(data) { if (getFullSize() != size) { @@ -100,7 +111,7 @@ TcPacketStored::TcPacketStored(const uint8_t* data, uint32_t size) : if (this->checkAndSetStore()) { ReturnValue_t status = store->addData(&storeAddress, data, size); if (status != HasReturnvaluesIF::RETURN_OK) { - this->setData(NULL); + this->setData(nullptr); } } } diff --git a/tmtcpacket/pus/TcPacketStored.h b/tmtcpacket/pus/TcPacketStored.h index 2d86f89b..1666107b 100644 --- a/tmtcpacket/pus/TcPacketStored.h +++ b/tmtcpacket/pus/TcPacketStored.h @@ -1,8 +1,8 @@ -#ifndef TCPACKETSTORED_H_ -#define TCPACKETSTORED_H_ +#ifndef TMTCPACKET_PUS_TCPACKETSTORED_H_ +#define TMTCPACKET_PUS_TCPACKETSTORED_H_ -#include "../../storagemanager/StorageManagerIF.h" #include "TcPacketBase.h" +#include "../../storagemanager/StorageManagerIF.h" /** * This class generates a ECSS PUS Telecommand packet within a given @@ -15,26 +15,6 @@ * @ingroup tmtcpackets */ class TcPacketStored : public TcPacketBase { -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(); public: /** * This is a default constructor which does not set the data pointer. @@ -53,18 +33,20 @@ public: * 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 ack Set's the packet's Ack field, - * which specifies number and size of verification packets returned - * for this command. * @param service Sets the packet's Service ID field. - * This specifies the destination service. + * 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. + * 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 ack, uint8_t service, uint8_t subservice, uint8_t sequence_count = 0, const uint8_t* data = NULL, uint32_t size = 0 ); + 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. @@ -72,10 +54,19 @@ public: * @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. + * @return The current store address. The (raw) value is + * @c StorageManagerIF::INVALID_ADDRESS if the packet is not linked. */ store_address_t getStoreAddress(); /** @@ -99,7 +90,28 @@ public: * 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 /* TCPACKETSTORED_H_ */ +#endif /* TMTCPACKET_PUS_TCPACKETSTORED_H_ */ diff --git a/tmtcpacket/pus/TmPacketBase.cpp b/tmtcpacket/pus/TmPacketBase.cpp index 3c1a8ca4..f3bc3f00 100644 --- a/tmtcpacket/pus/TmPacketBase.cpp +++ b/tmtcpacket/pus/TmPacketBase.cpp @@ -1,13 +1,19 @@ +#include "TmPacketBase.h" + #include "../../globalfunctions/CRC.h" +#include "../../globalfunctions/arrayprinter.h" #include "../../objectmanager/ObjectManagerIF.h" #include "../../serviceinterface/ServiceInterfaceStream.h" -#include "TmPacketBase.h" #include "../../timemanager/CCSDSTime.h" -#include -TmPacketBase::TmPacketBase(uint8_t* set_data) : - SpacePacketBase(set_data) { - tm_data = (TmPacketPointer*) set_data; +#include + +TimeStamperIF* TmPacketBase::timeStamper = nullptr; +object_id_t TmPacketBase::timeStamperId = 0; + +TmPacketBase::TmPacketBase(uint8_t* setData) : + SpacePacketBase(setData) { + tmData = reinterpret_cast(setData); } TmPacketBase::~TmPacketBase() { @@ -15,25 +21,25 @@ TmPacketBase::~TmPacketBase() { } uint8_t TmPacketBase::getService() { - return tm_data->data_field.service_type; + return tmData->data_field.service_type; } uint8_t TmPacketBase::getSubService() { - return tm_data->data_field.service_subtype; + return tmData->data_field.service_subtype; } uint8_t* TmPacketBase::getSourceData() { - return &tm_data->data; + return &tmData->data; } uint16_t TmPacketBase::getSourceDataSize() { - return getPacketDataLength() - sizeof(tm_data->data_field) + return getPacketDataLength() - sizeof(tmData->data_field) - CRC_SIZE + 1; } uint16_t TmPacketBase::getErrorControl() { uint32_t size = getSourceDataSize() + CRC_SIZE; - uint8_t* p_to_buffer = &tm_data->data; + uint8_t* p_to_buffer = &tmData->data; return (p_to_buffer[size - 2] << 8) + p_to_buffer[size - 1]; } @@ -47,16 +53,12 @@ void TmPacketBase::setErrorControl() { void TmPacketBase::setData(const uint8_t* p_Data) { SpacePacketBase::setData(p_Data); - tm_data = (TmPacketPointer*) p_Data; + tmData = (TmPacketPointer*) p_Data; } void TmPacketBase::print() { - /*uint8_t * wholeData = getWholeData(); - debug << "TmPacket contains: " << std::endl; - for (uint8_t count = 0; count < getFullSize(); ++count ) { - debug << std::hex << (uint16_t)wholeData[count] << " "; - } - debug << std::dec << std::endl;*/ + sif::debug << "TmPacketBase::print: " << std::endl; + arrayprinter::print(getWholeData(), getFullSize()); } bool TmPacketBase::checkAndSetStamper() { @@ -73,32 +75,36 @@ bool TmPacketBase::checkAndSetStamper() { ReturnValue_t TmPacketBase::getPacketTime(timeval* timestamp) const { uint32_t tempSize = 0; - return CCSDSTime::convertFromCcsds(timestamp, tm_data->data_field.time, - &tempSize, sizeof(tm_data->data_field.time)); + return CCSDSTime::convertFromCcsds(timestamp, tmData->data_field.time, + &tempSize, sizeof(tmData->data_field.time)); } uint8_t* TmPacketBase::getPacketTimeRaw() const{ - return tm_data->data_field.time; + return tmData->data_field.time; } -void TmPacketBase::initializeTmPacket(uint16_t apid, uint8_t service, uint8_t subservice, uint8_t packetSubcounter) { +void TmPacketBase::initializeTmPacket(uint16_t apid, uint8_t service, + uint8_t subservice, uint8_t packetSubcounter) { //Set primary header: initSpacePacketHeader(false, true, apid); //Set data Field Header: //First, set to zero. - memset(&tm_data->data_field, 0, sizeof(tm_data->data_field)); - //Set CCSDS_secondary header flag to 0, version number to 001 and ack to 0000 + memset(&tmData->data_field, 0, sizeof(tmData->data_field)); + // NOTE: In PUS-C, the PUS Version is 2 and specified for the first 4 bits. - // The other 4 bits of the first byte are the spacecraft time reference status - // To change to PUS-C, set 0b00100000 - tm_data->data_field.version_type_ack = 0b00010000; - tm_data->data_field.service_type = service; - tm_data->data_field.service_subtype = subservice; - tm_data->data_field.subcounter = packetSubcounter; + // The other 4 bits of the first byte are the spacecraft time reference + // status. To change to PUS-C, set 0b00100000. + // Set CCSDS_secondary header flag to 0, version number to 001 and ack + // to 0000 + tmData->data_field.version_type_ack = 0b00010000; + tmData->data_field.service_type = service; + tmData->data_field.service_subtype = subservice; + tmData->data_field.subcounter = packetSubcounter; //Timestamp packet if (checkAndSetStamper()) { - timeStamper->addTimeStamp(tm_data->data_field.time, sizeof(tm_data->data_field.time)); + timeStamper->addTimeStamp(tmData->data_field.time, + sizeof(tmData->data_field.time)); } } @@ -106,9 +112,6 @@ void TmPacketBase::setSourceDataSize(uint16_t size) { setPacketDataLength(size + sizeof(PUSTmDataFieldHeader) + CRC_SIZE - 1); } -uint32_t TmPacketBase::getTimestampSize() const { - return sizeof(tm_data->data_field.time); +size_t TmPacketBase::getTimestampSize() const { + return sizeof(tmData->data_field.time); } - -TimeStamperIF* TmPacketBase::timeStamper = NULL; -object_id_t TmPacketBase::timeStamperId = 0; diff --git a/tmtcpacket/pus/TmPacketBase.h b/tmtcpacket/pus/TmPacketBase.h index 85ae4dac..6efc0165 100644 --- a/tmtcpacket/pus/TmPacketBase.h +++ b/tmtcpacket/pus/TmPacketBase.h @@ -1,8 +1,8 @@ -#ifndef TMPACKETBASE_H_ -#define TMPACKETBASE_H_ +#ifndef TMTCPACKET_PUS_TMPACKETBASE_H_ +#define TMTCPACKET_PUS_TMPACKETBASE_H_ +#include "../SpacePacketBase.h" #include "../../timemanager/TimeStamperIF.h" -#include "../../tmtcpacket/SpacePacketBase.h" #include "../../timemanager/Clock.h" #include "../../objectmanager/SystemObjectIF.h" @@ -14,7 +14,7 @@ void setStaticFrameworkObjectIds(); * This struct defines a byte-wise structured PUS TM Data Field Header. * Any optional fields in the header must be added or removed here. * Currently, no Destination field is present, but an eigth-byte representation - * for a time tag [TBD]. + * for a time tag. * @ingroup tmtcpackets */ struct PUSTmDataFieldHeader { @@ -40,7 +40,7 @@ struct TmPacketPointer { /** * This class is the basic data handler for any ECSS PUS Telemetry packet. * - * In addition to \SpacePacketBase, the class provides methods to handle + * In addition to #SpacePacketBase, the class provides methods to handle * the standardized entries of the PUS TM 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 @@ -54,29 +54,27 @@ public: /** * This constant defines the minimum size of a valid PUS Telemetry Packet. */ - static const uint32_t TM_PACKET_MIN_SIZE = (sizeof(CCSDSPrimaryHeader) + sizeof(PUSTmDataFieldHeader) + 2); //!< Minimum size of a valid PUS Telemetry Packet. - static const uint32_t MISSION_TM_PACKET_MAX_SIZE = 2048; //!< Maximum size of a TM Packet in this mission. - static const uint8_t VERSION_NUMBER_BYTE_PUS_A = 0b00010000; //!< First byte of secondary header for PUS-A packets. + static const uint32_t TM_PACKET_MIN_SIZE = (sizeof(CCSDSPrimaryHeader) + + sizeof(PUSTmDataFieldHeader) + 2); + //! Maximum size of a TM Packet in this mission. + //! TODO: Make this dependant on a config variable. + static const uint32_t MISSION_TM_PACKET_MAX_SIZE = 2048; + //! First byte of secondary header for PUS-A packets. + //! TODO: Maybe also support PUS-C via config? + static const uint8_t VERSION_NUMBER_BYTE_PUS_A = 0b00010000; + /** * This is the default constructor. * It sets its internal data pointer to the address passed and also * forwards the data pointer to the parent SpacePacketBase class. * @param set_address The position where the packet data lies. */ - TmPacketBase( uint8_t* set_data ); + TmPacketBase( uint8_t* setData ); /** * This is the empty default destructor. */ virtual ~TmPacketBase(); - /** - * Initializes the Tm Packet header. - * Does set the timestamp (to now), but not the error control field. - * @param apid APID used. - * @param service PUS Service - * @param subservice PUS Subservice - * @param packetSubcounter Additional subcounter used. - */ - void initializeTmPacket(uint16_t apid, uint8_t service, uint8_t subservice, uint8_t packetSubcounter); + /** * This is a getter for the packet's PUS Service ID, which is the second * byte of the Data Field Header. @@ -106,11 +104,14 @@ public: */ uint16_t getSourceDataSize(); - /** - * In case data was filled manually (almost never the case). - * @param size Size of source data (without CRC and data filed header!). - */ - void setSourceDataSize(uint16_t size); + /** + * With this method, the Error Control Field is updated to match the + * current content of the packet. This method is not protected because + * a recalculation by the user might be necessary when manipulating fields + * like the sequence count. + */ + void setErrorControl(); + /** * This getter returns the Error Control Field of the packet. * @@ -120,28 +121,15 @@ public: * @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(); - /** - * With this method, the packet data pointer can be redirected to another - * location. - * - * This call overwrites the parent's setData method to set both its - * \c tc_data pointer and the parent's \c data pointer. - * - * @param p_data A pointer to another PUS Telemetry Packet. - */ - void setData( const uint8_t* p_Data ); + /** * This is a debugging helper method that prints the whole packet content * to the screen. */ void print(); /** - * Interprets the "time"-field in the secondary header and returns it in timeval format. + * Interprets the "time"-field in the secondary header and returns it in + * timeval format. * @return Converted timestamp of packet. */ ReturnValue_t getPacketTime(timeval* timestamp) const; @@ -151,7 +139,7 @@ public: */ uint8_t* getPacketTimeRaw() const; - uint32_t getTimestampSize() const; + size_t getTimestampSize() const; protected: /** @@ -160,20 +148,49 @@ protected: * * To be hardware-safe, all elements are of byte size. */ - TmPacketPointer* tm_data; + TmPacketPointer* tmData; /** * The timeStamper is responsible for adding a timestamp to the packet. * It is initialized lazy. */ static TimeStamperIF* timeStamper; + //! The ID to use when looking for a time stamper. + static object_id_t timeStamperId; - static object_id_t timeStamperId; //!< The ID to use when looking for a time stamper. - /** - * Checks if a time stamper is available and tries to set it if not. - * @return Returns false if setting failed. - */ - bool checkAndSetStamper(); + /** + * Initializes the Tm Packet header. + * Does set the timestamp (to now), but not the error control field. + * @param apid APID used. + * @param service PUS Service + * @param subservice PUS Subservice + * @param packetSubcounter Additional subcounter used. + */ + void initializeTmPacket(uint16_t apid, uint8_t service, uint8_t subservice, + uint8_t packetSubcounter); + + /** + * With this method, the packet data pointer can be redirected to another + * location. + * + * This call overwrites the parent's setData method to set both its + * @c tc_data pointer and the parent's @c data pointer. + * + * @param p_data A pointer to another PUS Telemetry Packet. + */ + void setData( const uint8_t* pData ); + + /** + * In case data was filled manually (almost never the case). + * @param size Size of source data (without CRC and data filed header!). + */ + void setSourceDataSize(uint16_t size); + + /** + * Checks if a time stamper is available and tries to set it if not. + * @return Returns false if setting failed. + */ + bool checkAndSetStamper(); }; -#endif /* TMPACKETBASE_H_ */ +#endif /* TMTCPACKET_PUS_TMPACKETBASE_H_ */ diff --git a/tmtcpacket/pus/TmPacketStored.cpp b/tmtcpacket/pus/TmPacketStored.cpp index 4e4c9434..0fb789aa 100644 --- a/tmtcpacket/pus/TmPacketStored.cpp +++ b/tmtcpacket/pus/TmPacketStored.cpp @@ -1,11 +1,16 @@ +#include "TmPacketStored.h" + #include "../../objectmanager/ObjectManagerIF.h" #include "../../serviceinterface/ServiceInterfaceStream.h" -#include "TmPacketStored.h" #include "../../tmtcservices/TmTcMessage.h" -#include + +#include + +StorageManagerIF *TmPacketStored::store = nullptr; +InternalErrorReporterIF *TmPacketStored::internalErrorReporter = nullptr; TmPacketStored::TmPacketStored(store_address_t setAddress) : - TmPacketBase(NULL), storeAddress(setAddress) { + TmPacketBase(nullptr), storeAddress(setAddress) { setStoreAddress(storeAddress); } @@ -14,10 +19,10 @@ TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service, uint32_t size, const uint8_t *headerData, uint32_t headerSize) : TmPacketBase(NULL) { storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; - if (!checkAndSetStore()) { + if (not checkAndSetStore()) { return; } - uint8_t *pData = NULL; + uint8_t *pData = nullptr; ReturnValue_t returnValue = store->getFreeElement(&storeAddress, (TmPacketBase::TM_PACKET_MIN_SIZE + size + headerSize), &pData); @@ -38,7 +43,7 @@ TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service, SerializeIF *header) : TmPacketBase(NULL) { storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; - if (!checkAndSetStore()) { + if (not checkAndSetStore()) { return; } size_t sourceDataSize = 0; @@ -77,29 +82,29 @@ store_address_t TmPacketStored::getStoreAddress() { void TmPacketStored::deletePacket() { store->deleteData(storeAddress); storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; - setData(NULL); + setData(nullptr); } void TmPacketStored::setStoreAddress(store_address_t setAddress) { storeAddress = setAddress; - const uint8_t* temp_data = NULL; - size_t temp_size; - if (!checkAndSetStore()) { + const uint8_t* tempData = nullptr; + size_t tempSize; + if (not checkAndSetStore()) { return; } - ReturnValue_t status = store->getData(storeAddress, &temp_data, &temp_size); + ReturnValue_t status = store->getData(storeAddress, &tempData, &tempSize); if (status == StorageManagerIF::RETURN_OK) { - setData(temp_data); + setData(tempData); } else { - setData(NULL); + setData(nullptr); storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; } } bool TmPacketStored::checkAndSetStore() { - if (store == NULL) { + if (store == nullptr) { store = objectManager->get(objects::TM_STORE); - if (store == NULL) { + if (store == nullptr) { sif::error << "TmPacketStored::TmPacketStored: TM Store not found!" << std::endl; return false; @@ -108,12 +113,9 @@ bool TmPacketStored::checkAndSetStore() { return true; } -StorageManagerIF *TmPacketStored::store = NULL; -InternalErrorReporterIF *TmPacketStored::internalErrorReporter = NULL; - ReturnValue_t TmPacketStored::sendPacket(MessageQueueId_t destination, MessageQueueId_t sentFrom, bool doErrorReporting) { - if (getWholeData() == NULL) { + if (getWholeData() == nullptr) { //SHOULDDO: More decent code. return HasReturnvaluesIF::RETURN_FAILED; } @@ -133,11 +135,11 @@ ReturnValue_t TmPacketStored::sendPacket(MessageQueueId_t destination, } void TmPacketStored::checkAndReportLostTm() { - if (internalErrorReporter == NULL) { + if (internalErrorReporter == nullptr) { internalErrorReporter = objectManager->get( objects::INTERNAL_ERROR_REPORTER); } - if (internalErrorReporter != NULL) { + if (internalErrorReporter != nullptr) { internalErrorReporter->lostTm(); } } diff --git a/tmtcpacket/pus/TmPacketStored.h b/tmtcpacket/pus/TmPacketStored.h index 8962d343..6ddbf131 100644 --- a/tmtcpacket/pus/TmPacketStored.h +++ b/tmtcpacket/pus/TmPacketStored.h @@ -1,9 +1,10 @@ -#ifndef TMPACKETSTORED_H_ -#define TMPACKETSTORED_H_ +#ifndef TMTCPACKET_PUS_TMPACKETSTORED_H_ +#define TMTCPACKET_PUS_TMPACKETSTORED_H_ + +#include "TmPacketBase.h" #include "../../serialize/SerializeIF.h" #include "../../storagemanager/StorageManagerIF.h" -#include "TmPacketBase.h" #include "../../internalError/InternalErrorReporterIF.h" #include "../../ipc/MessageQueueSenderIF.h" @@ -18,31 +19,6 @@ * @ingroup tmtcpackets */ class TmPacketStored : public TmPacketBase { -private: - /** - * This is a pointer to the store all instances of the class use. - * If the store is not yet set (i.e. \c store is NULL), every constructor - * call tries to set it and throws an error message in case of failures. - * The default store is objects::TM_STORE. - */ - static StorageManagerIF* store; - - static InternalErrorReporterIF *internalErrorReporter; - - /** - * The address where the packet data of the object instance is stored. - */ - store_address_t storeAddress; - /** - * A helper method to check if a store is assigned to the class. - * If not, the method tries to retrieve the store from the global - * ObjectManager. - * @return @li \c true if the store is linked or could be created. - * @li \c false otherwise. - */ - bool checkAndSetStore(); - - void checkAndReportLostTm(); public: /** * This is a default constructor which does not set the data pointer. @@ -52,28 +28,38 @@ public: /** * With this constructor, new space is allocated in the packet store and * a new PUS Telemetry Packet is created there. - * Packet Application Data passed in data is copied into the packet. The Application data is - * passed in two parts, first a header, then a data field. This allows building a Telemetry - * Packet from two separate data sources. + * Packet Application Data passed in data is copied into the packet. + * The Application data is passed in two parts, first a header, then a + * data field. This allows building a Telemetry Packet from two separate + * data sources. * @param apid Sets the packet's APID field. * @param service Sets the packet's Service ID field. * This specifies the source service. * @param subservice Sets the packet's Service Subtype field. * This specifies the source sub-service. * @param packet_counter Sets the Packet counter field of this packet - * @param data The payload data to be copied to the Application Data Field + * @param data The payload data to be copied to the + * Application Data Field * @param size The amount of data to be copied. - * @param headerData The header Data of the Application field; will be copied in front of data + * @param headerData The header Data of the Application field, + * will be copied in front of data * @param headerSize The size of the headerDataF */ - TmPacketStored( uint16_t apid, uint8_t service, uint8_t subservice, uint8_t packet_counter = 0, const uint8_t* data = NULL, uint32_t size = 0, const uint8_t* headerData = NULL, uint32_t headerSize = 0); + TmPacketStored( uint16_t apid, uint8_t service, uint8_t subservice, + uint8_t packet_counter = 0, const uint8_t* data = nullptr, + uint32_t size = 0, const uint8_t* headerData = nullptr, + uint32_t headerSize = 0); /** - * Another ctor to directly pass structured content and header data to the packet to avoid additional buffers. + * Another ctor to directly pass structured content and header data to the + * packet to avoid additional buffers. */ - TmPacketStored( uint16_t apid, uint8_t service, uint8_t subservice, uint8_t packet_counter, SerializeIF* content, SerializeIF* header = NULL); + TmPacketStored( uint16_t apid, uint8_t service, uint8_t subservice, + uint8_t packet_counter, SerializeIF* content, + SerializeIF* header = nullptr); /** * This is a getter for the current store address of the packet. - * @return The current store address. The (raw) value is \c StorageManagerIF::INVALID_ADDRESS if + * @return The current store address. The (raw) value is + * @c StorageManagerIF::INVALID_ADDRESS if * the packet is not linked. */ store_address_t getStoreAddress(); @@ -89,8 +75,34 @@ public: */ void setStoreAddress( store_address_t setAddress ); - ReturnValue_t sendPacket( MessageQueueId_t destination, MessageQueueId_t sentFrom, bool doErrorReporting = true ); + ReturnValue_t sendPacket( MessageQueueId_t destination, + MessageQueueId_t sentFrom, bool doErrorReporting = true ); +private: + /** + * This is a pointer to the store all instances of the class use. + * If the store is not yet set (i.e. @c store is NULL), every constructor + * call tries to set it and throws an error message in case of failures. + * The default store is objects::TM_STORE. + */ + static StorageManagerIF* store; + + static InternalErrorReporterIF *internalErrorReporter; + + /** + * The address where the packet data of the object instance is stored. + */ + store_address_t storeAddress; + /** + * A helper method to check if a store is assigned to the class. + * If not, the method tries to retrieve the store from the global + * ObjectManager. + * @return @li @c true if the store is linked or could be created. + * @li @c false otherwise. + */ + bool checkAndSetStore(); + + void checkAndReportLostTm(); }; -#endif /* TMPACKETSTORED_H_ */ +#endif /* TMTCPACKET_PUS_TMPACKETSTORED_H_ */