Merge branch 'master' into mueller/unittest-integration-from-master

This commit is contained in:
Steffen Gaisser 2020-10-29 19:59:23 +01:00
commit 51c5b05f03
17 changed files with 536 additions and 375 deletions

View File

@ -3,8 +3,9 @@
#include "../ipc/MessageQueueSenderIF.h" #include "../ipc/MessageQueueSenderIF.h"
#include "../objectmanager/ObjectManagerIF.h" #include "../objectmanager/ObjectManagerIF.h"
ActionHelper::ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue) : ActionHelper::ActionHelper(HasActionsIF* setOwner,
owner(setOwner), queueToUse(useThisQueue), ipcStore(nullptr) { MessageQueueIF* useThisQueue) :
owner(setOwner), queueToUse(useThisQueue) {
} }
ActionHelper::~ActionHelper() { ActionHelper::~ActionHelper() {
@ -33,13 +34,15 @@ ReturnValue_t ActionHelper::initialize(MessageQueueIF* queueToUse_) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
void ActionHelper::step(uint8_t step, MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result) { void ActionHelper::step(uint8_t step, MessageQueueId_t reportTo,
ActionId_t commandId, ReturnValue_t result) {
CommandMessage reply; CommandMessage reply;
ActionMessage::setStepReply(&reply, commandId, step + STEP_OFFSET, result); ActionMessage::setStepReply(&reply, commandId, step + STEP_OFFSET, result);
queueToUse->sendMessage(reportTo, &reply); queueToUse->sendMessage(reportTo, &reply);
} }
void ActionHelper::finish(MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result) { void ActionHelper::finish(MessageQueueId_t reportTo, ActionId_t commandId,
ReturnValue_t result) {
CommandMessage reply; CommandMessage reply;
ActionMessage::setCompletionReply(&reply, commandId, result); ActionMessage::setCompletionReply(&reply, commandId, result);
queueToUse->sendMessage(reportTo, &reply); queueToUse->sendMessage(reportTo, &reply);
@ -49,8 +52,8 @@ void ActionHelper::setQueueToUse(MessageQueueIF* queue) {
queueToUse = queue; queueToUse = queue;
} }
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId, void ActionHelper::prepareExecution(MessageQueueId_t commandedBy,
store_address_t dataAddress) { ActionId_t actionId, store_address_t dataAddress) {
const uint8_t* dataPtr = NULL; const uint8_t* dataPtr = NULL;
size_t size = 0; size_t size = 0;
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size); ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
@ -62,6 +65,11 @@ void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t act
} }
result = owner->executeAction(actionId, commandedBy, dataPtr, size); result = owner->executeAction(actionId, commandedBy, dataPtr, size);
ipcStore->deleteData(dataAddress); ipcStore->deleteData(dataAddress);
if(result == HasActionsIF::EXECUTION_FINISHED) {
CommandMessage reply;
ActionMessage::setCompletionReply(&reply, actionId, result);
queueToUse->sendMessage(commandedBy, &reply);
}
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
CommandMessage reply; CommandMessage reply;
ActionMessage::setStepReply(&reply, actionId, 0, result); ActionMessage::setStepReply(&reply, actionId, 0, result);
@ -86,22 +94,28 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo,
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = data->serialize(&dataPtr, &size, maxSize, SerializeIF::Endianness::BIG); result = data->serialize(&dataPtr, &size, maxSize,
SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
ipcStore->deleteData(storeAddress); ipcStore->deleteData(storeAddress);
return result; return result;
} }
//We don't need to report the objectId, as we receive REQUESTED data before the completion success message. // We don't need to report the objectId, as we receive REQUESTED data
//True aperiodic replies need to be reported with another dedicated message. // before the completion success message.
// True aperiodic replies need to be reported with
// another dedicated message.
ActionMessage::setDataReply(&reply, replyId, storeAddress); ActionMessage::setDataReply(&reply, replyId, storeAddress);
//TODO Service Implementation sucks at the moment // If the sender needs to be hidden, for example to handle packet
if (hideSender){ // as unrequested reply, this will be done here.
if (hideSender) {
result = MessageQueueSenderIF::sendMessage(reportTo, &reply); result = MessageQueueSenderIF::sendMessage(reportTo, &reply);
} else { }
else {
result = queueToUse->sendMessage(reportTo, &reply); result = queueToUse->sendMessage(reportTo, &reply);
} }
if ( result != HasReturnvaluesIF::RETURN_OK){
if (result != HasReturnvaluesIF::RETURN_OK){
ipcStore->deleteData(storeAddress); ipcStore->deleteData(storeAddress);
} }
return result; return result;
@ -109,3 +123,39 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo,
void ActionHelper::resetHelper() { void ActionHelper::resetHelper() {
} }
ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo,
ActionId_t replyId, const uint8_t *data, size_t dataSize,
bool hideSender) {
CommandMessage reply;
store_address_t storeAddress;
ReturnValue_t result = ipcStore->addData(&storeAddress, data, dataSize);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
if (result != HasReturnvaluesIF::RETURN_OK) {
ipcStore->deleteData(storeAddress);
return result;
}
// We don't need to report the objectId, as we receive REQUESTED data
// before the completion success message.
// True aperiodic replies need to be reported with
// another dedicated message.
ActionMessage::setDataReply(&reply, replyId, storeAddress);
// If the sender needs to be hidden, for example to handle packet
// as unrequested reply, this will be done here.
if (hideSender) {
result = MessageQueueSenderIF::sendMessage(reportTo, &reply);
}
else {
result = queueToUse->sendMessage(reportTo, &reply);
}
if (result != HasReturnvaluesIF::RETURN_OK){
ipcStore->deleteData(storeAddress);
}
return result;
}

View File

