Added CFDP packet stack
This PR adds the packet stack for the CCSDS File Delivery Protocol. It also refactors the existing TMTC infastructure to allow sending of CFDP packets to the CCSDS handlers. This includes the whole PDU (Protocol Data Unit) stack: - File Data PDUs and all file directive PDUs - ACK PDU - NAK PDU - Metadata PDU - Finished PDU - Prompt PDU - Keep Alive PDU - EOF PDU The PR includes a full set of unittests for the packet stack with a coverage of 90+ %. The refactoring of the existing TMTC infastructure includes non-ideal solutions like diamond inheritance. Avoiding this solution would require refactoring the packet stack. This would be a good idea anyway because the existing stack is tightly coupled to the FSFW, making reuse more difficult if only the stack is planned to be used without the store functionalities etc. The PDU implementation provided here is only weakly coupled to the FSFW, only using components like returnvalues or the Serialization modules. There are dedicated serializers and deserializers, which also helps in creating small focused modules which are easy to test. Some of the modules here were provied by Matthias Tompert.
This commit is contained in:
@ -3,5 +3,6 @@ target_sources(${LIB_FSFW_NAME} PRIVATE
|
||||
SpacePacketBase.cpp
|
||||
)
|
||||
|
||||
add_subdirectory(cfdp)
|
||||
add_subdirectory(packetmatcher)
|
||||
add_subdirectory(pus)
|
34
src/fsfw/tmtcpacket/RedirectableDataPointerIF.h
Normal file
34
src/fsfw/tmtcpacket/RedirectableDataPointerIF.h
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef TMTCPACKET_PUS_TC_SETTABLEDATAPOINTERIF_H_
|
||||
#define TMTCPACKET_PUS_TC_SETTABLEDATAPOINTERIF_H_
|
||||
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include <cstddef>
|
||||
|
||||
/**
|
||||
* @brief This interface can be used for classes which store a reference to data. It allows
|
||||
* the implementing class to redirect the data it refers too.
|
||||
*/
|
||||
class RedirectableDataPointerIF {
|
||||
public:
|
||||
virtual ~RedirectableDataPointerIF() {};
|
||||
|
||||
/**
|
||||
* Redirect the data pointer, but allow an implementation to change the data.
|
||||
* The default implementation also sets a read-only pointer where applicable.
|
||||
* @param dataPtr
|
||||
* @param maxSize Maximum allowed size in buffer which holds the data. Can be used for size
|
||||
* checks if a struct is cast directly onto the data pointer to ensure that the buffer is
|
||||
* large enough
|
||||
* @param args Any additional user arguments required to set the data pointer
|
||||
* @return
|
||||
* - RETURN_OK if the pointer was set successfully
|
||||
* - RETURN_FAILED on general error of if the maximum size is too small
|
||||
*/
|
||||
virtual ReturnValue_t setData(uint8_t* dataPtr, size_t maxSize, void* args = nullptr) = 0;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_TMTCPACKET_PUS_TC_SETTABLEDATAPOINTERIF_H_ */
|
@ -5,23 +5,23 @@
|
||||
SpacePacket::SpacePacket(uint16_t packetDataLength, bool isTelecommand, uint16_t apid,
|
||||
uint16_t sequenceCount):
|
||||
SpacePacketBase( (uint8_t*)&this->localData ) {
|
||||
initSpacePacketHeader(isTelecommand, false, apid, sequenceCount);
|
||||
this->setPacketSequenceCount(sequenceCount);
|
||||
if ( packetDataLength <= sizeof(this->localData.fields.buffer) ) {
|
||||
this->setPacketDataLength(packetDataLength);
|
||||
} else {
|
||||
this->setPacketDataLength( sizeof(this->localData.fields.buffer) );
|
||||
}
|
||||
initSpacePacketHeader(isTelecommand, false, apid, sequenceCount);
|
||||
this->setPacketSequenceCount(sequenceCount);
|
||||
if ( packetDataLength <= sizeof(this->localData.fields.buffer) ) {
|
||||
this->setPacketDataLength(packetDataLength);
|
||||
} else {
|
||||
this->setPacketDataLength( sizeof(this->localData.fields.buffer) );
|
||||
}
|
||||
}
|
||||
|
||||
SpacePacket::~SpacePacket( void ) {
|
||||
}
|
||||
|
||||
bool SpacePacket::addWholeData( const uint8_t* p_Data, uint32_t packet_size ) {
|
||||
if ( packet_size <= sizeof(this->data) ) {
|
||||
memcpy( &this->localData.byteStream, p_Data, packet_size );
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if ( packet_size <= sizeof(this->data) ) {
|
||||
memcpy( &this->localData.byteStream, p_Data, packet_size );
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ public:
|
||||
* @param sequenceCount ets the packet's Source Sequence Count field.
|
||||
*/
|
||||
SpacePacket(uint16_t packetDataLength, bool isTelecommand = false,
|
||||
uint16_t apid = APID_IDLE_PACKET, uint16_t sequenceCount = 0);
|
||||
uint16_t apid = APID_IDLE_PACKET, uint16_t sequenceCount = 0);
|
||||
/**
|
||||
* The class's default destructor.
|
||||
*/
|
||||
|
@ -110,10 +110,6 @@ uint8_t* SpacePacketBase::getWholeData() {
|
||||
return (uint8_t*)this->data;
|
||||
}
|
||||
|
||||
void SpacePacketBase::setData( const uint8_t* p_Data ) {
|
||||
this->data = (SpacePacketPointer*)p_Data;
|
||||
}
|
||||
|
||||
uint32_t SpacePacketBase::getApidAndSequenceCount() const {
|
||||
return (getAPID() << 16) + getPacketSequenceCount();
|
||||
}
|
||||
@ -121,3 +117,11 @@ uint32_t SpacePacketBase::getApidAndSequenceCount() const {
|
||||
uint8_t* SpacePacketBase::getPacketData() {
|
||||
return &(data->packet_data);
|
||||
}
|
||||
|
||||
ReturnValue_t SpacePacketBase::setData(uint8_t *pData, size_t maxSize, void *args) {
|
||||
if(maxSize < 6) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
this->data = reinterpret_cast<SpacePacketPointer*>(const_cast<uint8_t*>(pData));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef FSFW_TMTCPACKET_SPACEPACKETBASE_H_
|
||||
#define FSFW_TMTCPACKET_SPACEPACKETBASE_H_
|
||||
|
||||
#include <fsfw/tmtcpacket/RedirectableDataPointerIF.h>
|
||||
#include "ccsds_header.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
@ -37,7 +38,7 @@ struct SpacePacketPointer {
|
||||
* the most significant bit (from left).
|
||||
* @ingroup tmtcpackets
|
||||
*/
|
||||
class SpacePacketBase {
|
||||
class SpacePacketBase: virtual public RedirectableDataPointerIF {
|
||||
protected:
|
||||
/**
|
||||
* A pointer to a structure which defines the data structure of
|
||||
@ -70,8 +71,7 @@ public:
|
||||
*/
|
||||
virtual ~SpacePacketBase();
|
||||
|
||||
//CCSDS Methods
|
||||
|
||||
//CCSDS Methods:
|
||||
/**
|
||||
* Getter for the packet version number field.
|
||||
* @return Returns the highest three bit of the packet in one byte.
|
||||
@ -163,7 +163,7 @@ public:
|
||||
*/
|
||||
void setPacketDataLength( uint16_t setLength );
|
||||
|
||||
// Helper methods
|
||||
//Helper methods:
|
||||
/**
|
||||
* This method returns a raw uint8_t pointer to the packet.
|
||||
* @return A \c uint8_t pointer to the first byte of the CCSDS primary header.
|
||||
@ -171,12 +171,14 @@ public:
|
||||
virtual uint8_t* getWholeData( void );
|
||||
|
||||
uint8_t* getPacketData();
|
||||
|
||||
/**
|
||||
* With this method, the packet data pointer can be redirected to another
|
||||
* location.
|
||||
* @param p_Data A pointer to another raw Space Packet.
|
||||
*/
|
||||
virtual void setData( const uint8_t* p_Data );
|
||||
virtual ReturnValue_t setData(uint8_t* p_Data , size_t maxSize,
|
||||
void* args = nullptr) override;
|
||||
/**
|
||||
* This method returns the full raw packet size.
|
||||
* @return The full size of the packet in bytes.
|
||||
|
20
src/fsfw/tmtcpacket/cfdp/CFDPPacket.cpp
Normal file
20
src/fsfw/tmtcpacket/cfdp/CFDPPacket.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
#include "fsfw/tmtcpacket/cfdp/CFDPPacket.h"
|
||||
|
||||
#include "fsfw/globalfunctions/CRC.h"
|
||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
CFDPPacket::CFDPPacket(const uint8_t* setData): SpacePacketBase(setData) {}
|
||||
|
||||
CFDPPacket::~CFDPPacket() {}
|
||||
|
||||
void CFDPPacket::print() {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::info << "CFDPPacket::print:" << std::endl;
|
||||
#else
|
||||
sif::printInfo("CFDPPacket::print:\n");
|
||||
#endif
|
||||
arrayprinter::print(getWholeData(), getFullSize());
|
||||
}
|
27
src/fsfw/tmtcpacket/cfdp/CFDPPacket.h
Normal file
27
src/fsfw/tmtcpacket/cfdp/CFDPPacket.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef FSFW_INC_FSFW_TMTCPACKET_CFDP_CFDPPACKET_H_
|
||||
#define FSFW_INC_FSFW_TMTCPACKET_CFDP_CFDPPACKET_H_
|
||||
|
||||
#include "fsfw/tmtcpacket/SpacePacketBase.h"
|
||||
|
||||
class CFDPPacket : public SpacePacketBase {
|
||||
public:
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
CFDPPacket( const uint8_t* setData );
|
||||
/**
|
||||
* This is the empty default destructor.
|
||||
*/
|
||||
virtual ~CFDPPacket();
|
||||
|
||||
/**
|
||||
* This is a debugging helper method that prints the whole packet content
|
||||
* to the screen.
|
||||
*/
|
||||
void print();
|
||||
};
|
||||
|
||||
#endif /* FSFW_INC_FSFW_TMTCPACKET_CFDP_CFDPPACKET_H_ */
|
97
src/fsfw/tmtcpacket/cfdp/CFDPPacketStored.cpp
Normal file
97
src/fsfw/tmtcpacket/cfdp/CFDPPacketStored.cpp
Normal file
@ -0,0 +1,97 @@
|
||||
#include "fsfw/tmtcpacket/cfdp/CFDPPacketStored.h"
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
|
||||
StorageManagerIF* CFDPPacketStored::store = nullptr;
|
||||
|
||||
CFDPPacketStored::CFDPPacketStored(): CFDPPacket(nullptr) {
|
||||
}
|
||||
|
||||
CFDPPacketStored::CFDPPacketStored(store_address_t setAddress): CFDPPacket(nullptr) {
|
||||
this->setStoreAddress(setAddress);
|
||||
}
|
||||
|
||||
CFDPPacketStored::CFDPPacketStored(const uint8_t* data, size_t size): CFDPPacket(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, -1);
|
||||
}
|
||||
const uint8_t* storePtr = nullptr;
|
||||
// Repoint base data pointer to the data in the store.
|
||||
store->getData(storeAddress, &storePtr, &size);
|
||||
this->setData(const_cast<uint8_t*>(storePtr), size);
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t CFDPPacketStored::deletePacket() {
|
||||
ReturnValue_t result = this->store->deleteData(this->storeAddress);
|
||||
this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
|
||||
// To circumvent size checks
|
||||
this->setData(nullptr, -1);
|
||||
return result;
|
||||
}
|
||||
|
||||
//CFDPPacket* CFDPPacketStored::getPacketBase() {
|
||||
// return this;
|
||||
//}
|
||||
void CFDPPacketStored::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);
|
||||
}
|
||||
if (status == StorageManagerIF::RETURN_OK) {
|
||||
this->setData(const_cast<uint8_t*>(tempData), tempSize);
|
||||
} else {
|
||||
// To circumvent size checks
|
||||
this->setData(nullptr, -1);
|
||||
this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
|
||||
}
|
||||
}
|
||||
|
||||
store_address_t CFDPPacketStored::getStoreAddress() {
|
||||
return this->storeAddress;
|
||||
}
|
||||
|
||||
CFDPPacketStored::~CFDPPacketStored() {
|
||||
}
|
||||
|
||||
ReturnValue_t CFDPPacketStored::getData(const uint8_t **dataPtr, size_t *dataSize) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
//ReturnValue_t CFDPPacketStored::setData(const uint8_t *data) {
|
||||
// return HasReturnvaluesIF::RETURN_OK;
|
||||
//}
|
||||
|
||||
bool CFDPPacketStored::checkAndSetStore() {
|
||||
if (this->store == nullptr) {
|
||||
this->store = ObjectManager::instance()->get<StorageManagerIF>(objects::TC_STORE);
|
||||
if (this->store == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "CFDPPacketStored::CFDPPacketStored: TC Store not found!"
|
||||
<< std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CFDPPacketStored::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;
|
||||
}
|
67
src/fsfw/tmtcpacket/cfdp/CFDPPacketStored.h
Normal file
67
src/fsfw/tmtcpacket/cfdp/CFDPPacketStored.h
Normal file
@ -0,0 +1,67 @@
|
||||
#ifndef FSFW_INC_FSFW_TMTCPACKET_CFDP_CFDPPACKETSTORED_H_
|
||||
#define FSFW_INC_FSFW_TMTCPACKET_CFDP_CFDPPACKETSTORED_H_
|
||||
|
||||
#include "../pus/tc/TcPacketStoredBase.h"
|
||||
#include "CFDPPacket.h"
|
||||
|
||||
class CFDPPacketStored:
|
||||
public CFDPPacket,
|
||||
public TcPacketStoredBase {
|
||||
public:
|
||||
/**
|
||||
* Create stored packet with existing data.
|
||||
* @param data
|
||||
* @param size
|
||||
*/
|
||||
CFDPPacketStored(const uint8_t* data, size_t size);
|
||||
/**
|
||||
* Create stored packet from existing packet in store
|
||||
* @param setAddress
|
||||
*/
|
||||
CFDPPacketStored(store_address_t setAddress);
|
||||
CFDPPacketStored();
|
||||
|
||||
virtual ~CFDPPacketStored();
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
void setStoreAddress(store_address_t setAddress);
|
||||
|
||||
store_address_t getStoreAddress();
|
||||
|
||||
ReturnValue_t deletePacket();
|
||||
|
||||
private:
|
||||
|
||||
bool isSizeCorrect();
|
||||
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 /* FSFW_INC_FSFW_TMTCPACKET_CFDP_CFDPPACKETSTORED_H_ */
|
4
src/fsfw/tmtcpacket/cfdp/CMakeLists.txt
Normal file
4
src/fsfw/tmtcpacket/cfdp/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE
|
||||
CFDPPacket.cpp
|
||||
CFDPPacketStored.cpp
|
||||
)
|
@ -1,5 +1,5 @@
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE
|
||||
TcPacketBase.cpp
|
||||
TcPacketPusBase.cpp
|
||||
TcPacketPus.cpp
|
||||
TcPacketStoredBase.cpp
|
||||
TcPacketStoredPus.cpp
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <cstring>
|
||||
|
||||
TcPacketPus::TcPacketPus(const uint8_t *setData): TcPacketBase(setData) {
|
||||
TcPacketPus::TcPacketPus(const uint8_t *setData): TcPacketPusBase(setData) {
|
||||
tcData = reinterpret_cast<TcPacketPointer*>(const_cast<uint8_t*>(setData));
|
||||
}
|
||||
|
||||
@ -59,13 +59,6 @@ void TcPacketPus::setErrorControl() {
|
||||
(&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<TcPacketPointer*>(const_cast<uint8_t*>(pData));
|
||||
}
|
||||
|
||||
uint8_t TcPacketPus::getSecondaryHeaderFlag() const {
|
||||
#if FSFW_USE_PUS_C_TELECOMMANDS == 1
|
||||
// Does not exist for PUS C
|
||||
@ -93,5 +86,20 @@ uint16_t TcPacketPus::getSourceId() const {
|
||||
|
||||
size_t TcPacketPus::calculateFullPacketLength(size_t appDataLen) const {
|
||||
return sizeof(CCSDSPrimaryHeader) + sizeof(PUSTcDataFieldHeader) +
|
||||
appDataLen + TcPacketBase::CRC_SIZE;
|
||||
appDataLen + TcPacketPusBase::CRC_SIZE;
|
||||
}
|
||||
|
||||
ReturnValue_t TcPacketPus::setData(uint8_t *dataPtr, size_t maxSize, void *args) {
|
||||
ReturnValue_t result = SpacePacketBase::setData(dataPtr, maxSize);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if(maxSize < sizeof(TcPacketPointer)) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
// This function is const-correct, but it was decided to keep the pointer non-const
|
||||
// for convenience. Therefore, cast away constness here and then cast to packet type.
|
||||
tcData = reinterpret_cast<TcPacketPointer*>(const_cast<uint8_t*>(dataPtr));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "fsfw/FSFW.h"
|
||||
#include "../definitions.h"
|
||||
#include "fsfw/tmtcpacket/ccsds_header.h"
|
||||
#include "TcPacketBase.h"
|
||||
#include "TcPacketPusBase.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
@ -38,7 +38,7 @@ struct TcPacketPointer {
|
||||
};
|
||||
|
||||
|
||||
class TcPacketPus: public TcPacketBase {
|
||||
class TcPacketPus: public TcPacketPusBase {
|
||||
public:
|
||||
static const uint16_t TC_PACKET_MIN_SIZE = (sizeof(CCSDSPrimaryHeader) +
|
||||
sizeof(PUSTcDataFieldHeader) + 2);
|
||||
@ -65,7 +65,8 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
void setData(const uint8_t* pData) override;
|
||||
ReturnValue_t setData(uint8_t* dataPtr, size_t maxSize,
|
||||
void* args = nullptr) override;
|
||||
|
||||
/**
|
||||
* Initializes the Tc Packet header.
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "fsfw/tmtcpacket/pus/tc/TcPacketBase.h"
|
||||
#include "TcPacketPusBase.h"
|
||||
|
||||
#include "fsfw/globalfunctions/CRC.h"
|
||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||
@ -6,11 +6,11 @@
|
||||
|
||||
#include <cstring>
|
||||
|
||||
TcPacketBase::TcPacketBase(const uint8_t* setData): SpacePacketBase(setData) {}
|
||||
TcPacketPusBase::TcPacketPusBase(const uint8_t* setData): SpacePacketBase(setData) {}
|
||||
|
||||
TcPacketBase::~TcPacketBase() {}
|
||||
TcPacketPusBase::~TcPacketPusBase() {}
|
||||
|
||||
void TcPacketBase::print() {
|
||||
void TcPacketPusBase::print() {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::info << "TcPacketBase::print:" << std::endl;
|
||||
#else
|
@ -1,6 +1,7 @@
|
||||
#ifndef TMTCPACKET_PUS_TCPACKETBASE_H_
|
||||
#define TMTCPACKET_PUS_TCPACKETBASE_H_
|
||||
|
||||
#include <fsfw/tmtcpacket/RedirectableDataPointerIF.h>
|
||||
#include "fsfw/tmtcpacket/SpacePacketBase.h"
|
||||
#include <cstddef>
|
||||
|
||||
@ -15,7 +16,8 @@
|
||||
* check can be performed by making use of the getWholeData method.
|
||||
* @ingroup tmtcpackets
|
||||
*/
|
||||
class TcPacketBase : public SpacePacketBase {
|
||||
class TcPacketPusBase : public SpacePacketBase,
|
||||
virtual public RedirectableDataPointerIF {
|
||||
friend class TcPacketStoredBase;
|
||||
public:
|
||||
|
||||
@ -41,11 +43,11 @@ public:
|
||||
* forwards the data pointer to the parent SpacePacketBase class.
|
||||
* @param setData The position where the packet data lies.
|
||||
*/
|
||||
TcPacketBase( const uint8_t* setData );
|
||||
TcPacketPusBase( const uint8_t* setData );
|
||||
/**
|
||||
* This is the empty default destructor.
|
||||
*/
|
||||
virtual ~TcPacketBase();
|
||||
virtual ~TcPacketPusBase();
|
||||
|
||||
/**
|
||||
* This command returns the CCSDS Secondary Header Flag.
|
||||
@ -133,6 +135,7 @@ public:
|
||||
* to the screen.
|
||||
*/
|
||||
void print();
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
@ -143,7 +146,8 @@ protected:
|
||||
*
|
||||
* @param p_data A pointer to another PUS Telecommand Packet.
|
||||
*/
|
||||
void setData( const uint8_t* pData ) = 0;
|
||||
virtual ReturnValue_t setData(uint8_t* pData, size_t maxSize,
|
||||
void* args = nullptr) override = 0;
|
||||
};
|
||||
|
||||
|
@ -46,7 +46,8 @@ bool TcPacketStoredBase::checkAndSetStore() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void TcPacketStoredBase::setStoreAddress(store_address_t setAddress) {
|
||||
void TcPacketStoredBase::setStoreAddress(store_address_t setAddress,
|
||||
RedirectableDataPointerIF* packet) {
|
||||
this->storeAddress = setAddress;
|
||||
const uint8_t* tempData = nullptr;
|
||||
size_t tempSize;
|
||||
@ -54,15 +55,12 @@ void TcPacketStoredBase::setStoreAddress(store_address_t setAddress) {
|
||||
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);
|
||||
packet->setData(const_cast<uint8_t*>(tempData), tempSize);
|
||||
}
|
||||
else {
|
||||
tcPacketBase->setData(nullptr);
|
||||
packet->setData(nullptr, -1);
|
||||
this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
|
||||
}
|
||||
}
|
||||
|
@ -2,16 +2,10 @@
|
||||
#define TMTCPACKET_PUS_TCPACKETSTORED_H_
|
||||
|
||||
#include "TcPacketStoredIF.h"
|
||||
#include "../../../storagemanager/StorageManagerIF.h"
|
||||
#include "fsfw/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.
|
||||
* Base class for telecommand packets like CFDP or PUS packets.
|
||||
* @ingroup tmtcpackets
|
||||
*/
|
||||
class TcPacketStoredBase: public TcPacketStoredIF {
|
||||
@ -44,7 +38,7 @@ public:
|
||||
*/
|
||||
ReturnValue_t getData(const uint8_t ** dataPtr, size_t* dataSize) override;
|
||||
|
||||
void setStoreAddress(store_address_t setAddress) override;
|
||||
void setStoreAddress(store_address_t setAddress, RedirectableDataPointerIF* packet) override;
|
||||
store_address_t getStoreAddress() override;
|
||||
|
||||
/**
|
||||
|
@ -1,9 +1,10 @@
|
||||
#ifndef FSFW_TMTCPACKET_PUS_TCPACKETSTOREDIF_H_
|
||||
#define FSFW_TMTCPACKET_PUS_TCPACKETSTOREDIF_H_
|
||||
|
||||
#include "TcPacketBase.h"
|
||||
#include "../../../storagemanager/storeAddress.h"
|
||||
#include "../../../returnvalues/HasReturnvaluesIF.h"
|
||||
#include <fsfw/tmtcpacket/RedirectableDataPointerIF.h>
|
||||
#include "TcPacketPusBase.h"
|
||||
#include "fsfw/storagemanager/storeAddress.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
class TcPacketStoredIF {
|
||||
public:
|
||||
@ -14,7 +15,7 @@ public:
|
||||
* 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 void setStoreAddress(store_address_t setAddress, RedirectableDataPointerIF* packet) = 0;
|
||||
|
||||
virtual store_address_t getStoreAddress() = 0;
|
||||
|
||||
@ -25,12 +26,6 @@ public:
|
||||
* @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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -22,7 +22,7 @@ TcPacketStoredPus::TcPacketStoredPus(uint16_t apid, uint8_t service,
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
this->setData(pData);
|
||||
this->setData(pData, TC_PACKET_MIN_SIZE + size);
|
||||
#if FSFW_USE_PUS_C_TELECOMMANDS == 1
|
||||
pus::PusVersion pusVersion = pus::PusVersion::PUS_C_VERSION;
|
||||
#else
|
||||
@ -39,7 +39,7 @@ TcPacketStoredPus::TcPacketStoredPus(): TcPacketStoredBase(), TcPacketPus(nullpt
|
||||
}
|
||||
|
||||
TcPacketStoredPus::TcPacketStoredPus(store_address_t setAddress): TcPacketPus(nullptr) {
|
||||
TcPacketStoredBase::setStoreAddress(setAddress);
|
||||
TcPacketStoredBase::setStoreAddress(setAddress, this);
|
||||
}
|
||||
|
||||
TcPacketStoredPus::TcPacketStoredPus(const uint8_t* data, size_t size): TcPacketPus(data) {
|
||||
@ -49,23 +49,24 @@ TcPacketStoredPus::TcPacketStoredPus(const uint8_t* data, size_t size): TcPacket
|
||||
if (this->checkAndSetStore()) {
|
||||
ReturnValue_t status = store->addData(&storeAddress, data, size);
|
||||
if (status != HasReturnvaluesIF::RETURN_OK) {
|
||||
this->setData(nullptr);
|
||||
this->setData(nullptr, size);
|
||||
}
|
||||
const uint8_t* storePtr = nullptr;
|
||||
// Repoint base data pointer to the data in the store.
|
||||
store->getData(storeAddress, &storePtr, &size);
|
||||
this->setData(storePtr);
|
||||
this->setData(const_cast<uint8_t*>(storePtr), size);
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t TcPacketStoredPus::deletePacket() {
|
||||
ReturnValue_t result = this->store->deleteData(this->storeAddress);
|
||||
this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
|
||||
this->setData(nullptr);
|
||||
// To circumvent size checks
|
||||
this->setData(nullptr, -1);
|
||||
return result;
|
||||
}
|
||||
|
||||
TcPacketBase* TcPacketStoredPus::getPacketBase() {
|
||||
TcPacketPusBase* TcPacketStoredPus::getPacketBase() {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ public:
|
||||
*/
|
||||
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);
|
||||
size_t size = 0, uint8_t ack = TcPacketPusBase::ACK_ALL);
|
||||
/**
|
||||
* Create stored packet with existing data.
|
||||
* @param data
|
||||
@ -41,7 +41,7 @@ public:
|
||||
TcPacketStoredPus();
|
||||
|
||||
ReturnValue_t deletePacket() override;
|
||||
TcPacketBase* getPacketBase() override;
|
||||
TcPacketPusBase* getPacketBase();
|
||||
|
||||
private:
|
||||
|
||||
|
@ -36,9 +36,13 @@ uint16_t TmPacketPusA::getSourceDataSize() {
|
||||
- CRC_SIZE + 1;
|
||||
}
|
||||
|
||||
void TmPacketPusA::setData(const uint8_t* p_Data) {
|
||||
SpacePacketBase::setData(p_Data);
|
||||
tmData = (TmPacketPointerPusA*) p_Data;
|
||||
ReturnValue_t TmPacketPusA::setData(uint8_t* p_Data, size_t maxSize, void* args) {
|
||||
ReturnValue_t result = SpacePacketBase::setData(p_Data, maxSize);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
tmData = reinterpret_cast<TmPacketPointerPusA*>(const_cast<uint8_t*>(p_Data));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -110,7 +110,8 @@ protected:
|
||||
*
|
||||
* @param p_data A pointer to another PUS Telemetry Packet.
|
||||
*/
|
||||
void setData( const uint8_t* pData );
|
||||
ReturnValue_t setData(uint8_t* pData, size_t maxSize,
|
||||
void* args = nullptr) override;
|
||||
|
||||
/**
|
||||
* In case data was filled manually (almost never the case).
|
||||
|
@ -35,9 +35,16 @@ uint16_t TmPacketPusC::getSourceDataSize() {
|
||||
return getPacketDataLength() - sizeof(tmData->dataField) - CRC_SIZE + 1;
|
||||
}
|
||||
|
||||
void TmPacketPusC::setData(const uint8_t* p_Data) {
|
||||
SpacePacketBase::setData(p_Data);
|
||||
tmData = (TmPacketPointerPusC*) p_Data;
|
||||
ReturnValue_t TmPacketPusC::setData(uint8_t* p_Data, size_t maxSize, void* args) {
|
||||
ReturnValue_t result = SpacePacketBase::setData(p_Data, maxSize);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if(maxSize < sizeof(TmPacketPointerPusC)) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
tmData = reinterpret_cast<TmPacketPointerPusC*>(const_cast<uint8_t*>(p_Data));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -110,9 +110,9 @@ protected:
|
||||
* 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.
|
||||
* @param pData A pointer to another PUS Telemetry Packet.
|
||||
*/
|
||||
void setData( const uint8_t* pData );
|
||||
ReturnValue_t setData(uint8_t* pData, size_t maxSize, void* args = nullptr) override;
|
||||
|
||||
/**
|
||||
* In case data was filled manually (almost never the case).
|
||||
|
@ -27,7 +27,7 @@ store_address_t TmPacketStoredBase::getStoreAddress() {
|
||||
void TmPacketStoredBase::deletePacket() {
|
||||
store->deleteData(storeAddress);
|
||||
storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
|
||||
setDataPointer(nullptr);
|
||||
setData(nullptr, -1);
|
||||
}
|
||||
|
||||
void TmPacketStoredBase::setStoreAddress(store_address_t setAddress) {
|
||||
@ -39,9 +39,9 @@ void TmPacketStoredBase::setStoreAddress(store_address_t setAddress) {
|
||||
}
|
||||
ReturnValue_t status = store->getData(storeAddress, &tempData, &tempSize);
|
||||
if (status == StorageManagerIF::RETURN_OK) {
|
||||
setDataPointer(tempData);
|
||||
setData(const_cast<uint8_t*>(tempData), tempSize);
|
||||
} else {
|
||||
setDataPointer(nullptr);
|
||||
setData(nullptr, -1);
|
||||
storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
* packets in a store with the help of a storeAddress.
|
||||
* @ingroup tmtcpackets
|
||||
*/
|
||||
class TmPacketStoredBase {
|
||||
class TmPacketStoredBase: virtual public RedirectableDataPointerIF {
|
||||
public:
|
||||
/**
|
||||
* This is a default constructor which does not set the data pointer.
|
||||
@ -33,7 +33,6 @@ public:
|
||||
virtual ~TmPacketStoredBase();
|
||||
|
||||
virtual uint8_t* getAllTmData() = 0;
|
||||
virtual void setDataPointer(const uint8_t* newPointer) = 0;
|
||||
|
||||
/**
|
||||
* This is a getter for the current store address of the packet.
|
||||
|
@ -26,7 +26,7 @@ TmPacketStoredPusA::TmPacketStoredPusA(uint16_t apid, uint8_t service,
|
||||
handleStoreFailure("A", returnValue, sizeToReserve);
|
||||
return;
|
||||
}
|
||||
setData(pData);
|
||||
setData(pData, sizeToReserve);
|
||||
initializeTmPacket(apid, service, subservice, packetSubcounter);
|
||||
memcpy(getSourceData(), headerData, headerSize);
|
||||
memcpy(getSourceData() + headerSize, data, size);
|
||||
@ -56,7 +56,7 @@ TmPacketStoredPusA::TmPacketStoredPusA(uint16_t apid, uint8_t service,
|
||||
handleStoreFailure("A", returnValue, sizeToReserve);
|
||||
return;
|
||||
}
|
||||
setData(pData);
|
||||
setData(pData, sizeToReserve);
|
||||
initializeTmPacket(apid, service, subservice, packetSubcounter);
|
||||
uint8_t *putDataHere = getSourceData();
|
||||
size_t size = 0;
|
||||
@ -75,6 +75,6 @@ uint8_t* TmPacketStoredPusA::getAllTmData() {
|
||||
return getWholeData();
|
||||
}
|
||||
|
||||
void TmPacketStoredPusA::setDataPointer(const uint8_t *newPointer) {
|
||||
setData(newPointer);
|
||||
ReturnValue_t TmPacketStoredPusA::setData(uint8_t *newPointer, size_t maxSize, void* args) {
|
||||
return TmPacketPusA::setData(newPointer, maxSize);
|
||||
}
|
||||
|
@ -57,7 +57,17 @@ public:
|
||||
SerializeIF* header = nullptr);
|
||||
|
||||
uint8_t* getAllTmData() override;
|
||||
void setDataPointer(const uint8_t* newPointer) override;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Implementation required by base class
|
||||
* @param newPointer
|
||||
* @param maxSize
|
||||
* @param args
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t setData(uint8_t* newPointer, size_t maxSize, void* args = nullptr) override;
|
||||
|
||||
};
|
||||
|
||||
|
@ -27,7 +27,7 @@ TmPacketStoredPusC::TmPacketStoredPusC(uint16_t apid, uint8_t service,
|
||||
handleStoreFailure("C", returnValue, sizeToReserve);
|
||||
return;
|
||||
}
|
||||
setData(pData);
|
||||
setData(pData, sizeToReserve);
|
||||
initializeTmPacket(apid, service, subservice, packetSubcounter, destinationId, timeRefField);
|
||||
memcpy(getSourceData(), headerData, headerSize);
|
||||
memcpy(getSourceData() + headerSize, data, size);
|
||||
@ -56,7 +56,7 @@ TmPacketStoredPusC::TmPacketStoredPusC(uint16_t apid, uint8_t service,
|
||||
handleStoreFailure("C", returnValue, sizeToReserve);
|
||||
return;
|
||||
}
|
||||
setData(pData);
|
||||
TmPacketPusC::setData(pData, sizeToReserve);
|
||||
initializeTmPacket(apid, service, subservice, packetSubcounter, destinationId, timeRefField);
|
||||
uint8_t *putDataHere = getSourceData();
|
||||
size_t size = 0;
|
||||
@ -76,6 +76,7 @@ uint8_t* TmPacketStoredPusC::getAllTmData() {
|
||||
return getWholeData();
|
||||
}
|
||||
|
||||
void TmPacketStoredPusC::setDataPointer(const uint8_t *newPointer) {
|
||||
setData(newPointer);
|
||||
ReturnValue_t TmPacketStoredPusC::setData(uint8_t *newPointer, size_t maxSize,
|
||||
void* args) {
|
||||
return TmPacketPusC::setData(newPointer, maxSize);
|
||||
}
|
||||
|
@ -59,7 +59,17 @@ public:
|
||||
SerializeIF* header = nullptr, uint16_t destinationId = 0, uint8_t timeRefField = 0);
|
||||
|
||||
uint8_t* getAllTmData() override;
|
||||
void setDataPointer(const uint8_t* newPointer) override;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Implementation required by base class
|
||||
* @param newPointer
|
||||
* @param maxSize
|
||||
* @param args
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t setData(uint8_t* newPointer, size_t maxSize, void* args = nullptr) override;
|
||||
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user