@ -1,15 +1,18 @@
#ifndef ACTIONHELPER_H_ #ifndef FSFW_ACTION_ACTIONHELPER_H_
#define ACTIONHELPER_H_ #define FSFW_ACTION_ACTIONHELPER_H_
#include "ActionMessage.h" #include "ActionMessage.h"
#include "../serialize/SerializeIF.h" #include "../serialize/SerializeIF.h"
#include "../ipc/MessageQueueIF.h" #include "../ipc/MessageQueueIF.h"
/** /**
* \brief Action Helper is a helper class which handles action messages * @brief Action Helper is a helper class which handles action messages
* *
* Components which use the HasActionIF this helper can be used to handle the action messages. * Components which use the HasActionIF this helper can be used to handle
* It does handle step messages as well as other answers to action calls. It uses the executeAction function * the action messages.
* of its owner as callback. The call of the initialize function is mandatory and it needs a valid messageQueueIF pointer! * It does handle step messages as well as other answers to action calls.
* It uses the executeAction function of its owner as callback.
* The call of the initialize function is mandatory and needs a
* valid MessageQueueIF pointer!
*/ */
class HasActionsIF; class HasActionsIF;
@ -18,7 +21,8 @@ public:
/** /**
* Constructor of the action helper * Constructor of the action helper
* @param setOwner Pointer to the owner of the interface * @param setOwner Pointer to the owner of the interface
* @param useThisQueue messageQueue to be used, can be set during initialize function as well. * @param useThisQueue messageQueue to be used, can be set during
* initialize function as well.
*/ */
ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue); ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
@ -26,28 +30,36 @@ public:
/** /**
* Function to be called from the owner with a new command message * Function to be called from the owner with a new command message
* *
* If the message is a valid action message the helper will use the executeAction function from HasActionsIF. * If the message is a valid action message the helper will use the
* If the message is invalid or the callback fails a message reply will be send to the sender of the message automatically. * executeAction function from HasActionsIF.
* If the message is invalid or the callback fails a message reply will be
* send to the sender of the message automatically.
* *
* @param command Pointer to a command message received by the owner * @param command Pointer to a command message received by the owner
* @return HasReturnvaluesIF::RETURN_OK if the message is a action message, CommandMessage::UNKNOW_COMMAND if this message ID is unkown * @return HasReturnvaluesIF::RETURN_OK if the message is a action message,
* CommandMessage::UNKNOW_COMMAND if this message ID is unkown
*/ */
ReturnValue_t handleActionMessage(CommandMessage* command); ReturnValue_t handleActionMessage(CommandMessage* command);
/** /**
* Helper initialize function. Must be called before use of any other helper function * Helper initialize function. Must be called before use of any other
* @param queueToUse_ Pointer to the messageQueue to be used, optional if queue was set in constructor * helper function
* @param queueToUse_ Pointer to the messageQueue to be used, optional
* if queue was set in constructor
* @return Returns RETURN_OK if successful * @return Returns RETURN_OK if successful
*/ */
ReturnValue_t initialize(MessageQueueIF* queueToUse_ = nullptr); ReturnValue_t initialize(MessageQueueIF* queueToUse_ = nullptr);
/** /**
* Function to be called from the owner to send a step message. Success or failure will be determined by the result value. * Function to be called from the owner to send a step message.
* Success or failure will be determined by the result value.
* *
* @param step Number of steps already done * @param step Number of steps already done
* @param reportTo The messageQueueId to report the step message to * @param reportTo The messageQueueId to report the step message to
* @param commandId ID of the executed command * @param commandId ID of the executed command
* @param result Result of the execution * @param result Result of the execution
*/ */
void step(uint8_t step, MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result = HasReturnvaluesIF::RETURN_OK); void step(uint8_t step, MessageQueueId_t reportTo,
ActionId_t commandId,
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
/** /**
* Function to be called by the owner to send a action completion message * Function to be called by the owner to send a action completion message
* *
@ -55,39 +67,59 @@ public:
* @param commandId ID of the executed command * @param commandId ID of the executed command
* @param result Result of the execution * @param result Result of the execution
*/ */
void finish(MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result = HasReturnvaluesIF::RETURN_OK); void finish(MessageQueueId_t reportTo, ActionId_t commandId,
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
/** /**
* Function to be called by the owner if an action does report data * Function to be called by the owner if an action does report data.
* * Takes a SerializeIF* pointer and serializes it into the IPC store.
* @param reportTo MessageQueueId_t to report the action completion message to * @param reportTo MessageQueueId_t to report the action completion
* message to
* @param replyId ID of the executed command * @param replyId ID of the executed command
* @param data Pointer to the data * @param data Pointer to the data
* @return Returns RETURN_OK if successful, otherwise failure code * @return Returns RETURN_OK if successful, otherwise failure code
*/ */
ReturnValue_t reportData(MessageQueueId_t reportTo, ActionId_t replyId, SerializeIF* data, bool hideSender = false); ReturnValue_t reportData(MessageQueueId_t reportTo, ActionId_t replyId,
SerializeIF* data, bool hideSender = false);
/**
* Function to be called by the owner if an action does report data.
* Takes the raw data and writes it into the IPC store.
* @param reportTo MessageQueueId_t to report the action completion
* message to
* @param replyId ID of the executed command
* @param data Pointer to the data
* @return Returns RETURN_OK if successful, otherwise failure code
*/
ReturnValue_t reportData(MessageQueueId_t reportTo, ActionId_t replyId,
const uint8_t* data, size_t dataSize, bool hideSender = false);
/** /**
* Function to setup the MessageQueueIF* of the helper. Can be used to set the messageQueueIF* if * Function to setup the MessageQueueIF* of the helper. Can be used to
* message queue is unavailable at construction and initialize but must be setup before first call of other functions. * set the MessageQueueIF* if message queue is unavailable at construction
* and initialize but must be setup before first call of other functions.
* @param queue Queue to be used by the helper * @param queue Queue to be used by the helper
*/ */
void setQueueToUse(MessageQueueIF *queue); void setQueueToUse(MessageQueueIF *queue);
protected: protected:
static const uint8_t STEP_OFFSET = 1;//!< Increase of value of this per step //!< Increase of value of this per step
static const uint8_t STEP_OFFSET = 1;
HasActionsIF* owner;//!< Pointer to the owner HasActionsIF* owner;//!< Pointer to the owner
MessageQueueIF* queueToUse;//!< Queue to be used as response sender, has to be set with //! Queue to be used as response sender, has to be set in ctor or with
StorageManagerIF* ipcStore;//!< Pointer to an IPC Store, initialized during construction or initialize(MessageQueueIF* queueToUse_) or with setQueueToUse(MessageQueueIF *queue) //! setQueueToUse
MessageQueueIF* queueToUse;
//! Pointer to an IPC Store, initialized during construction or
StorageManagerIF* ipcStore = nullptr;
/** /**
*Internal function called by handleActionMessage(CommandMessage* command) * Internal function called by handleActionMessage
*
* @param commandedBy MessageQueueID of Commander * @param commandedBy MessageQueueID of Commander
* @param actionId ID of action to be done * @param actionId ID of action to be done
* @param dataAddress Address of additional data in IPC Store * @param dataAddress Address of additional data in IPC Store
*/ */
virtual void prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId, store_address_t dataAddress); virtual void prepareExecution(MessageQueueId_t commandedBy,
ActionId_t actionId, store_address_t dataAddress);
/** /**
* * @brief Default implementation is empty.
*/ */
virtual void resetHelper(); virtual void resetHelper();
}; };
#endif /* ACTIONHELPER_H_ */ #endif /* FSFW_ACTION_ACTIONHELPER_H_ */

View File

@ -1,11 +1,12 @@
#ifndef FRAMEWORK_ACTION_HASACTIONSIF_H_ #ifndef FSFW_ACTION_HASACTIONSIF_H_
#define FRAMEWORK_ACTION_HASACTIONSIF_H_ #define FSFW_ACTION_HASACTIONSIF_H_
#include "ActionHelper.h" #include "ActionHelper.h"
#include "ActionMessage.h" #include "ActionMessage.h"
#include "SimpleActionHelper.h" #include "SimpleActionHelper.h"
#include "../returnvalues/HasReturnvaluesIF.h" #include "../returnvalues/HasReturnvaluesIF.h"
#include "../ipc/MessageQueueIF.h" #include "../ipc/MessageQueueIF.h"
/** /**
* @brief * @brief
* Interface for component which uses actions * Interface for component which uses actions
@ -47,14 +48,16 @@ public:
virtual MessageQueueId_t getCommandQueue() const = 0; virtual MessageQueueId_t getCommandQueue() const = 0;
/** /**
* Execute or initialize the execution of a certain function. * Execute or initialize the execution of a certain function.
* Returning #EXECUTION_FINISHED or a failure code, nothing else needs to * The ActionHelpers will execute this function and behave differently
* be done. When needing more steps, return RETURN_OK and issue steps and * depending on the returnvalue.
* completion manually. *
* One "step failed" or completion report must be issued! * @return
* -@c EXECUTION_FINISHED Finish reply will be generated
* -@c Not RETURN_OK Step failure reply will be generated
*/ */
virtual ReturnValue_t executeAction(ActionId_t actionId, virtual ReturnValue_t executeAction(ActionId_t actionId,
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) = 0; MessageQueueId_t commandedBy, const uint8_t* data, size_t size) = 0;
}; };
#endif /* FRAMEWORK_ACTION_HASACTIONSIF_H_ */ #endif /* FSFW_ACTION_HASACTIONSIF_H_ */

View File

@ -1,16 +1,17 @@
#include "HasActionsIF.h" #include "HasActionsIF.h"
#include "SimpleActionHelper.h" #include "SimpleActionHelper.h"
SimpleActionHelper::SimpleActionHelper(HasActionsIF* setOwner, SimpleActionHelper::SimpleActionHelper(HasActionsIF* setOwner,
MessageQueueIF* useThisQueue) : MessageQueueIF* useThisQueue) :
ActionHelper(setOwner, useThisQueue), isExecuting(false), lastCommander( ActionHelper(setOwner, useThisQueue), isExecuting(false) {
0), lastAction(0), stepCount(0) {
} }
SimpleActionHelper::~SimpleActionHelper() { SimpleActionHelper::~SimpleActionHelper() {
} }
void SimpleActionHelper::step(ReturnValue_t result) { void SimpleActionHelper::step(ReturnValue_t result) {
//STEP_OFFESET is subtracted to compensate for adding offset in base method, which is not necessary here. // STEP_OFFESET is subtracted to compensate for adding offset in base
// method, which is not necessary here.
ActionHelper::step(stepCount - STEP_OFFSET, lastCommander, lastAction, ActionHelper::step(stepCount - STEP_OFFSET, lastCommander, lastAction,
result); result);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {

View File

@ -1,8 +1,13 @@
#ifndef SIMPLEACTIONHELPER_H_ #ifndef FSFW_ACTION_SIMPLEACTIONHELPER_H_
#define SIMPLEACTIONHELPER_H_ #define FSFW_ACTION_SIMPLEACTIONHELPER_H_
#include "ActionHelper.h" #include "ActionHelper.h"
/**
* @brief This is an action helper which is only able to service one action
* at a time but remembers last commander and last action which
* simplifies usage
*/
class SimpleActionHelper: public ActionHelper { class SimpleActionHelper: public ActionHelper {
public: public:
SimpleActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue); SimpleActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
@ -12,13 +17,14 @@ public:
ReturnValue_t reportData(SerializeIF* data); ReturnValue_t reportData(SerializeIF* data);
protected: protected:
void prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId, store_address_t dataAddress); void prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
virtual void resetHelper(); store_address_t dataAddress);
virtual void resetHelper();
private: private:
bool isExecuting; bool isExecuting;
MessageQueueId_t lastCommander; MessageQueueId_t lastCommander = MessageQueueIF::NO_QUEUE;
ActionId_t lastAction; ActionId_t lastAction = 0;
uint8_t stepCount; uint8_t stepCount = 0;
}; };
#endif /* SIMPLEACTIONHELPER_H_ */ #endif /* SIMPLEACTIONHELPER_H_ */

View File

@ -14,8 +14,12 @@ public:
static const uint8_t INTERFACE_ID = CLASS_ID::TIME_STAMPER_IF; static const uint8_t INTERFACE_ID = CLASS_ID::TIME_STAMPER_IF;
static const ReturnValue_t BAD_TIMESTAMP = MAKE_RETURN_CODE(1); 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. //! This is a mission-specific constant and determines the total
virtual ReturnValue_t addTimeStamp(uint8_t* buffer, const uint8_t maxSize) = 0; //! 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() {} virtual ~TimeStamperIF() {}
}; };

View File

@ -1,6 +1,6 @@
#include "../serviceinterface/ServiceInterfaceStream.h"
#include "SpacePacketBase.h" #include "SpacePacketBase.h"
#include <string.h> #include "../serviceinterface/ServiceInterfaceStream.h"
#include <cstring>
SpacePacketBase::SpacePacketBase( const uint8_t* set_address ) { SpacePacketBase::SpacePacketBase( const uint8_t* set_address ) {
this->data = (SpacePacketPointer*) 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; 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: //reset header to zero:
memset(data,0, sizeof(this->data->header) ); memset(data,0, sizeof(this->data->header) );
//Set TC/TM bit. //Set TC/TM bit.
@ -81,7 +82,7 @@ void SpacePacketBase::setPacketDataLength( uint16_t new_length) {
this->data->header.packet_length_l = ( new_length & 0x00FF ); 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 //+1 is done because size in packet data length field is: size of data field -1
return this->getPacketDataLength() + sizeof(this->data->header) + 1; return this->getPacketDataLength() + sizeof(this->data->header) + 1;
} }

View File

@ -1,10 +1,11 @@
#ifndef SPACEPACKETBASE_H_ #ifndef FSFW_TMTCPACKET_SPACEPACKETBASE_H_
#define SPACEPACKETBASE_H_ #define FSFW_TMTCPACKET_SPACEPACKETBASE_H_
#include "ccsds_header.h" #include "ccsds_header.h"
#include <cstddef>
/** /**
* \defgroup tmtcpackets Space Packets * @defgroup tmtcpackets Space Packets
* This is the group, where all classes associated with Telecommand and * This is the group, where all classes associated with Telecommand and
* Telemetry packets belong to. * Telemetry packets belong to.
* The class hierarchy resembles the dependency between the different standards * The class hierarchy resembles the dependency between the different standards
@ -81,7 +82,8 @@ public:
*/ */
bool isTelecommand( void ); 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), * The CCSDS header provides a secondary header flag (the fifth-highest bit),
* which is checked with this method. * which is checked with this method.
@ -167,10 +169,10 @@ public:
* This method returns the full raw packet size. * This method returns the full raw packet size.
* @return The full size of the packet in bytes. * @return The full size of the packet in bytes.
*/ */
uint32_t getFullSize(); size_t getFullSize();
uint32_t getApidAndSequenceCount() const; uint32_t getApidAndSequenceCount() const;
}; };
#endif /* SPACEPACKETBASE_H_ */ #endif /* FSFW_TMTCPACKET_SPACEPACKETBASE_H_ */

View File

@ -7,7 +7,8 @@ class TmPacketMinimal;
class PacketTimestampInterpreterIF { class PacketTimestampInterpreterIF {
public: public:
virtual ~PacketTimestampInterpreterIF() {} 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; virtual ReturnValue_t getPacketTimeRaw(TmPacketMinimal* packet, const uint8_t** timePtr, uint32_t* size) const = 0;
}; };

View File

@ -1,11 +1,14 @@
#include "../../globalfunctions/CRC.h"
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include "TcPacketBase.h" #include "TcPacketBase.h"
#include <string.h>
TcPacketBase::TcPacketBase(const uint8_t* set_data) : #include "../../globalfunctions/CRC.h"
SpacePacketBase(set_data) { #include "../../globalfunctions/arrayprinter.h"
tcData = (TcPacketPointer*) set_data; #include "../../serviceinterface/ServiceInterfaceStream.h"
#include <cstring>
TcPacketBase::TcPacketBase(const uint8_t* setData) :
SpacePacketBase(setData) {
tcData = reinterpret_cast<TcPacketPointer*>(const_cast<uint8_t*>(setData));
} }
TcPacketBase::~TcPacketBase() { TcPacketBase::~TcPacketBase() {
@ -13,28 +16,28 @@ TcPacketBase::~TcPacketBase() {
} }
uint8_t TcPacketBase::getService() { uint8_t TcPacketBase::getService() {
return tcData->data_field.service_type; return tcData->dataField.service_type;
} }
uint8_t TcPacketBase::getSubService() { uint8_t TcPacketBase::getSubService() {
return tcData->data_field.service_subtype; return tcData->dataField.service_subtype;
} }
uint8_t TcPacketBase::getAcknowledgeFlags() { 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 { const uint8_t* TcPacketBase::getApplicationData() const {
return &tcData->data; return &tcData->appData;
} }
uint16_t TcPacketBase::getApplicationDataSize() { 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 TcPacketBase::getErrorControl() {
uint16_t size = getApplicationDataSize() + CRC_SIZE; 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]; return (p_to_buffer[size - 2] << 8) + p_to_buffer[size - 1];
} }
@ -42,41 +45,42 @@ void TcPacketBase::setErrorControl() {
uint32_t full_size = getFullSize(); uint32_t full_size = getFullSize();
uint16_t crc = CRC::crc16ccitt(getWholeData(), full_size - CRC_SIZE); uint16_t crc = CRC::crc16ccitt(getWholeData(), full_size - CRC_SIZE);
uint32_t size = getApplicationDataSize(); uint32_t size = getApplicationDataSize();
(&tcData->data)[size] = (crc & 0XFF00) >> 8; // CRCH (&tcData->appData)[size] = (crc & 0XFF00) >> 8; // CRCH
(&tcData->data)[size + 1] = (crc) & 0X00FF; // CRCL (&tcData->appData)[size + 1] = (crc) & 0X00FF; // CRCL
} }
void TcPacketBase::setData(const uint8_t* p_Data) { void TcPacketBase::setData(const uint8_t* pData) {
SpacePacketBase::setData(p_Data); SpacePacketBase::setData(pData);
tcData = (TcPacketPointer*) p_Data; tcData = (TcPacketPointer*) pData;
} }
uint8_t TcPacketBase::getSecondaryHeaderFlag() { 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() { uint8_t TcPacketBase::getPusVersionNumber() {
return (tcData->data_field.version_type_ack & 0b01110000) >> 4; return (tcData->dataField.version_type_ack & 0b01110000) >> 4;
} }
void TcPacketBase::print() { void TcPacketBase::print() {
uint8_t * wholeData = getWholeData(); sif::debug << "TcPacketBase::print: " << std::endl;
sif::debug << "TcPacket contains: " << std::endl; arrayprinter::print(getWholeData(), getFullSize());
for (uint8_t count = 0; count < getFullSize(); ++count) {
sif::debug << std::hex << (uint16_t) wholeData[count] << " ";
}
sif::debug << std::dec << std::endl;
} }
void TcPacketBase::initializeTcPacket(uint16_t apid, uint16_t sequenceCount, 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); initSpacePacketHeader(true, true, apid, sequenceCount);
memset(&tcData->data_field, 0, sizeof(tcData->data_field)); std::memset(&tcData->dataField, 0, sizeof(tcData->dataField));
setPacketDataLength(sizeof(tcData->data_field) + CRC_SIZE); setPacketDataLength(sizeof(PUSTcDataFieldHeader) + CRC_SIZE - 1);
//Data Field Header: //Data Field Header:
//Set CCSDS_secondary_header_flag to 0, version number to 001 and ack to 0000 //Set CCSDS_secondary_header_flag to 0 and version number to 001
tcData->data_field.version_type_ack = 0b00010000; tcData->dataField.version_type_ack = 0b00010000;
tcData->data_field.version_type_ack |= (ack & 0x0F); tcData->dataField.version_type_ack |= (ack & 0x0F);
tcData->data_field.service_type = service; tcData->dataField.service_type = service;
tcData->data_field.service_subtype = subservice; tcData->dataField.service_subtype = subservice;
}
size_t TcPacketBase::calculateFullPacketLength(size_t appDataLen) {
return sizeof(CCSDSPrimaryHeader) + sizeof(PUSTcDataFieldHeader) +
appDataLen + TcPacketBase::CRC_SIZE;
} }

View File

@ -1,7 +1,9 @@
#ifndef TCPACKETBASE_H_ #ifndef TMTCPACKET_PUS_TCPACKETBASE_H_
#define TCPACKETBASE_H_ #define TMTCPACKET_PUS_TCPACKETBASE_H_
#include "../../tmtcpacket/SpacePacketBase.h" #include "../../tmtcpacket/SpacePacketBase.h"
#include <cstddef>
/** /**
* This struct defines a byte-wise structured PUS TC Data Field Header. * This struct defines a byte-wise structured PUS TC Data Field Header.
@ -23,14 +25,14 @@ struct PUSTcDataFieldHeader {
*/ */
struct TcPacketPointer { struct TcPacketPointer {
CCSDSPrimaryHeader primary; CCSDSPrimaryHeader primary;
PUSTcDataFieldHeader data_field; PUSTcDataFieldHeader dataField;
uint8_t data; uint8_t appData;
}; };
/** /**
* This class is the basic data handler for any ECSS PUS Telecommand packet. * 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. * the standardized entries of the PUS TC Packet Data Field Header.
* It does not contain the packet data itself but a pointer to the * It does not contain the packet data itself but a pointer to the
* data must be set on instantiation. An invalid pointer may cause * data must be set on instantiation. An invalid pointer may cause
@ -39,67 +41,38 @@ struct TcPacketPointer {
* @ingroup tmtcpackets * @ingroup tmtcpackets
*/ */
class TcPacketBase : public SpacePacketBase { 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: public:
static const uint16_t TC_PACKET_MIN_SIZE = (sizeof(CCSDSPrimaryHeader) + sizeof(PUSTcDataFieldHeader) + 2); 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.
*/ enum AckField {
static const uint8_t ACK_ALL = 0b1111; //! No acknowledgements are expected.
/** ACK_NONE = 0b0000,
* With this constant for the acknowledge field a response on acceptance is expected. //! Acknowledgements on acceptance are expected.
*/ ACK_ACCEPTANCE = 0b0001,
static const uint8_t ACK_ACCEPTANCE = 0b0001; //! Acknowledgements on start are expected.
/** ACK_START = 0b0010,
* With this constant for the acknowledge field a response on start of execution is expected. //! Acknowledgements on step are expected.
*/ ACK_STEP = 0b0100,
static const uint8_t ACK_START = 0b0010; //! Acknowledfgement on completion are expected.
/** ACK_COMPLETION = 0b1000
* With this constant for the acknowledge field responses on execution steps are expected. };
*/
static const uint8_t ACK_STEP = 0b0100; static constexpr uint8_t ACK_ALL = ACK_ACCEPTANCE | ACK_START | ACK_STEP |
/** ACK_COMPLETION;
* 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;
/** /**
* This is the default constructor. * This is the default constructor.
* It sets its internal data pointer to the address passed and also * It sets its internal data pointer to the address passed and also
* forwards the data pointer to the parent SpacePacketBase class. * 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. * This is the empty default destructor.
*/ */
virtual ~TcPacketBase(); 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. * This command returns the CCSDS Secondary Header Flag.
* It shall always be zero for PUS Packets. This is the * It shall always be zero for PUS Packets. This is the
@ -166,22 +139,49 @@ public:
* current content of the packet. * current content of the packet.
*/ */
void setErrorControl(); 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 * This is a debugging helper method that prints the whole packet content
* to the screen. * to the screen.
*/ */
void print(); 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_ */

View File

@ -1,37 +1,50 @@
#include "TcPacketStored.h"
#include "../../objectmanager/ObjectManagerIF.h" #include "../../objectmanager/ObjectManagerIF.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
#include "TcPacketStored.h"
#include <string.h> #include <cstring>
StorageManagerIF* TcPacketStored::store = nullptr;
TcPacketStored::TcPacketStored(store_address_t setAddress) : TcPacketStored::TcPacketStored(store_address_t setAddress) :
TcPacketBase(NULL), storeAddress(setAddress) { TcPacketBase(nullptr), storeAddress(setAddress) {
this->setStoreAddress(this->storeAddress); setStoreAddress(storeAddress);
} }
TcPacketStored::TcPacketStored(uint16_t apid, uint8_t ack, uint8_t service, TcPacketStored::TcPacketStored(uint16_t apid, uint8_t service,
uint8_t subservice, uint8_t sequence_count, const uint8_t* data, uint8_t subservice, uint8_t sequenceCount, const uint8_t* data,
uint32_t size) : size_t size, uint8_t ack) :
TcPacketBase(NULL) { TcPacketBase(nullptr) {
this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
if (!this->checkAndSetStore()) { if (not this->checkAndSetStore()) {
return; return;
} }
uint8_t* p_data = NULL; uint8_t* pData = nullptr;
ReturnValue_t returnValue = this->store->getFreeElement(&this->storeAddress, 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) { if (returnValue != this->store->RETURN_OK) {
sif::warning << "TcPacketStored: Could not get free element from store!"
<< std::endl;
return; return;
} }
this->setData(p_data); this->setData(pData);
initializeTcPacket(apid, sequence_count, ack, service, subservice); initializeTcPacket(apid, sequenceCount, ack, service, subservice);
memcpy(&tcData->data, data, size); memcpy(&tcData->appData, data, size);
this->setPacketDataLength( this->setPacketDataLength(
size + sizeof(PUSTcDataFieldHeader) + CRC_SIZE - 1); size + sizeof(PUSTcDataFieldHeader) + CRC_SIZE - 1);
this->setErrorControl(); this->setErrorControl();
} }
TcPacketStored::TcPacketStored() : ReturnValue_t TcPacketStored::getData(const uint8_t ** dataPtr,
TcPacketBase(NULL) { 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->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
this->checkAndSetStore(); this->checkAndSetStore();
@ -40,14 +53,14 @@ TcPacketStored::TcPacketStored() :
ReturnValue_t TcPacketStored::deletePacket() { ReturnValue_t TcPacketStored::deletePacket() {
ReturnValue_t result = this->store->deleteData(this->storeAddress); ReturnValue_t result = this->store->deleteData(this->storeAddress);
this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
this->setData( NULL); this->setData(nullptr);
return result; return result;
} }
bool TcPacketStored::checkAndSetStore() { bool TcPacketStored::checkAndSetStore() {
if (this->store == NULL) { if (this->store == nullptr) {
this->store = objectManager->get<StorageManagerIF>(objects::TC_STORE); this->store = objectManager->get<StorageManagerIF>(objects::TC_STORE);
if (this->store == NULL) { if (this->store == nullptr) {
sif::error << "TcPacketStored::TcPacketStored: TC Store not found!" sif::error << "TcPacketStored::TcPacketStored: TC Store not found!"
<< std::endl; << std::endl;
return false; return false;
@ -58,17 +71,17 @@ bool TcPacketStored::checkAndSetStore() {
void TcPacketStored::setStoreAddress(store_address_t setAddress) { void TcPacketStored::setStoreAddress(store_address_t setAddress) {
this->storeAddress = setAddress; this->storeAddress = setAddress;
const uint8_t* temp_data = NULL; const uint8_t* tempData = nullptr;
size_t temp_size; size_t temp_size;
ReturnValue_t status = StorageManagerIF::RETURN_FAILED; ReturnValue_t status = StorageManagerIF::RETURN_FAILED;
if (this->checkAndSetStore()) { if (this->checkAndSetStore()) {
status = this->store->getData(this->storeAddress, &temp_data, status = this->store->getData(this->storeAddress, &tempData,
&temp_size); &temp_size);
} }
if (status == StorageManagerIF::RETURN_OK) { if (status == StorageManagerIF::RETURN_OK) {
this->setData(temp_data); this->setData(tempData);
} else { } else {
this->setData(NULL); this->setData(nullptr);
this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
} }
} }
@ -78,7 +91,7 @@ store_address_t TcPacketStored::getStoreAddress() {
} }
bool TcPacketStored::isSizeCorrect() { bool TcPacketStored::isSizeCorrect() {
const uint8_t* temp_data = NULL; const uint8_t* temp_data = nullptr;
size_t temp_size; size_t temp_size;
ReturnValue_t status = this->store->getData(this->storeAddress, &temp_data, ReturnValue_t status = this->store->getData(this->storeAddress, &temp_data,
&temp_size); &temp_size);
@ -90,8 +103,6 @@ bool TcPacketStored::isSizeCorrect() {
return false; return false;
} }
StorageManagerIF* TcPacketStored::store = NULL;
TcPacketStored::TcPacketStored(const uint8_t* data, uint32_t size) : TcPacketStored::TcPacketStored(const uint8_t* data, uint32_t size) :
TcPacketBase(data) { TcPacketBase(data) {
if (getFullSize() != size) { if (getFullSize() != size) {
@ -100,7 +111,7 @@ TcPacketStored::TcPacketStored(const uint8_t* data, uint32_t size) :
if (this->checkAndSetStore()) { if (this->checkAndSetStore()) {
ReturnValue_t status = store->addData(&storeAddress, data, size); ReturnValue_t status = store->addData(&storeAddress, data, size);
if (status != HasReturnvaluesIF::RETURN_OK) { if (status != HasReturnvaluesIF::RETURN_OK) {
this->setData(NULL); this->setData(nullptr);
} }
} }
} }

View File

@ -1,8 +1,8 @@
#ifndef TCPACKETSTORED_H_ #ifndef TMTCPACKET_PUS_TCPACKETSTORED_H_
#define TCPACKETSTORED_H_ #define TMTCPACKET_PUS_TCPACKETSTORED_H_
#include "../../storagemanager/StorageManagerIF.h"
#include "TcPacketBase.h" #include "TcPacketBase.h"
#include "../../storagemanager/StorageManagerIF.h"
/** /**
* This class generates a ECSS PUS Telecommand packet within a given * This class generates a ECSS PUS Telecommand packet within a given
@ -15,26 +15,6 @@
* @ingroup tmtcpackets * @ingroup tmtcpackets
*/ */
class TcPacketStored : public TcPacketBase { 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: public:
/** /**
* This is a default constructor which does not set the data pointer. * 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. * a new PUS Telecommand Packet is created there.
* Packet Application Data passed in data is copied into the packet. * Packet Application Data passed in data is copied into the packet.
* @param apid Sets the packet's APID field. * @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. * @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. * @param subservice Sets the packet's Service Subtype field.
* This specifies the destination sub-service. * This specifies the destination sub-service.
* @param sequence_count Sets the packet's Source Sequence Count field. * @param sequence_count Sets the packet's Source Sequence Count field.
* @param data The data to be copied to the Application Data Field. * @param data The data to be copied to the Application Data Field.
* @param size The amount of data to be copied. * @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. * Another constructor to create a TcPacket from a raw packet stream.
* Takes the data and adds it unchecked to the TcStore. * Takes the data and adds it unchecked to the TcStore.
@ -72,10 +54,19 @@ public:
* @param Size size of the packet. * @param Size size of the packet.
*/ */
TcPacketStored( const uint8_t* data, uint32_t size); 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. * 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
* the packet is not linked. * @c StorageManagerIF::INVALID_ADDRESS if the packet is not linked.
*/ */
store_address_t getStoreAddress(); store_address_t getStoreAddress();
/** /**
@ -99,7 +90,28 @@ public:
* store or size is incorrect. * store or size is incorrect.
*/ */
bool isSizeCorrect(); 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_ */

View File

@ -1,13 +1,19 @@
#include "TmPacketBase.h"
#include "../../globalfunctions/CRC.h" #include "../../globalfunctions/CRC.h"
#include "../../globalfunctions/arrayprinter.h"
#include "../../objectmanager/ObjectManagerIF.h" #include "../../objectmanager/ObjectManagerIF.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
#include "TmPacketBase.h"
#include "../../timemanager/CCSDSTime.h" #include "../../timemanager/CCSDSTime.h"
#include <string.h>
TmPacketBase::TmPacketBase(uint8_t* set_data) : #include <cstring>
SpacePacketBase(set_data) {
tm_data = (TmPacketPointer*) set_data; TimeStamperIF* TmPacketBase::timeStamper = nullptr;
object_id_t TmPacketBase::timeStamperId = 0;
TmPacketBase::TmPacketBase(uint8_t* setData) :
SpacePacketBase(setData) {
tmData = reinterpret_cast<TmPacketPointer*>(setData);
} }
TmPacketBase::~TmPacketBase() { TmPacketBase::~TmPacketBase() {
@ -15,25 +21,25 @@ TmPacketBase::~TmPacketBase() {
} }
uint8_t TmPacketBase::getService() { uint8_t TmPacketBase::getService() {
return tm_data->data_field.service_type; return tmData->data_field.service_type;
} }
uint8_t TmPacketBase::getSubService() { uint8_t TmPacketBase::getSubService() {
return tm_data->data_field.service_subtype; return tmData->data_field.service_subtype;
} }
uint8_t* TmPacketBase::getSourceData() { uint8_t* TmPacketBase::getSourceData() {
return &tm_data->data; return &tmData->data;
} }
uint16_t TmPacketBase::getSourceDataSize() { uint16_t TmPacketBase::getSourceDataSize() {
return getPacketDataLength() - sizeof(tm_data->data_field) return getPacketDataLength() - sizeof(tmData->data_field)
- CRC_SIZE + 1; - CRC_SIZE + 1;
} }
uint16_t TmPacketBase::getErrorControl() { uint16_t TmPacketBase::getErrorControl() {
uint32_t size = getSourceDataSize() + CRC_SIZE; 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]; 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) { void TmPacketBase::setData(const uint8_t* p_Data) {
SpacePacketBase::setData(p_Data); SpacePacketBase::setData(p_Data);
tm_data = (TmPacketPointer*) p_Data; tmData = (TmPacketPointer*) p_Data;
} }
void TmPacketBase::print() { void TmPacketBase::print() {
/*uint8_t * wholeData = getWholeData(); sif::debug << "TmPacketBase::print: " << std::endl;
debug << "TmPacket contains: " << std::endl; arrayprinter::print(getWholeData(), getFullSize());
for (uint8_t count = 0; count < getFullSize(); ++count ) {
debug << std::hex << (uint16_t)wholeData[count] << " ";
}
debug << std::dec << std::endl;*/
} }
bool TmPacketBase::checkAndSetStamper() { bool TmPacketBase::checkAndSetStamper() {
@ -73,32 +75,36 @@ bool TmPacketBase::checkAndSetStamper() {
ReturnValue_t TmPacketBase::getPacketTime(timeval* timestamp) const { ReturnValue_t TmPacketBase::getPacketTime(timeval* timestamp) const {
uint32_t tempSize = 0; uint32_t tempSize = 0;
return CCSDSTime::convertFromCcsds(timestamp, tm_data->data_field.time, return CCSDSTime::convertFromCcsds(timestamp, tmData->data_field.time,
&tempSize, sizeof(tm_data->data_field.time)); &tempSize, sizeof(tmData->data_field.time));
} }
uint8_t* TmPacketBase::getPacketTimeRaw() const{ 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: //Set primary header:
initSpacePacketHeader(false, true, apid); initSpacePacketHeader(false, true, apid);
//Set data Field Header: //Set data Field Header:
//First, set to zero. //First, set to zero.
memset(&tm_data->data_field, 0, sizeof(tm_data->data_field)); memset(&tmData->data_field, 0, sizeof(tmData->data_field));
//Set CCSDS_secondary header flag to 0, version number to 001 and ack to 0000
// NOTE: In PUS-C, the PUS Version is 2 and specified for the first 4 bits. // 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 // The other 4 bits of the first byte are the spacecraft time reference
// To change to PUS-C, set 0b00100000 // status. To change to PUS-C, set 0b00100000.
tm_data->data_field.version_type_ack = 0b00010000; // Set CCSDS_secondary header flag to 0, version number to 001 and ack
tm_data->data_field.service_type = service; // to 0000
tm_data->data_field.service_subtype = subservice; tmData->data_field.version_type_ack = 0b00010000;
tm_data->data_field.subcounter = packetSubcounter; tmData->data_field.service_type = service;
tmData->data_field.service_subtype = subservice;
tmData->data_field.subcounter = packetSubcounter;
//Timestamp packet //Timestamp packet
if (checkAndSetStamper()) { 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); setPacketDataLength(size + sizeof(PUSTmDataFieldHeader) + CRC_SIZE - 1);
} }
uint32_t TmPacketBase::getTimestampSize() const { size_t TmPacketBase::getTimestampSize() const {
return sizeof(tm_data->data_field.time); return sizeof(tmData->data_field.time);
} }
TimeStamperIF* TmPacketBase::timeStamper = NULL;
object_id_t TmPacketBase::timeStamperId = 0;

View File

@ -1,8 +1,8 @@
#ifndef TMPACKETBASE_H_ #ifndef TMTCPACKET_PUS_TMPACKETBASE_H_
#define TMPACKETBASE_H_ #define TMTCPACKET_PUS_TMPACKETBASE_H_
#include "../SpacePacketBase.h"
#include "../../timemanager/TimeStamperIF.h" #include "../../timemanager/TimeStamperIF.h"
#include "../../tmtcpacket/SpacePacketBase.h"
#include "../../timemanager/Clock.h" #include "../../timemanager/Clock.h"
#include "../../objectmanager/SystemObjectIF.h" #include "../../objectmanager/SystemObjectIF.h"
@ -14,7 +14,7 @@ void setStaticFrameworkObjectIds();
* This struct defines a byte-wise structured PUS TM Data Field Header. * This struct defines a byte-wise structured PUS TM Data Field Header.
* Any optional fields in the header must be added or removed here. * Any optional fields in the header must be added or removed here.
* Currently, no Destination field is present, but an eigth-byte representation * Currently, no Destination field is present, but an eigth-byte representation
* for a time tag [TBD]. * for a time tag.
* @ingroup tmtcpackets * @ingroup tmtcpackets
*/ */
struct PUSTmDataFieldHeader { struct PUSTmDataFieldHeader {
@ -40,7 +40,7 @@ struct TmPacketPointer {
/** /**
* This class is the basic data handler for any ECSS PUS Telemetry packet. * 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. * the standardized entries of the PUS TM Packet Data Field Header.
* It does not contain the packet data itself but a pointer to the * It does not contain the packet data itself but a pointer to the
* data must be set on instantiation. An invalid pointer may cause * 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. * 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 TM_PACKET_MIN_SIZE = (sizeof(CCSDSPrimaryHeader) +
static const uint32_t MISSION_TM_PACKET_MAX_SIZE = 2048; //!< Maximum size of a TM Packet in this mission. sizeof(PUSTmDataFieldHeader) + 2);
static const uint8_t VERSION_NUMBER_BYTE_PUS_A = 0b00010000; //!< First byte of secondary header for PUS-A packets. //! 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. * This is the default constructor.
* It sets its internal data pointer to the address passed and also * It sets its internal data pointer to the address passed and also
* forwards the data pointer to the parent SpacePacketBase class. * forwards the data pointer to the parent SpacePacketBase class.
* @param set_address The position where the packet data lies. * @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. * This is the empty default destructor.
*/ */
virtual ~TmPacketBase(); 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 * This is a getter for the packet's PUS Service ID, which is the second
* byte of the Data Field Header. * byte of the Data Field Header.
@ -106,11 +104,14 @@ public:
*/ */
uint16_t getSourceDataSize(); uint16_t getSourceDataSize();
/** /**
* In case data was filled manually (almost never the case). * With this method, the Error Control Field is updated to match the
* @param size Size of source data (without CRC and data filed header!). * current content of the packet. This method is not protected because
*/ * a recalculation by the user might be necessary when manipulating fields
void setSourceDataSize(uint16_t size); * like the sequence count.
*/
void setErrorControl();
/** /**
* This getter returns the Error Control Field of the packet. * This getter returns the Error Control Field of the packet.
* *
@ -120,28 +121,15 @@ public:
* @return The PUS Error Control * @return The PUS Error Control
*/ */
uint16_t getErrorControl(); 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 * This is a debugging helper method that prints the whole packet content
* to the screen. * to the screen.
*/ */
void print(); 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. * @return Converted timestamp of packet.
*/ */
ReturnValue_t getPacketTime(timeval* timestamp) const; ReturnValue_t getPacketTime(timeval* timestamp) const;
@ -151,7 +139,7 @@ public:
*/ */
uint8_t* getPacketTimeRaw() const; uint8_t* getPacketTimeRaw() const;
uint32_t getTimestampSize() const; size_t getTimestampSize() const;
protected: protected:
/** /**
@ -160,20 +148,49 @@ protected:
* *
* To be hardware-safe, all elements are of byte size. * 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. * The timeStamper is responsible for adding a timestamp to the packet.
* It is initialized lazy. * It is initialized lazy.
*/ */
static TimeStamperIF* timeStamper; 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. /**
/** * Initializes the Tm Packet header.
* Checks if a time stamper is available and tries to set it if not. * Does set the timestamp (to now), but not the error control field.
* @return Returns false if setting failed. * @param apid APID used.
*/ * @param service PUS Service
bool checkAndSetStamper(); * @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_ */

View File

@ -1,11 +1,16 @@
#include "TmPacketStored.h"
#include "../../objectmanager/ObjectManagerIF.h" #include "../../objectmanager/ObjectManagerIF.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
#include "TmPacketStored.h"
#include "../../tmtcservices/TmTcMessage.h" #include "../../tmtcservices/TmTcMessage.h"
#include <string.h>
#include <cstring>
StorageManagerIF *TmPacketStored::store = nullptr;
InternalErrorReporterIF *TmPacketStored::internalErrorReporter = nullptr;
TmPacketStored::TmPacketStored(store_address_t setAddress) : TmPacketStored::TmPacketStored(store_address_t setAddress) :
TmPacketBase(NULL), storeAddress(setAddress) { TmPacketBase(nullptr), storeAddress(setAddress) {
setStoreAddress(storeAddress); setStoreAddress(storeAddress);
} }
@ -14,10 +19,10 @@ TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service,
uint32_t size, const uint8_t *headerData, uint32_t headerSize) : uint32_t size, const uint8_t *headerData, uint32_t headerSize) :
TmPacketBase(NULL) { TmPacketBase(NULL) {
storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
if (!checkAndSetStore()) { if (not checkAndSetStore()) {
return; return;
} }
uint8_t *pData = NULL; uint8_t *pData = nullptr;
ReturnValue_t returnValue = store->getFreeElement(&storeAddress, ReturnValue_t returnValue = store->getFreeElement(&storeAddress,
(TmPacketBase::TM_PACKET_MIN_SIZE + size + headerSize), &pData); (TmPacketBase::TM_PACKET_MIN_SIZE + size + headerSize), &pData);
@ -38,7 +43,7 @@ TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service,
SerializeIF *header) : SerializeIF *header) :
TmPacketBase(NULL) { TmPacketBase(NULL) {
storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
if (!checkAndSetStore()) { if (not checkAndSetStore()) {
return; return;
} }
size_t sourceDataSize = 0; size_t sourceDataSize = 0;
@ -77,29 +82,29 @@ store_address_t TmPacketStored::getStoreAddress() {
void TmPacketStored::deletePacket() { void TmPacketStored::deletePacket() {
store->deleteData(storeAddress); store->deleteData(storeAddress);
storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
setData(NULL); setData(nullptr);
} }
void TmPacketStored::setStoreAddress(store_address_t setAddress) { void TmPacketStored::setStoreAddress(store_address_t setAddress) {
storeAddress = setAddress; storeAddress = setAddress;
const uint8_t* temp_data = NULL; const uint8_t* tempData = nullptr;
size_t temp_size; size_t tempSize;
if (!checkAndSetStore()) { if (not checkAndSetStore()) {
return; return;
} }
ReturnValue_t status = store->getData(storeAddress, &temp_data, &temp_size); ReturnValue_t status = store->getData(storeAddress, &tempData, &tempSize);
if (status == StorageManagerIF::RETURN_OK) { if (status == StorageManagerIF::RETURN_OK) {
setData(temp_data); setData(tempData);
} else { } else {
setData(NULL); setData(nullptr);
storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
} }
} }
bool TmPacketStored::checkAndSetStore() { bool TmPacketStored::checkAndSetStore() {
if (store == NULL) { if (store == nullptr) {
store = objectManager->get<StorageManagerIF>(objects::TM_STORE); store = objectManager->get<StorageManagerIF>(objects::TM_STORE);
if (store == NULL) { if (store == nullptr) {
sif::error << "TmPacketStored::TmPacketStored: TM Store not found!" sif::error << "TmPacketStored::TmPacketStored: TM Store not found!"
<< std::endl; << std::endl;
return false; return false;
@ -108,12 +113,9 @@ bool TmPacketStored::checkAndSetStore() {
return true; return true;
} }
StorageManagerIF *TmPacketStored::store = NULL;
InternalErrorReporterIF *TmPacketStored::internalErrorReporter = NULL;
ReturnValue_t TmPacketStored::sendPacket(MessageQueueId_t destination, ReturnValue_t TmPacketStored::sendPacket(MessageQueueId_t destination,
MessageQueueId_t sentFrom, bool doErrorReporting) { MessageQueueId_t sentFrom, bool doErrorReporting) {
if (getWholeData() == NULL) { if (getWholeData() == nullptr) {
//SHOULDDO: More decent code. //SHOULDDO: More decent code.
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
@ -133,11 +135,11 @@ ReturnValue_t TmPacketStored::sendPacket(MessageQueueId_t destination,
} }
void TmPacketStored::checkAndReportLostTm() { void TmPacketStored::checkAndReportLostTm() {
if (internalErrorReporter == NULL) { if (internalErrorReporter == nullptr) {
internalErrorReporter = objectManager->get<InternalErrorReporterIF>( internalErrorReporter = objectManager->get<InternalErrorReporterIF>(
objects::INTERNAL_ERROR_REPORTER); objects::INTERNAL_ERROR_REPORTER);
} }
if (internalErrorReporter != NULL) { if (internalErrorReporter != nullptr) {
internalErrorReporter->lostTm(); internalErrorReporter->lostTm();
} }
} }

View File

@ -1,9 +1,10 @@
#ifndef TMPACKETSTORED_H_ #ifndef TMTCPACKET_PUS_TMPACKETSTORED_H_
#define TMPACKETSTORED_H_ #define TMTCPACKET_PUS_TMPACKETSTORED_H_
#include "TmPacketBase.h"
#include "../../serialize/SerializeIF.h" #include "../../serialize/SerializeIF.h"
#include "../../storagemanager/StorageManagerIF.h" #include "../../storagemanager/StorageManagerIF.h"
#include "TmPacketBase.h"
#include "../../internalError/InternalErrorReporterIF.h" #include "../../internalError/InternalErrorReporterIF.h"
#include "../../ipc/MessageQueueSenderIF.h" #include "../../ipc/MessageQueueSenderIF.h"
@ -18,31 +19,6 @@
* @ingroup tmtcpackets * @ingroup tmtcpackets
*/ */
class TmPacketStored : public TmPacketBase { 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: public:
/** /**
* This is a default constructor which does not set the data pointer. * 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 * With this constructor, new space is allocated in the packet store and
* a new PUS Telemetry Packet is created there. * a new PUS Telemetry Packet is created there.
* Packet Application Data passed in data is copied into the packet. The Application data is * Packet Application Data passed in data is copied into the packet.
* passed in two parts, first a header, then a data field. This allows building a Telemetry * The Application data is passed in two parts, first a header, then a
* Packet from two separate data sources. * data field. This allows building a Telemetry Packet from two separate
* data sources.
* @param apid Sets the packet's APID field. * @param apid Sets the packet's APID field.
* @param service Sets the packet's Service ID field. * @param service Sets the packet's Service ID field.
* This specifies the source service. * This specifies the source service.
* @param subservice Sets the packet's Service Subtype field. * @param subservice Sets the packet's Service Subtype field.
* This specifies the source sub-service. * This specifies the source sub-service.
* @param packet_counter Sets the Packet counter field of this packet * @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 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 * @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. * 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. * the packet is not linked.
*/ */
store_address_t getStoreAddress(); store_address_t getStoreAddress();
@ -89,8 +75,34 @@ public:
*/ */
void setStoreAddress( store_address_t setAddress ); 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_ */