reapply clang format
This commit is contained in:
@ -4,8 +4,8 @@
|
||||
#include "fsfw/action/ActionHelper.h"
|
||||
#include "fsfw/action/ActionMessage.h"
|
||||
#include "fsfw/action/CommandActionHelper.h"
|
||||
#include "fsfw/action/HasActionsIF.h"
|
||||
#include "fsfw/action/CommandsActionsIF.h"
|
||||
#include "fsfw/action/HasActionsIF.h"
|
||||
#include "fsfw/action/SimpleActionHelper.h"
|
||||
|
||||
#endif /* FSFW_INC_FSFW_ACTION_H_ */
|
||||
|
@ -1,177 +1,165 @@
|
||||
#include "fsfw/action.h"
|
||||
|
||||
#include "fsfw/ipc/MessageQueueSenderIF.h"
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
|
||||
ActionHelper::ActionHelper(HasActionsIF* setOwner,
|
||||
MessageQueueIF* useThisQueue) :
|
||||
owner(setOwner), queueToUse(useThisQueue) {
|
||||
}
|
||||
ActionHelper::ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue)
|
||||
: owner(setOwner), queueToUse(useThisQueue) {}
|
||||
|
||||
ActionHelper::~ActionHelper() {
|
||||
}
|
||||
ActionHelper::~ActionHelper() {}
|
||||
|
||||
ReturnValue_t ActionHelper::handleActionMessage(CommandMessage* command) {
|
||||
if (command->getCommand() == ActionMessage::EXECUTE_ACTION) {
|
||||
ActionId_t currentAction = ActionMessage::getActionId(command);
|
||||
prepareExecution(command->getSender(), currentAction,
|
||||
ActionMessage::getStoreId(command));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else {
|
||||
return CommandMessage::UNKNOWN_COMMAND;
|
||||
}
|
||||
if (command->getCommand() == ActionMessage::EXECUTE_ACTION) {
|
||||
ActionId_t currentAction = ActionMessage::getActionId(command);
|
||||
prepareExecution(command->getSender(), currentAction, ActionMessage::getStoreId(command));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else {
|
||||
return CommandMessage::UNKNOWN_COMMAND;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t ActionHelper::initialize(MessageQueueIF* queueToUse_) {
|
||||
ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
||||
if (ipcStore == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
if(queueToUse_ != nullptr) {
|
||||
setQueueToUse(queueToUse_);
|
||||
}
|
||||
ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
||||
if (ipcStore == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
if (queueToUse_ != nullptr) {
|
||||
setQueueToUse(queueToUse_);
|
||||
}
|
||||
|
||||
if(queueToUse == nullptr) {
|
||||
if (queueToUse == nullptr) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "ActionHelper::initialize: No queue set" << std::endl;
|
||||
sif::warning << "ActionHelper::initialize: No queue set" << std::endl;
|
||||
#else
|
||||
sif::printWarning("ActionHelper::initialize: No queue set\n");
|
||||
sif::printWarning("ActionHelper::initialize: No queue set\n");
|
||||
#endif
|
||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
void ActionHelper::step(uint8_t step, MessageQueueId_t reportTo,
|
||||
ActionId_t commandId, ReturnValue_t result) {
|
||||
CommandMessage reply;
|
||||
ActionMessage::setStepReply(&reply, commandId, step + STEP_OFFSET, result);
|
||||
queueToUse->sendMessage(reportTo, &reply);
|
||||
void ActionHelper::step(uint8_t step, MessageQueueId_t reportTo, ActionId_t commandId,
|
||||
ReturnValue_t result) {
|
||||
CommandMessage reply;
|
||||
ActionMessage::setStepReply(&reply, commandId, step + STEP_OFFSET, result);
|
||||
queueToUse->sendMessage(reportTo, &reply);
|
||||
}
|
||||
|
||||
void ActionHelper::finish(bool success, MessageQueueId_t reportTo, ActionId_t commandId,
|
||||
ReturnValue_t result) {
|
||||
ReturnValue_t result) {
|
||||
CommandMessage reply;
|
||||
ActionMessage::setCompletionReply(&reply, commandId, success, result);
|
||||
queueToUse->sendMessage(reportTo, &reply);
|
||||
}
|
||||
|
||||
void ActionHelper::setQueueToUse(MessageQueueIF* queue) { queueToUse = queue; }
|
||||
|
||||
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
|
||||
store_address_t dataAddress) {
|
||||
const uint8_t* dataPtr = NULL;
|
||||
size_t size = 0;
|
||||
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
CommandMessage reply;
|
||||
ActionMessage::setCompletionReply(&reply, commandId, success, result);
|
||||
queueToUse->sendMessage(reportTo, &reply);
|
||||
}
|
||||
|
||||
void ActionHelper::setQueueToUse(MessageQueueIF* queue) {
|
||||
queueToUse = queue;
|
||||
}
|
||||
|
||||
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy,
|
||||
ActionId_t actionId, store_address_t dataAddress) {
|
||||
const uint8_t* dataPtr = NULL;
|
||||
size_t size = 0;
|
||||
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
CommandMessage reply;
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
return;
|
||||
}
|
||||
result = owner->executeAction(actionId, commandedBy, dataPtr, size);
|
||||
ipcStore->deleteData(dataAddress);
|
||||
if(result == HasActionsIF::EXECUTION_FINISHED) {
|
||||
CommandMessage reply;
|
||||
ActionMessage::setCompletionReply(&reply, actionId, true, result);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
}
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
CommandMessage reply;
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo,
|
||||
ActionId_t replyId, SerializeIF* data, bool hideSender) {
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
return;
|
||||
}
|
||||
result = owner->executeAction(actionId, commandedBy, dataPtr, size);
|
||||
ipcStore->deleteData(dataAddress);
|
||||
if (result == HasActionsIF::EXECUTION_FINISHED) {
|
||||
CommandMessage reply;
|
||||
store_address_t storeAddress;
|
||||
uint8_t *dataPtr;
|
||||
size_t maxSize = data->getSerializedSize();
|
||||
if (maxSize == 0) {
|
||||
/* No error, there's simply nothing to report. */
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
size_t size = 0;
|
||||
ReturnValue_t result = ipcStore->getFreeElement(&storeAddress, maxSize,
|
||||
&dataPtr);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
ActionMessage::setCompletionReply(&reply, actionId, true, result);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
}
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
CommandMessage reply;
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, ActionId_t replyId,
|
||||
SerializeIF* data, bool hideSender) {
|
||||
CommandMessage reply;
|
||||
store_address_t storeAddress;
|
||||
uint8_t* dataPtr;
|
||||
size_t maxSize = data->getSerializedSize();
|
||||
if (maxSize == 0) {
|
||||
/* No error, there's simply nothing to report. */
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
size_t size = 0;
|
||||
ReturnValue_t result = ipcStore->getFreeElement(&storeAddress, maxSize, &dataPtr);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "ActionHelper::reportData: Getting free element from IPC store failed!" <<
|
||||
std::endl;
|
||||
sif::warning << "ActionHelper::reportData: Getting free element from IPC store failed!"
|
||||
<< std::endl;
|
||||
#else
|
||||
sif::printWarning("ActionHelper::reportData: Getting free element from IPC "
|
||||
"store failed!\n");
|
||||
sif::printWarning(
|
||||
"ActionHelper::reportData: Getting free element from IPC "
|
||||
"store failed!\n");
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
result = data->serialize(&dataPtr, &size, maxSize,
|
||||
SerializeIF::Endianness::BIG);
|
||||
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;
|
||||
}
|
||||
result = data->serialize(&dataPtr, &size, maxSize, SerializeIF::Endianness::BIG);
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "ActionHelper::reportData: Adding data to IPC store failed!" << std::endl;
|
||||
sif::warning << "ActionHelper::reportData: Adding data to IPC store failed!" << std::endl;
|
||||
#else
|
||||
sif::printWarning("ActionHelper::reportData: Adding data to IPC store failed!\n");
|
||||
sif::printWarning("ActionHelper::reportData: Adding data to IPC store failed!\n");
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
#ifndef FSFW_ACTION_ACTIONHELPER_H_
|
||||
#define FSFW_ACTION_ACTIONHELPER_H_
|
||||
|
||||
#include "ActionMessage.h"
|
||||
#include "../serialize/SerializeIF.h"
|
||||
#include "../ipc/MessageQueueIF.h"
|
||||
#include "../serialize/SerializeIF.h"
|
||||
#include "ActionMessage.h"
|
||||
/**
|
||||
* @brief Action Helper is a helper class which handles action messages
|
||||
*
|
||||
@ -17,110 +17,110 @@
|
||||
class HasActionsIF;
|
||||
|
||||
class ActionHelper {
|
||||
public:
|
||||
/**
|
||||
* Constructor of the action helper
|
||||
* @param setOwner Pointer to the owner of the interface
|
||||
* @param useThisQueue messageQueue to be used, can be set during
|
||||
* initialize function as well.
|
||||
*/
|
||||
ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
|
||||
public:
|
||||
/**
|
||||
* Constructor of the action helper
|
||||
* @param setOwner Pointer to the owner of the interface
|
||||
* @param useThisQueue messageQueue to be used, can be set during
|
||||
* initialize function as well.
|
||||
*/
|
||||
ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
|
||||
|
||||
virtual ~ActionHelper();
|
||||
/**
|
||||
* 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 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
|
||||
* @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);
|
||||
/**
|
||||
* Helper initialize function. Must be called before use of any other
|
||||
* helper function
|
||||
* @param queueToUse_ Pointer to the messageQueue to be used, optional
|
||||
* if queue was set in constructor
|
||||
* @return Returns RETURN_OK if successful
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @param step Number of steps already done
|
||||
* @param reportTo The messageQueueId to report the step message to
|
||||
* @param commandId ID of the executed command
|
||||
* @param result Result of the execution
|
||||
*/
|
||||
void step(uint8_t step, MessageQueueId_t reportTo,
|
||||
ActionId_t commandId,
|
||||
virtual ~ActionHelper();
|
||||
/**
|
||||
* 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 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
|
||||
* @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);
|
||||
/**
|
||||
* Helper initialize function. Must be called before use of any other
|
||||
* helper function
|
||||
* @param queueToUse_ Pointer to the messageQueue to be used, optional
|
||||
* if queue was set in constructor
|
||||
* @return Returns RETURN_OK if successful
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @param step Number of steps already done
|
||||
* @param reportTo The messageQueueId to report the step message to
|
||||
* @param commandId ID of the executed command
|
||||
* @param result Result of the execution
|
||||
*/
|
||||
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
|
||||
* @param success Specify whether action was completed successfully or not.
|
||||
* @param reportTo MessageQueueId_t to report the action completion message to
|
||||
* @param commandId ID of the executed command
|
||||
* @param result Result of the execution
|
||||
*/
|
||||
void finish(bool success, 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.
|
||||
* Takes a SerializeIF* pointer and serializes 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,
|
||||
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 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
|
||||
*/
|
||||
void setQueueToUse(MessageQueueIF *queue);
|
||||
protected:
|
||||
//! Increase of value of this per step
|
||||
static const uint8_t STEP_OFFSET = 1;
|
||||
//! Pointer to the owner
|
||||
HasActionsIF* owner;
|
||||
//! Queue to be used as response sender, has to be set in ctor or with
|
||||
//! setQueueToUse
|
||||
MessageQueueIF* queueToUse;
|
||||
//! Pointer to an IPC Store, initialized during construction or
|
||||
StorageManagerIF* ipcStore = nullptr;
|
||||
/**
|
||||
* Function to be called by the owner to send a action completion message
|
||||
* @param success Specify whether action was completed successfully or not.
|
||||
* @param reportTo MessageQueueId_t to report the action completion message to
|
||||
* @param commandId ID of the executed command
|
||||
* @param result Result of the execution
|
||||
*/
|
||||
void finish(bool success, 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.
|
||||
* Takes a SerializeIF* pointer and serializes 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, 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 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
|
||||
*/
|
||||
void setQueueToUse(MessageQueueIF* queue);
|
||||
|
||||
/**
|
||||
* Internal function called by handleActionMessage
|
||||
* @param commandedBy MessageQueueID of Commander
|
||||
* @param actionId ID of action to be done
|
||||
* @param dataAddress Address of additional data in IPC Store
|
||||
*/
|
||||
virtual void prepareExecution(MessageQueueId_t commandedBy,
|
||||
ActionId_t actionId, store_address_t dataAddress);
|
||||
/**
|
||||
* @brief Default implementation is empty.
|
||||
*/
|
||||
virtual void resetHelper();
|
||||
protected:
|
||||
//! Increase of value of this per step
|
||||
static const uint8_t STEP_OFFSET = 1;
|
||||
//! Pointer to the owner
|
||||
HasActionsIF* owner;
|
||||
//! Queue to be used as response sender, has to be set in ctor or with
|
||||
//! setQueueToUse
|
||||
MessageQueueIF* queueToUse;
|
||||
//! Pointer to an IPC Store, initialized during construction or
|
||||
StorageManagerIF* ipcStore = nullptr;
|
||||
|
||||
/**
|
||||
* Internal function called by handleActionMessage
|
||||
* @param commandedBy MessageQueueID of Commander
|
||||
* @param actionId ID of action to be done
|
||||
* @param dataAddress Address of additional data in IPC Store
|
||||
*/
|
||||
virtual void prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
|
||||
store_address_t dataAddress);
|
||||
/**
|
||||
* @brief Default implementation is empty.
|
||||
*/
|
||||
virtual void resetHelper();
|
||||
};
|
||||
|
||||
#endif /* FSFW_ACTION_ACTIONHELPER_H_ */
|
||||
|
@ -1,81 +1,77 @@
|
||||
#include "fsfw/action.h"
|
||||
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||
|
||||
ActionMessage::ActionMessage() {
|
||||
}
|
||||
ActionMessage::ActionMessage() {}
|
||||
|
||||
ActionMessage::~ActionMessage() {
|
||||
}
|
||||
ActionMessage::~ActionMessage() {}
|
||||
|
||||
void ActionMessage::setCommand(CommandMessage* message, ActionId_t fid,
|
||||
store_address_t parameters) {
|
||||
message->setCommand(EXECUTE_ACTION);
|
||||
message->setParameter(fid);
|
||||
message->setParameter2(parameters.raw);
|
||||
store_address_t parameters) {
|
||||
message->setCommand(EXECUTE_ACTION);
|
||||
message->setParameter(fid);
|
||||
message->setParameter2(parameters.raw);
|
||||
}
|
||||
|
||||
ActionId_t ActionMessage::getActionId(const CommandMessage* message) {
|
||||
return ActionId_t(message->getParameter());
|
||||
return ActionId_t(message->getParameter());
|
||||
}
|
||||
|
||||
store_address_t ActionMessage::getStoreId(const CommandMessage* message) {
|
||||
store_address_t temp;
|
||||
temp.raw = message->getParameter2();
|
||||
return temp;
|
||||
store_address_t temp;
|
||||
temp.raw = message->getParameter2();
|
||||
return temp;
|
||||
}
|
||||
|
||||
void ActionMessage::setStepReply(CommandMessage* message, ActionId_t fid, uint8_t step,
|
||||
ReturnValue_t result) {
|
||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||
message->setCommand(STEP_SUCCESS);
|
||||
} else {
|
||||
message->setCommand(STEP_FAILED);
|
||||
}
|
||||
message->setParameter(fid);
|
||||
message->setParameter2((step << 16) + result);
|
||||
ReturnValue_t result) {
|
||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||
message->setCommand(STEP_SUCCESS);
|
||||
} else {
|
||||
message->setCommand(STEP_FAILED);
|
||||
}
|
||||
message->setParameter(fid);
|
||||
message->setParameter2((step << 16) + result);
|
||||
}
|
||||
|
||||
uint8_t ActionMessage::getStep(const CommandMessage* message) {
|
||||
return uint8_t((message->getParameter2() >> 16) & 0xFF);
|
||||
return uint8_t((message->getParameter2() >> 16) & 0xFF);
|
||||
}
|
||||
|
||||
ReturnValue_t ActionMessage::getReturnCode(const CommandMessage* message) {
|
||||
return message->getParameter2() & 0xFFFF;
|
||||
return message->getParameter2() & 0xFFFF;
|
||||
}
|
||||
|
||||
void ActionMessage::setDataReply(CommandMessage* message, ActionId_t actionId,
|
||||
store_address_t data) {
|
||||
message->setCommand(DATA_REPLY);
|
||||
message->setParameter(actionId);
|
||||
message->setParameter2(data.raw);
|
||||
store_address_t data) {
|
||||
message->setCommand(DATA_REPLY);
|
||||
message->setParameter(actionId);
|
||||
message->setParameter2(data.raw);
|
||||
}
|
||||
|
||||
void ActionMessage::setCompletionReply(CommandMessage* message,
|
||||
ActionId_t fid, bool success, ReturnValue_t result) {
|
||||
if (success) {
|
||||
message->setCommand(COMPLETION_SUCCESS);
|
||||
}
|
||||
else {
|
||||
message->setCommand(COMPLETION_FAILED);
|
||||
}
|
||||
message->setParameter(fid);
|
||||
message->setParameter2(result);
|
||||
void ActionMessage::setCompletionReply(CommandMessage* message, ActionId_t fid, bool success,
|
||||
ReturnValue_t result) {
|
||||
if (success) {
|
||||
message->setCommand(COMPLETION_SUCCESS);
|
||||
} else {
|
||||
message->setCommand(COMPLETION_FAILED);
|
||||
}
|
||||
message->setParameter(fid);
|
||||
message->setParameter2(result);
|
||||
}
|
||||
|
||||
void ActionMessage::clear(CommandMessage* message) {
|
||||
switch(message->getCommand()) {
|
||||
switch (message->getCommand()) {
|
||||
case EXECUTE_ACTION:
|
||||
case DATA_REPLY: {
|
||||
StorageManagerIF *ipcStore = ObjectManager::instance()->get<StorageManagerIF>(
|
||||
objects::IPC_STORE);
|
||||
if (ipcStore != NULL) {
|
||||
ipcStore->deleteData(getStoreId(message));
|
||||
}
|
||||
break;
|
||||
StorageManagerIF* ipcStore =
|
||||
ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
||||
if (ipcStore != NULL) {
|
||||
ipcStore->deleteData(getStoreId(message));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -14,34 +14,33 @@ using ActionId_t = uint32_t;
|
||||
* ActionHelper are able to process these messages.
|
||||
*/
|
||||
class ActionMessage {
|
||||
private:
|
||||
ActionMessage();
|
||||
public:
|
||||
static const uint8_t MESSAGE_ID = messagetypes::ACTION;
|
||||
static const Command_t EXECUTE_ACTION = MAKE_COMMAND_ID(1);
|
||||
static const Command_t STEP_SUCCESS = MAKE_COMMAND_ID(2);
|
||||
static const Command_t STEP_FAILED = MAKE_COMMAND_ID(3);
|
||||
static const Command_t DATA_REPLY = MAKE_COMMAND_ID(4);
|
||||
static const Command_t COMPLETION_SUCCESS = MAKE_COMMAND_ID(5);
|
||||
static const Command_t COMPLETION_FAILED = MAKE_COMMAND_ID(6);
|
||||
private:
|
||||
ActionMessage();
|
||||
|
||||
virtual ~ActionMessage();
|
||||
static void setCommand(CommandMessage* message, ActionId_t fid,
|
||||
store_address_t parameters);
|
||||
public:
|
||||
static const uint8_t MESSAGE_ID = messagetypes::ACTION;
|
||||
static const Command_t EXECUTE_ACTION = MAKE_COMMAND_ID(1);
|
||||
static const Command_t STEP_SUCCESS = MAKE_COMMAND_ID(2);
|
||||
static const Command_t STEP_FAILED = MAKE_COMMAND_ID(3);
|
||||
static const Command_t DATA_REPLY = MAKE_COMMAND_ID(4);
|
||||
static const Command_t COMPLETION_SUCCESS = MAKE_COMMAND_ID(5);
|
||||
static const Command_t COMPLETION_FAILED = MAKE_COMMAND_ID(6);
|
||||
|
||||
static ActionId_t getActionId(const CommandMessage* message );
|
||||
static store_address_t getStoreId(const CommandMessage* message);
|
||||
virtual ~ActionMessage();
|
||||
static void setCommand(CommandMessage* message, ActionId_t fid, store_address_t parameters);
|
||||
|
||||
static void setStepReply(CommandMessage* message, ActionId_t fid,
|
||||
uint8_t step, ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
static uint8_t getStep(const CommandMessage* message );
|
||||
static ReturnValue_t getReturnCode(const CommandMessage* message );
|
||||
static void setDataReply(CommandMessage* message, ActionId_t actionId,
|
||||
store_address_t data);
|
||||
static void setCompletionReply(CommandMessage* message, ActionId_t fid,
|
||||
bool success, ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
static ActionId_t getActionId(const CommandMessage* message);
|
||||
static store_address_t getStoreId(const CommandMessage* message);
|
||||
|
||||
static void clear(CommandMessage* message);
|
||||
static void setStepReply(CommandMessage* message, ActionId_t fid, uint8_t step,
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
static uint8_t getStep(const CommandMessage* message);
|
||||
static ReturnValue_t getReturnCode(const CommandMessage* message);
|
||||
static void setDataReply(CommandMessage* message, ActionId_t actionId, store_address_t data);
|
||||
static void setCompletionReply(CommandMessage* message, ActionId_t fid, bool success,
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
static void clear(CommandMessage* message);
|
||||
};
|
||||
|
||||
#endif /* FSFW_ACTION_ACTIONMESSAGE_H_ */
|
||||
|
@ -1,125 +1,115 @@
|
||||
#include "fsfw/action.h"
|
||||
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
|
||||
CommandActionHelper::CommandActionHelper(CommandsActionsIF *setOwner) :
|
||||
owner(setOwner), queueToUse(NULL), ipcStore(
|
||||
NULL), commandCount(0), lastTarget(0) {
|
||||
}
|
||||
CommandActionHelper::CommandActionHelper(CommandsActionsIF *setOwner)
|
||||
: owner(setOwner), queueToUse(NULL), ipcStore(NULL), commandCount(0), lastTarget(0) {}
|
||||
|
||||
CommandActionHelper::~CommandActionHelper() {
|
||||
}
|
||||
CommandActionHelper::~CommandActionHelper() {}
|
||||
|
||||
ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo,
|
||||
ActionId_t actionId, SerializeIF *data) {
|
||||
HasActionsIF *receiver = ObjectManager::instance()->get<HasActionsIF>(commandTo);
|
||||
if (receiver == NULL) {
|
||||
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
|
||||
}
|
||||
store_address_t storeId;
|
||||
uint8_t *storePointer;
|
||||
size_t maxSize = data->getSerializedSize();
|
||||
ReturnValue_t result = ipcStore->getFreeElement(&storeId, maxSize,
|
||||
&storePointer);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
size_t size = 0;
|
||||
result = data->serialize(&storePointer, &size, maxSize,
|
||||
SerializeIF::Endianness::BIG);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return sendCommand(receiver->getCommandQueue(), actionId, storeId);
|
||||
}
|
||||
|
||||
ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo,
|
||||
ActionId_t actionId, const uint8_t *data, uint32_t size) {
|
||||
// if (commandCount != 0) {
|
||||
// return CommandsFunctionsIF::ALREADY_COMMANDING;
|
||||
// }
|
||||
HasActionsIF *receiver = ObjectManager::instance()->get<HasActionsIF>(commandTo);
|
||||
if (receiver == NULL) {
|
||||
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
|
||||
}
|
||||
store_address_t storeId;
|
||||
ReturnValue_t result = ipcStore->addData(&storeId, data, size);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return sendCommand(receiver->getCommandQueue(), actionId, storeId);
|
||||
}
|
||||
|
||||
ReturnValue_t CommandActionHelper::sendCommand(MessageQueueId_t queueId,
|
||||
ActionId_t actionId, store_address_t storeId) {
|
||||
CommandMessage command;
|
||||
ActionMessage::setCommand(&command, actionId, storeId);
|
||||
ReturnValue_t result = queueToUse->sendMessage(queueId, &command);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
ipcStore->deleteData(storeId);
|
||||
}
|
||||
lastTarget = queueId;
|
||||
commandCount++;
|
||||
ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo, ActionId_t actionId,
|
||||
SerializeIF *data) {
|
||||
HasActionsIF *receiver = ObjectManager::instance()->get<HasActionsIF>(commandTo);
|
||||
if (receiver == NULL) {
|
||||
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
|
||||
}
|
||||
store_address_t storeId;
|
||||
uint8_t *storePointer;
|
||||
size_t maxSize = data->getSerializedSize();
|
||||
ReturnValue_t result = ipcStore->getFreeElement(&storeId, maxSize, &storePointer);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
size_t size = 0;
|
||||
result = data->serialize(&storePointer, &size, maxSize, SerializeIF::Endianness::BIG);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return sendCommand(receiver->getCommandQueue(), actionId, storeId);
|
||||
}
|
||||
|
||||
ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo, ActionId_t actionId,
|
||||
const uint8_t *data, uint32_t size) {
|
||||
// if (commandCount != 0) {
|
||||
// return CommandsFunctionsIF::ALREADY_COMMANDING;
|
||||
// }
|
||||
HasActionsIF *receiver = ObjectManager::instance()->get<HasActionsIF>(commandTo);
|
||||
if (receiver == NULL) {
|
||||
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
|
||||
}
|
||||
store_address_t storeId;
|
||||
ReturnValue_t result = ipcStore->addData(&storeId, data, size);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return sendCommand(receiver->getCommandQueue(), actionId, storeId);
|
||||
}
|
||||
|
||||
ReturnValue_t CommandActionHelper::sendCommand(MessageQueueId_t queueId, ActionId_t actionId,
|
||||
store_address_t storeId) {
|
||||
CommandMessage command;
|
||||
ActionMessage::setCommand(&command, actionId, storeId);
|
||||
ReturnValue_t result = queueToUse->sendMessage(queueId, &command);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
ipcStore->deleteData(storeId);
|
||||
}
|
||||
lastTarget = queueId;
|
||||
commandCount++;
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t CommandActionHelper::initialize() {
|
||||
ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
||||
if (ipcStore == NULL) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
||||
if (ipcStore == NULL) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
queueToUse = owner->getCommandQueuePtr();
|
||||
if (queueToUse == NULL) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
queueToUse = owner->getCommandQueuePtr();
|
||||
if (queueToUse == NULL) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t CommandActionHelper::handleReply(CommandMessage *reply) {
|
||||
if (reply->getSender() != lastTarget) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
switch (reply->getCommand()) {
|
||||
if (reply->getSender() != lastTarget) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
switch (reply->getCommand()) {
|
||||
case ActionMessage::COMPLETION_SUCCESS:
|
||||
commandCount--;
|
||||
owner->completionSuccessfulReceived(ActionMessage::getActionId(reply));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
commandCount--;
|
||||
owner->completionSuccessfulReceived(ActionMessage::getActionId(reply));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
case ActionMessage::COMPLETION_FAILED:
|
||||
commandCount--;
|
||||
owner->completionFailedReceived(ActionMessage::getActionId(reply),
|
||||
ActionMessage::getReturnCode(reply));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
commandCount--;
|
||||
owner->completionFailedReceived(ActionMessage::getActionId(reply),
|
||||
ActionMessage::getReturnCode(reply));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
case ActionMessage::STEP_SUCCESS:
|
||||
owner->stepSuccessfulReceived(ActionMessage::getActionId(reply),
|
||||
ActionMessage::getStep(reply));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
owner->stepSuccessfulReceived(ActionMessage::getActionId(reply),
|
||||
ActionMessage::getStep(reply));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
case ActionMessage::STEP_FAILED:
|
||||
commandCount--;
|
||||
owner->stepFailedReceived(ActionMessage::getActionId(reply),
|
||||
ActionMessage::getStep(reply),
|
||||
ActionMessage::getReturnCode(reply));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
commandCount--;
|
||||
owner->stepFailedReceived(ActionMessage::getActionId(reply), ActionMessage::getStep(reply),
|
||||
ActionMessage::getReturnCode(reply));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
case ActionMessage::DATA_REPLY:
|
||||
extractDataForOwner(ActionMessage::getActionId(reply),
|
||||
ActionMessage::getStoreId(reply));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
extractDataForOwner(ActionMessage::getActionId(reply), ActionMessage::getStoreId(reply));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
default:
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t CommandActionHelper::getCommandCount() const {
|
||||
return commandCount;
|
||||
}
|
||||
uint8_t CommandActionHelper::getCommandCount() const { return commandCount; }
|
||||
|
||||
void CommandActionHelper::extractDataForOwner(ActionId_t actionId, store_address_t storeId) {
|
||||
const uint8_t * data = NULL;
|
||||
size_t size = 0;
|
||||
ReturnValue_t result = ipcStore->getData(storeId, &data, &size);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return;
|
||||
}
|
||||
owner->dataReceived(actionId, data, size);
|
||||
ipcStore->deleteData(storeId);
|
||||
const uint8_t *data = NULL;
|
||||
size_t size = 0;
|
||||
ReturnValue_t result = ipcStore->getData(storeId, &data, &size);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return;
|
||||
}
|
||||
owner->dataReceived(actionId, data, size);
|
||||
ipcStore->deleteData(storeId);
|
||||
}
|
||||
|
@ -2,35 +2,35 @@
|
||||
#define COMMANDACTIONHELPER_H_
|
||||
|
||||
#include "ActionMessage.h"
|
||||
#include "fsfw/ipc/MessageQueueIF.h"
|
||||
#include "fsfw/objectmanager/ObjectManagerIF.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include "fsfw/serialize/SerializeIF.h"
|
||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||
#include "fsfw/ipc/MessageQueueIF.h"
|
||||
|
||||
class CommandsActionsIF;
|
||||
|
||||
class CommandActionHelper {
|
||||
friend class CommandsActionsIF;
|
||||
public:
|
||||
CommandActionHelper(CommandsActionsIF* owner);
|
||||
virtual ~CommandActionHelper();
|
||||
ReturnValue_t commandAction(object_id_t commandTo,
|
||||
ActionId_t actionId, const uint8_t* data, uint32_t size);
|
||||
ReturnValue_t commandAction(object_id_t commandTo,
|
||||
ActionId_t actionId, SerializeIF* data);
|
||||
ReturnValue_t initialize();
|
||||
ReturnValue_t handleReply(CommandMessage* reply);
|
||||
uint8_t getCommandCount() const;
|
||||
private:
|
||||
CommandsActionsIF* owner;
|
||||
MessageQueueIF* queueToUse;
|
||||
StorageManagerIF* ipcStore;
|
||||
uint8_t commandCount;
|
||||
MessageQueueId_t lastTarget;
|
||||
void extractDataForOwner(ActionId_t actionId, store_address_t storeId);
|
||||
ReturnValue_t sendCommand(MessageQueueId_t queueId, ActionId_t actionId,
|
||||
store_address_t storeId);
|
||||
friend class CommandsActionsIF;
|
||||
|
||||
public:
|
||||
CommandActionHelper(CommandsActionsIF* owner);
|
||||
virtual ~CommandActionHelper();
|
||||
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId, const uint8_t* data,
|
||||
uint32_t size);
|
||||
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId, SerializeIF* data);
|
||||
ReturnValue_t initialize();
|
||||
ReturnValue_t handleReply(CommandMessage* reply);
|
||||
uint8_t getCommandCount() const;
|
||||
|
||||
private:
|
||||
CommandsActionsIF* owner;
|
||||
MessageQueueIF* queueToUse;
|
||||
StorageManagerIF* ipcStore;
|
||||
uint8_t commandCount;
|
||||
MessageQueueId_t lastTarget;
|
||||
void extractDataForOwner(ActionId_t actionId, store_address_t storeId);
|
||||
ReturnValue_t sendCommand(MessageQueueId_t queueId, ActionId_t actionId, store_address_t storeId);
|
||||
};
|
||||
|
||||
#endif /* COMMANDACTIONHELPER_H_ */
|
||||
|
@ -1,9 +1,9 @@
|
||||
#ifndef FSFW_ACTION_COMMANDSACTIONSIF_H_
|
||||
#define FSFW_ACTION_COMMANDSACTIONSIF_H_
|
||||
|
||||
#include "CommandActionHelper.h"
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
#include "../ipc/MessageQueueIF.h"
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
#include "CommandActionHelper.h"
|
||||
|
||||
/**
|
||||
* Interface to separate commanding actions of other objects.
|
||||
@ -15,23 +15,21 @@
|
||||
* - replyReceived(id, step, cause) (if cause == OK, it's a success).
|
||||
*/
|
||||
class CommandsActionsIF {
|
||||
friend class CommandActionHelper;
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::COMMANDS_ACTIONS_IF;
|
||||
static const ReturnValue_t OBJECT_HAS_NO_FUNCTIONS = MAKE_RETURN_CODE(1);
|
||||
static const ReturnValue_t ALREADY_COMMANDING = MAKE_RETURN_CODE(2);
|
||||
virtual ~CommandsActionsIF() {}
|
||||
virtual MessageQueueIF* getCommandQueuePtr() = 0;
|
||||
protected:
|
||||
virtual void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) = 0;
|
||||
virtual void stepFailedReceived(ActionId_t actionId, uint8_t step,
|
||||
ReturnValue_t returnCode) = 0;
|
||||
virtual void dataReceived(ActionId_t actionId, const uint8_t* data,
|
||||
uint32_t size) = 0;
|
||||
virtual void completionSuccessfulReceived(ActionId_t actionId) = 0;
|
||||
virtual void completionFailedReceived(ActionId_t actionId,
|
||||
ReturnValue_t returnCode) = 0;
|
||||
friend class CommandActionHelper;
|
||||
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::COMMANDS_ACTIONS_IF;
|
||||
static const ReturnValue_t OBJECT_HAS_NO_FUNCTIONS = MAKE_RETURN_CODE(1);
|
||||
static const ReturnValue_t ALREADY_COMMANDING = MAKE_RETURN_CODE(2);
|
||||
virtual ~CommandsActionsIF() {}
|
||||
virtual MessageQueueIF* getCommandQueuePtr() = 0;
|
||||
|
||||
protected:
|
||||
virtual void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) = 0;
|
||||
virtual void stepFailedReceived(ActionId_t actionId, uint8_t step, ReturnValue_t returnCode) = 0;
|
||||
virtual void dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) = 0;
|
||||
virtual void completionSuccessfulReceived(ActionId_t actionId) = 0;
|
||||
virtual void completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif /* FSFW_ACTION_COMMANDSACTIONSIF_H_ */
|
||||
|
@ -1,11 +1,11 @@
|
||||
#ifndef FSFW_ACTION_HASACTIONSIF_H_
|
||||
#define FSFW_ACTION_HASACTIONSIF_H_
|
||||
|
||||
#include "../ipc/MessageQueueIF.h"
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
#include "ActionHelper.h"
|
||||
#include "ActionMessage.h"
|
||||
#include "SimpleActionHelper.h"
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
#include "../ipc/MessageQueueIF.h"
|
||||
|
||||
/**
|
||||
* @brief
|
||||
@ -34,30 +34,29 @@
|
||||
* @ingroup interfaces
|
||||
*/
|
||||
class HasActionsIF {
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::HAS_ACTIONS_IF;
|
||||
static const ReturnValue_t IS_BUSY = MAKE_RETURN_CODE(1);
|
||||
static const ReturnValue_t INVALID_PARAMETERS = MAKE_RETURN_CODE(2);
|
||||
static const ReturnValue_t EXECUTION_FINISHED = MAKE_RETURN_CODE(3);
|
||||
static const ReturnValue_t INVALID_ACTION_ID = MAKE_RETURN_CODE(4);
|
||||
virtual ~HasActionsIF() { }
|
||||
/**
|
||||
* Function to get the MessageQueueId_t of the implementing object
|
||||
* @return MessageQueueId_t of the object
|
||||
*/
|
||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||
/**
|
||||
* Execute or initialize the execution of a certain function.
|
||||
* The ActionHelpers will execute this function and behave differently
|
||||
* depending on the returnvalue.
|
||||
*
|
||||
* @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,
|
||||
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) = 0;
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::HAS_ACTIONS_IF;
|
||||
static const ReturnValue_t IS_BUSY = MAKE_RETURN_CODE(1);
|
||||
static const ReturnValue_t INVALID_PARAMETERS = MAKE_RETURN_CODE(2);
|
||||
static const ReturnValue_t EXECUTION_FINISHED = MAKE_RETURN_CODE(3);
|
||||
static const ReturnValue_t INVALID_ACTION_ID = MAKE_RETURN_CODE(4);
|
||||
virtual ~HasActionsIF() {}
|
||||
/**
|
||||
* Function to get the MessageQueueId_t of the implementing object
|
||||
* @return MessageQueueId_t of the object
|
||||
*/
|
||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||
/**
|
||||
* Execute or initialize the execution of a certain function.
|
||||
* The ActionHelpers will execute this function and behave differently
|
||||
* depending on the returnvalue.
|
||||
*
|
||||
* @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, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size) = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif /* FSFW_ACTION_HASACTIONSIF_H_ */
|
||||
|
@ -1,74 +1,67 @@
|
||||
#include "fsfw/action.h"
|
||||
|
||||
SimpleActionHelper::SimpleActionHelper(HasActionsIF* setOwner,
|
||||
MessageQueueIF* useThisQueue) :
|
||||
ActionHelper(setOwner, useThisQueue), isExecuting(false) {
|
||||
}
|
||||
SimpleActionHelper::SimpleActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue)
|
||||
: ActionHelper(setOwner, useThisQueue), isExecuting(false) {}
|
||||
|
||||
SimpleActionHelper::~SimpleActionHelper() {
|
||||
}
|
||||
SimpleActionHelper::~SimpleActionHelper() {}
|
||||
|
||||
void SimpleActionHelper::step(ReturnValue_t result) {
|
||||
// STEP_OFFESET is subtracted to compensate for adding offset in base
|
||||
// method, which is not necessary here.
|
||||
ActionHelper::step(stepCount - STEP_OFFSET, lastCommander, lastAction,
|
||||
result);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
resetHelper();
|
||||
}
|
||||
// STEP_OFFESET is subtracted to compensate for adding offset in base
|
||||
// method, which is not necessary here.
|
||||
ActionHelper::step(stepCount - STEP_OFFSET, lastCommander, lastAction, result);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
resetHelper();
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleActionHelper::finish(ReturnValue_t result) {
|
||||
ActionHelper::finish(lastCommander, lastAction, result);
|
||||
resetHelper();
|
||||
ActionHelper::finish(lastCommander, lastAction, result);
|
||||
resetHelper();
|
||||
}
|
||||
|
||||
ReturnValue_t SimpleActionHelper::reportData(SerializeIF* data) {
|
||||
return ActionHelper::reportData(lastCommander, lastAction, data);
|
||||
return ActionHelper::reportData(lastCommander, lastAction, data);
|
||||
}
|
||||
|
||||
void SimpleActionHelper::resetHelper() {
|
||||
stepCount = 0;
|
||||
isExecuting = false;
|
||||
lastAction = 0;
|
||||
lastCommander = 0;
|
||||
stepCount = 0;
|
||||
isExecuting = false;
|
||||
lastAction = 0;
|
||||
lastCommander = 0;
|
||||
}
|
||||
|
||||
void SimpleActionHelper::prepareExecution(MessageQueueId_t commandedBy,
|
||||
ActionId_t actionId, store_address_t dataAddress) {
|
||||
CommandMessage reply;
|
||||
if (isExecuting) {
|
||||
ipcStore->deleteData(dataAddress);
|
||||
ActionMessage::setStepReply(&reply, actionId, 0,
|
||||
HasActionsIF::IS_BUSY);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
}
|
||||
const uint8_t* dataPtr = NULL;
|
||||
size_t size = 0;
|
||||
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
return;
|
||||
}
|
||||
lastCommander = commandedBy;
|
||||
lastAction = actionId;
|
||||
result = owner->executeAction(actionId, commandedBy, dataPtr, size);
|
||||
void SimpleActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
|
||||
store_address_t dataAddress) {
|
||||
CommandMessage reply;
|
||||
if (isExecuting) {
|
||||
ipcStore->deleteData(dataAddress);
|
||||
switch (result) {
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, HasActionsIF::IS_BUSY);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
}
|
||||
const uint8_t* dataPtr = NULL;
|
||||
size_t size = 0;
|
||||
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
return;
|
||||
}
|
||||
lastCommander = commandedBy;
|
||||
lastAction = actionId;
|
||||
result = owner->executeAction(actionId, commandedBy, dataPtr, size);
|
||||
ipcStore->deleteData(dataAddress);
|
||||
switch (result) {
|
||||
case HasReturnvaluesIF::RETURN_OK:
|
||||
isExecuting = true;
|
||||
stepCount++;
|
||||
break;
|
||||
isExecuting = true;
|
||||
stepCount++;
|
||||
break;
|
||||
case HasActionsIF::EXECUTION_FINISHED:
|
||||
ActionMessage::setCompletionReply(&reply, actionId,
|
||||
true, HasReturnvaluesIF::RETURN_OK);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
break;
|
||||
ActionMessage::setCompletionReply(&reply, actionId, true, HasReturnvaluesIF::RETURN_OK);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
break;
|
||||
default:
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
break;
|
||||
}
|
||||
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -8,23 +8,24 @@
|
||||
* at a time but remembers last commander and last action which
|
||||
* simplifies usage
|
||||
*/
|
||||
class SimpleActionHelper: public ActionHelper {
|
||||
public:
|
||||
SimpleActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
|
||||
virtual ~SimpleActionHelper();
|
||||
void step(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
void finish(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
ReturnValue_t reportData(SerializeIF* data);
|
||||
class SimpleActionHelper : public ActionHelper {
|
||||
public:
|
||||
SimpleActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
|
||||
virtual ~SimpleActionHelper();
|
||||
void step(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
void finish(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
ReturnValue_t reportData(SerializeIF* data);
|
||||
|
||||
protected:
|
||||
void prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
|
||||
store_address_t dataAddress);
|
||||
virtual void resetHelper();
|
||||
private:
|
||||
bool isExecuting;
|
||||
MessageQueueId_t lastCommander = MessageQueueIF::NO_QUEUE;
|
||||
ActionId_t lastAction = 0;
|
||||
uint8_t stepCount = 0;
|
||||
protected:
|
||||
void prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
|
||||
store_address_t dataAddress);
|
||||
virtual void resetHelper();
|
||||
|
||||
private:
|
||||
bool isExecuting;
|
||||
MessageQueueId_t lastCommander = MessageQueueIF::NO_QUEUE;
|
||||
ActionId_t lastAction = 0;
|
||||
uint8_t stepCount = 0;
|
||||
};
|
||||
|
||||
#endif /* SIMPLEACTIONHELPER_H_ */
|
||||
|
@ -1,60 +1,57 @@
|
||||
#include "fsfw/ipc/CommandMessage.h"
|
||||
#include "fsfw/storagemanager/storeAddress.h"
|
||||
#include "fsfw/cfdp/CFDPHandler.h"
|
||||
#include "fsfw/cfdp/CFDPMessage.h"
|
||||
|
||||
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
|
||||
#include "fsfw/cfdp/CFDPMessage.h"
|
||||
#include "fsfw/ipc/CommandMessage.h"
|
||||
#include "fsfw/ipc/QueueFactory.h"
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw/storagemanager/storeAddress.h"
|
||||
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
|
||||
|
||||
object_id_t CFDPHandler::packetSource = 0;
|
||||
object_id_t CFDPHandler::packetDestination = 0;
|
||||
|
||||
CFDPHandler::CFDPHandler(object_id_t setObjectId, CFDPDistributor* dist) : SystemObject(setObjectId) {
|
||||
requestQueue = QueueFactory::instance()->createMessageQueue(CFDP_HANDLER_MAX_RECEPTION);
|
||||
distributor = dist;
|
||||
CFDPHandler::CFDPHandler(object_id_t setObjectId, CFDPDistributor* dist)
|
||||
: SystemObject(setObjectId) {
|
||||
requestQueue = QueueFactory::instance()->createMessageQueue(CFDP_HANDLER_MAX_RECEPTION);
|
||||
distributor = dist;
|
||||
}
|
||||
|
||||
CFDPHandler::~CFDPHandler() {}
|
||||
|
||||
ReturnValue_t CFDPHandler::initialize() {
|
||||
ReturnValue_t result = SystemObject::initialize();
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
this->distributor->registerHandler(this);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
ReturnValue_t result = SystemObject::initialize();
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
this->distributor->registerHandler(this);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t CFDPHandler::handleRequest(store_address_t storeId) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "CFDPHandler::handleRequest" << std::endl;
|
||||
sif::debug << "CFDPHandler::handleRequest" << std::endl;
|
||||
#else
|
||||
sif::printDebug("CFDPHandler::handleRequest\n");
|
||||
sif::printDebug("CFDPHandler::handleRequest\n");
|
||||
#endif /* !FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||
#endif
|
||||
|
||||
//TODO read out packet from store using storeId
|
||||
// TODO read out packet from store using storeId
|
||||
|
||||
return RETURN_OK;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t CFDPHandler::performOperation(uint8_t opCode) {
|
||||
ReturnValue_t status = RETURN_OK;
|
||||
CommandMessage currentMessage;
|
||||
for (status = this->requestQueue->receiveMessage(¤tMessage); status == RETURN_OK;
|
||||
status = this->requestQueue->receiveMessage(¤tMessage)) {
|
||||
store_address_t storeId = CFDPMessage::getStoreId(¤tMessage);
|
||||
this->handleRequest(storeId);
|
||||
}
|
||||
return RETURN_OK;
|
||||
ReturnValue_t status = RETURN_OK;
|
||||
CommandMessage currentMessage;
|
||||
for (status = this->requestQueue->receiveMessage(¤tMessage); status == RETURN_OK;
|
||||
status = this->requestQueue->receiveMessage(¤tMessage)) {
|
||||
store_address_t storeId = CFDPMessage::getStoreId(¤tMessage);
|
||||
this->handleRequest(storeId);
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
uint16_t CFDPHandler::getIdentifier() {
|
||||
return 0;
|
||||
}
|
||||
uint16_t CFDPHandler::getIdentifier() { return 0; }
|
||||
|
||||
MessageQueueId_t CFDPHandler::getRequestQueue() {
|
||||
return this->requestQueue->getId();
|
||||
}
|
||||
MessageQueueId_t CFDPHandler::getRequestQueue() { return this->requestQueue->getId(); }
|
||||
|
@ -1,62 +1,63 @@
|
||||
#ifndef FSFW_CFDP_CFDPHANDLER_H_
|
||||
#define FSFW_CFDP_CFDPHANDLER_H_
|
||||
|
||||
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
||||
#include "fsfw/ipc/MessageQueueIF.h"
|
||||
#include "fsfw/objectmanager/SystemObject.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||
#include "fsfw/tcdistribution/CFDPDistributor.h"
|
||||
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
||||
|
||||
#include "fsfw/ipc/MessageQueueIF.h"
|
||||
|
||||
namespace Factory{
|
||||
namespace Factory {
|
||||
void setStaticFrameworkObjectIds();
|
||||
}
|
||||
|
||||
class CFDPHandler :
|
||||
public ExecutableObjectIF,
|
||||
public AcceptsTelecommandsIF,
|
||||
public SystemObject,
|
||||
public HasReturnvaluesIF {
|
||||
friend void (Factory::setStaticFrameworkObjectIds)();
|
||||
public:
|
||||
CFDPHandler(object_id_t setObjectId, CFDPDistributor* distributor);
|
||||
/**
|
||||
* The destructor is empty.
|
||||
*/
|
||||
virtual ~CFDPHandler();
|
||||
class CFDPHandler : public ExecutableObjectIF,
|
||||
public AcceptsTelecommandsIF,
|
||||
public SystemObject,
|
||||
public HasReturnvaluesIF {
|
||||
friend void(Factory::setStaticFrameworkObjectIds)();
|
||||
|
||||
virtual ReturnValue_t handleRequest(store_address_t storeId);
|
||||
public:
|
||||
CFDPHandler(object_id_t setObjectId, CFDPDistributor* distributor);
|
||||
/**
|
||||
* The destructor is empty.
|
||||
*/
|
||||
virtual ~CFDPHandler();
|
||||
|
||||
virtual ReturnValue_t initialize() override;
|
||||
virtual uint16_t getIdentifier() override;
|
||||
MessageQueueId_t getRequestQueue() override;
|
||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
protected:
|
||||
/**
|
||||
* This is a complete instance of the telecommand reception queue
|
||||
* of the class. It is initialized on construction of the class.
|
||||
*/
|
||||
MessageQueueIF* requestQueue = nullptr;
|
||||
virtual ReturnValue_t handleRequest(store_address_t storeId);
|
||||
|
||||
CFDPDistributor* distributor = nullptr;
|
||||
virtual ReturnValue_t initialize() override;
|
||||
virtual uint16_t getIdentifier() override;
|
||||
MessageQueueId_t getRequestQueue() override;
|
||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
|
||||
/**
|
||||
* The current CFDP packet to be processed.
|
||||
* It is deleted after handleRequest was executed.
|
||||
*/
|
||||
CFDPPacketStored currentPacket;
|
||||
protected:
|
||||
/**
|
||||
* This is a complete instance of the telecommand reception queue
|
||||
* of the class. It is initialized on construction of the class.
|
||||
*/
|
||||
MessageQueueIF* requestQueue = nullptr;
|
||||
|
||||
static object_id_t packetSource;
|
||||
CFDPDistributor* distributor = nullptr;
|
||||
|
||||
static object_id_t packetDestination;
|
||||
private:
|
||||
/**
|
||||
* This constant sets the maximum number of packets accepted per call.
|
||||
* Remember that one packet must be completely handled in one
|
||||
* #handleRequest call.
|
||||
*/
|
||||
static const uint8_t CFDP_HANDLER_MAX_RECEPTION = 100;
|
||||
/**
|
||||
* The current CFDP packet to be processed.
|
||||
* It is deleted after handleRequest was executed.
|
||||
*/
|
||||
CFDPPacketStored currentPacket;
|
||||
|
||||
static object_id_t packetSource;
|
||||
|
||||
static object_id_t packetDestination;
|
||||
|
||||
private:
|
||||
/**
|
||||
* This constant sets the maximum number of packets accepted per call.
|
||||
* Remember that one packet must be completely handled in one
|
||||
* #handleRequest call.
|
||||
*/
|
||||
static const uint8_t CFDP_HANDLER_MAX_RECEPTION = 100;
|
||||
};
|
||||
|
||||
#endif /* FSFW_CFDP_CFDPHANDLER_H_ */
|
||||
|
@ -1,21 +1,17 @@
|
||||
#include "CFDPMessage.h"
|
||||
|
||||
CFDPMessage::CFDPMessage() {
|
||||
}
|
||||
CFDPMessage::CFDPMessage() {}
|
||||
|
||||
CFDPMessage::~CFDPMessage() {
|
||||
}
|
||||
CFDPMessage::~CFDPMessage() {}
|
||||
|
||||
void CFDPMessage::setCommand(CommandMessage *message,
|
||||
store_address_t cfdpPacket) {
|
||||
message->setParameter(cfdpPacket.raw);
|
||||
void CFDPMessage::setCommand(CommandMessage *message, store_address_t cfdpPacket) {
|
||||
message->setParameter(cfdpPacket.raw);
|
||||
}
|
||||
|
||||
store_address_t CFDPMessage::getStoreId(const CommandMessage *message) {
|
||||
store_address_t storeAddressCFDPPacket;
|
||||
storeAddressCFDPPacket = message->getParameter();
|
||||
return storeAddressCFDPPacket;
|
||||
store_address_t storeAddressCFDPPacket;
|
||||
storeAddressCFDPPacket = message->getParameter();
|
||||
return storeAddressCFDPPacket;
|
||||
}
|
||||
|
||||
void CFDPMessage::clear(CommandMessage *message) {
|
||||
}
|
||||
void CFDPMessage::clear(CommandMessage *message) {}
|
||||
|
@ -6,18 +6,18 @@
|
||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||
|
||||
class CFDPMessage {
|
||||
private:
|
||||
CFDPMessage();
|
||||
public:
|
||||
static const uint8_t MESSAGE_ID = messagetypes::CFDP;
|
||||
private:
|
||||
CFDPMessage();
|
||||
|
||||
virtual ~CFDPMessage();
|
||||
static void setCommand(CommandMessage* message,
|
||||
store_address_t cfdpPacket);
|
||||
public:
|
||||
static const uint8_t MESSAGE_ID = messagetypes::CFDP;
|
||||
|
||||
static store_address_t getStoreId(const CommandMessage* message);
|
||||
virtual ~CFDPMessage();
|
||||
static void setCommand(CommandMessage* message, store_address_t cfdpPacket);
|
||||
|
||||
static void clear(CommandMessage* message);
|
||||
static store_address_t getStoreId(const CommandMessage* message);
|
||||
|
||||
static void clear(CommandMessage* message);
|
||||
};
|
||||
|
||||
#endif /* FSFW_CFDP_CFDPMESSAGE_H_ */
|
||||
|
@ -6,78 +6,73 @@
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
struct FileSize: public SerializeIF {
|
||||
public:
|
||||
FileSize(): largeFile(false) {};
|
||||
struct FileSize : public SerializeIF {
|
||||
public:
|
||||
FileSize() : largeFile(false){};
|
||||
|
||||
FileSize(uint64_t fileSize, bool isLarge = false) {
|
||||
setFileSize(fileSize, isLarge);
|
||||
};
|
||||
FileSize(uint64_t fileSize, bool isLarge = false) { setFileSize(fileSize, isLarge); };
|
||||
|
||||
ReturnValue_t serialize(bool isLarge, uint8_t **buffer, size_t *size,size_t maxSize,
|
||||
Endianness streamEndianness) {
|
||||
this->largeFile = isLarge;
|
||||
return serialize(buffer, size, maxSize, streamEndianness);
|
||||
ReturnValue_t serialize(bool isLarge, uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) {
|
||||
this->largeFile = isLarge;
|
||||
return serialize(buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const override {
|
||||
if (not largeFile) {
|
||||
uint32_t fileSizeTyped = fileSize;
|
||||
return SerializeAdapter::serialize(&fileSizeTyped, buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
return SerializeAdapter::serialize(&fileSize, buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size,size_t maxSize,
|
||||
Endianness streamEndianness) const override {
|
||||
if(not largeFile) {
|
||||
uint32_t fileSizeTyped = fileSize;
|
||||
return SerializeAdapter::serialize(&fileSizeTyped, buffer, size, maxSize,
|
||||
streamEndianness);
|
||||
size_t getSerializedSize() const override {
|
||||
if (largeFile) {
|
||||
return 8;
|
||||
} else {
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return SerializeAdapter::serialize(&fileSize, buffer, size, maxSize, streamEndianness);
|
||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override {
|
||||
if (largeFile) {
|
||||
return SerializeAdapter::deSerialize(&size, buffer, size, streamEndianness);
|
||||
} else {
|
||||
uint32_t sizeTmp = 0;
|
||||
ReturnValue_t result =
|
||||
SerializeAdapter::deSerialize(&sizeTmp, buffer, size, streamEndianness);
|
||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||
fileSize = sizeTmp;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
size_t getSerializedSize() const override {
|
||||
if (largeFile) {
|
||||
return 8;
|
||||
} else {
|
||||
return 4;
|
||||
}
|
||||
ReturnValue_t setFileSize(uint64_t fileSize, bool largeFile) {
|
||||
if (not largeFile and fileSize > UINT32_MAX) {
|
||||
// TODO: emit warning here
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
this->fileSize = fileSize;
|
||||
this->largeFile = largeFile;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override {
|
||||
if(largeFile) {
|
||||
return SerializeAdapter::deSerialize(&size, buffer, size, streamEndianness);
|
||||
} else {
|
||||
uint32_t sizeTmp = 0;
|
||||
ReturnValue_t result = SerializeAdapter::deSerialize(&sizeTmp, buffer, size,
|
||||
streamEndianness);
|
||||
if(result == HasReturnvaluesIF::RETURN_OK) {
|
||||
fileSize = sizeTmp;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
bool isLargeFile() const { return largeFile; }
|
||||
uint64_t getSize(bool *largeFile = nullptr) const {
|
||||
if (largeFile != nullptr) {
|
||||
*largeFile = this->largeFile;
|
||||
}
|
||||
return fileSize;
|
||||
}
|
||||
|
||||
ReturnValue_t setFileSize(uint64_t fileSize, bool largeFile) {
|
||||
if (not largeFile and fileSize > UINT32_MAX) {
|
||||
// TODO: emit warning here
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
this->fileSize = fileSize;
|
||||
this->largeFile = largeFile;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
bool isLargeFile() const {
|
||||
return largeFile;
|
||||
}
|
||||
uint64_t getSize(bool* largeFile = nullptr) const {
|
||||
if(largeFile != nullptr) {
|
||||
*largeFile = this->largeFile;
|
||||
}
|
||||
return fileSize;
|
||||
}
|
||||
private:
|
||||
uint64_t fileSize = 0;
|
||||
bool largeFile = false;
|
||||
private:
|
||||
uint64_t fileSize = 0;
|
||||
bool largeFile = false;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace cfdp
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_FILESIZE_H_ */
|
||||
|
@ -2,10 +2,12 @@
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_DEFINITIONS_H_
|
||||
|
||||
#include <fsfw/serialize/SerializeIF.h>
|
||||
#include <cstdint>
|
||||
|
||||
#include <cstddef>
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include <cstdint>
|
||||
|
||||
#include "fsfw/returnvalues/FwClassIds.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
@ -14,140 +16,122 @@ static constexpr uint8_t VERSION_BITS = 0b00100000;
|
||||
static constexpr uint8_t CFDP_CLASS_ID = CLASS_ID::CFDP;
|
||||
|
||||
static constexpr ReturnValue_t INVALID_TLV_TYPE =
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 1);
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 1);
|
||||
static constexpr ReturnValue_t INVALID_DIRECTIVE_FIELDS =
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 2);
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 2);
|
||||
static constexpr ReturnValue_t INVALID_PDU_DATAFIELD_LEN =
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 3);
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 3);
|
||||
static constexpr ReturnValue_t INVALID_ACK_DIRECTIVE_FIELDS =
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 4);
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 4);
|
||||
//! Can not parse options. This can also occur because there are options
|
||||
//! available but the user did not pass a valid options array
|
||||
static constexpr ReturnValue_t METADATA_CANT_PARSE_OPTIONS =
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 5);
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 5);
|
||||
static constexpr ReturnValue_t NAK_CANT_PARSE_OPTIONS =
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 6);
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 6);
|
||||
static constexpr ReturnValue_t FINISHED_CANT_PARSE_FS_RESPONSES =
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 6);
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 6);
|
||||
static constexpr ReturnValue_t FILESTORE_REQUIRES_SECOND_FILE =
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 8);
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 8);
|
||||
//! Can not parse filestore response because user did not pass a valid instance
|
||||
//! or remaining size is invalid
|
||||
static constexpr ReturnValue_t FILESTORE_RESPONSE_CANT_PARSE_FS_MESSAGE =
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 9);
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 9);
|
||||
|
||||
//! Checksum types according to the SANA Checksum Types registry
|
||||
//! https://sanaregistry.org/r/checksum_identifiers/
|
||||
enum ChecksumType {
|
||||
// Modular legacy checksum
|
||||
MODULAR = 0,
|
||||
CRC_32_PROXIMITY_1 = 1,
|
||||
CRC_32C = 2,
|
||||
CRC_32 = 3,
|
||||
NULL_CHECKSUM = 15
|
||||
// Modular legacy checksum
|
||||
MODULAR = 0,
|
||||
CRC_32_PROXIMITY_1 = 1,
|
||||
CRC_32C = 2,
|
||||
CRC_32 = 3,
|
||||
NULL_CHECKSUM = 15
|
||||
};
|
||||
|
||||
enum PduType: bool {
|
||||
FILE_DIRECTIVE = 0,
|
||||
FILE_DATA = 1
|
||||
enum PduType : bool { FILE_DIRECTIVE = 0, FILE_DATA = 1 };
|
||||
|
||||
enum TransmissionModes : bool { ACKNOWLEDGED = 0, UNACKNOWLEDGED = 1 };
|
||||
|
||||
enum SegmentMetadataFlag : bool { NOT_PRESENT = 0, PRESENT = 1 };
|
||||
|
||||
enum Direction : bool { TOWARDS_RECEIVER = 0, TOWARDS_SENDER = 1 };
|
||||
|
||||
enum SegmentationControl : bool {
|
||||
NO_RECORD_BOUNDARIES_PRESERVATION = 0,
|
||||
RECORD_BOUNDARIES_PRESERVATION = 1
|
||||
};
|
||||
|
||||
enum TransmissionModes: bool {
|
||||
ACKNOWLEDGED = 0,
|
||||
UNACKNOWLEDGED = 1
|
||||
enum WidthInBytes : uint8_t {
|
||||
// Only those are supported for now
|
||||
ONE_BYTE = 1,
|
||||
TWO_BYTES = 2,
|
||||
FOUR_BYTES = 4,
|
||||
};
|
||||
|
||||
enum SegmentMetadataFlag: bool {
|
||||
NOT_PRESENT = 0,
|
||||
PRESENT = 1
|
||||
enum FileDirectives : uint8_t {
|
||||
INVALID_DIRECTIVE = 0x0f,
|
||||
EOF_DIRECTIVE = 0x04,
|
||||
FINISH = 0x05,
|
||||
ACK = 0x06,
|
||||
METADATA = 0x07,
|
||||
NAK = 0x08,
|
||||
PROMPT = 0x09,
|
||||
KEEP_ALIVE = 0x0c
|
||||
};
|
||||
|
||||
enum Direction: bool {
|
||||
TOWARDS_RECEIVER = 0,
|
||||
TOWARDS_SENDER = 1
|
||||
};
|
||||
|
||||
enum SegmentationControl: bool {
|
||||
NO_RECORD_BOUNDARIES_PRESERVATION = 0,
|
||||
RECORD_BOUNDARIES_PRESERVATION = 1
|
||||
};
|
||||
|
||||
enum WidthInBytes: uint8_t {
|
||||
// Only those are supported for now
|
||||
ONE_BYTE = 1,
|
||||
TWO_BYTES = 2,
|
||||
FOUR_BYTES = 4,
|
||||
};
|
||||
|
||||
enum FileDirectives: uint8_t {
|
||||
INVALID_DIRECTIVE = 0x0f,
|
||||
EOF_DIRECTIVE = 0x04,
|
||||
FINISH = 0x05,
|
||||
ACK = 0x06,
|
||||
METADATA = 0x07,
|
||||
NAK = 0x08,
|
||||
PROMPT = 0x09,
|
||||
KEEP_ALIVE = 0x0c
|
||||
};
|
||||
|
||||
enum ConditionCode: uint8_t {
|
||||
NO_CONDITION_FIELD = 0xff,
|
||||
NO_ERROR = 0b0000,
|
||||
POSITIVE_ACK_LIMIT_REACHED = 0b0001,
|
||||
KEEP_ALIVE_LIMIT_REACHED = 0b0010,
|
||||
INVALID_TRANSMISSION_MODE = 0b0011,
|
||||
FILESTORE_REJECTION = 0b0100,
|
||||
FILE_CHECKSUM_FAILURE = 0b0101,
|
||||
FILE_SIZE_ERROR = 0b0110,
|
||||
NAK_LIMIT_REACHED = 0b0111,
|
||||
INACTIVITY_DETECTED = 0b1000,
|
||||
CHECK_LIMIT_REACHED = 0b1010,
|
||||
UNSUPPORTED_CHECKSUM_TYPE = 0b1011,
|
||||
SUSPEND_REQUEST_RECEIVED = 0b1110,
|
||||
CANCEL_REQUEST_RECEIVED = 0b1111
|
||||
enum ConditionCode : uint8_t {
|
||||
NO_CONDITION_FIELD = 0xff,
|
||||
NO_ERROR = 0b0000,
|
||||
POSITIVE_ACK_LIMIT_REACHED = 0b0001,
|
||||
KEEP_ALIVE_LIMIT_REACHED = 0b0010,
|
||||
INVALID_TRANSMISSION_MODE = 0b0011,
|
||||
FILESTORE_REJECTION = 0b0100,
|
||||
FILE_CHECKSUM_FAILURE = 0b0101,
|
||||
FILE_SIZE_ERROR = 0b0110,
|
||||
NAK_LIMIT_REACHED = 0b0111,
|
||||
INACTIVITY_DETECTED = 0b1000,
|
||||
CHECK_LIMIT_REACHED = 0b1010,
|
||||
UNSUPPORTED_CHECKSUM_TYPE = 0b1011,
|
||||
SUSPEND_REQUEST_RECEIVED = 0b1110,
|
||||
CANCEL_REQUEST_RECEIVED = 0b1111
|
||||
};
|
||||
|
||||
enum AckTransactionStatus {
|
||||
UNDEFINED = 0b00,
|
||||
ACTIVE = 0b01,
|
||||
TERMINATED = 0b10,
|
||||
UNRECOGNIZED = 0b11
|
||||
UNDEFINED = 0b00,
|
||||
ACTIVE = 0b01,
|
||||
TERMINATED = 0b10,
|
||||
UNRECOGNIZED = 0b11
|
||||
};
|
||||
|
||||
enum FinishedDeliveryCode {
|
||||
DATA_COMPLETE = 0,
|
||||
DATA_INCOMPLETE = 1
|
||||
};
|
||||
enum FinishedDeliveryCode { DATA_COMPLETE = 0, DATA_INCOMPLETE = 1 };
|
||||
|
||||
enum FinishedFileStatus {
|
||||
DISCARDED_DELIBERATELY = 0,
|
||||
DISCARDED_FILESTORE_REJECTION = 1,
|
||||
RETAINED_IN_FILESTORE = 2,
|
||||
FILE_STATUS_UNREPORTED = 3
|
||||
DISCARDED_DELIBERATELY = 0,
|
||||
DISCARDED_FILESTORE_REJECTION = 1,
|
||||
RETAINED_IN_FILESTORE = 2,
|
||||
FILE_STATUS_UNREPORTED = 3
|
||||
};
|
||||
|
||||
enum PromptResponseRequired: bool {
|
||||
PROMPT_NAK = 0,
|
||||
PROMPT_KEEP_ALIVE = 1
|
||||
};
|
||||
enum PromptResponseRequired : bool { PROMPT_NAK = 0, PROMPT_KEEP_ALIVE = 1 };
|
||||
|
||||
enum TlvTypes: uint8_t {
|
||||
FILESTORE_REQUEST = 0x00,
|
||||
FILESTORE_RESPONSE = 0x01,
|
||||
MSG_TO_USER = 0x02,
|
||||
FAULT_HANDLER = 0x04,
|
||||
FLOW_LABEL = 0x05,
|
||||
ENTITY_ID = 0x06,
|
||||
INVALID_TLV = 0xff,
|
||||
enum TlvTypes : uint8_t {
|
||||
FILESTORE_REQUEST = 0x00,
|
||||
FILESTORE_RESPONSE = 0x01,
|
||||
MSG_TO_USER = 0x02,
|
||||
FAULT_HANDLER = 0x04,
|
||||
FLOW_LABEL = 0x05,
|
||||
ENTITY_ID = 0x06,
|
||||
INVALID_TLV = 0xff,
|
||||
};
|
||||
|
||||
enum RecordContinuationState {
|
||||
NO_START_NO_END = 0b00,
|
||||
CONTAINS_START_NO_END = 0b01,
|
||||
CONTAINS_END_NO_START = 0b10,
|
||||
CONTAINS_START_AND_END = 0b11
|
||||
NO_START_NO_END = 0b00,
|
||||
CONTAINS_START_NO_END = 0b01,
|
||||
CONTAINS_END_NO_START = 0b10,
|
||||
CONTAINS_START_AND_END = 0b11
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace cfdp
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_DEFINITIONS_H_ */
|
||||
|
@ -1,52 +1,45 @@
|
||||
#include "AckInfo.h"
|
||||
|
||||
AckInfo::AckInfo(cfdp::FileDirectives ackedDirective, cfdp::ConditionCode ackedConditionCode,
|
||||
cfdp::AckTransactionStatus transactionStatus, uint8_t directiveSubtypeCode):
|
||||
ackedDirective(ackedDirective), ackedConditionCode(ackedConditionCode),
|
||||
transactionStatus(transactionStatus), directiveSubtypeCode(directiveSubtypeCode) {
|
||||
if (ackedDirective == cfdp::FileDirectives::FINISH) {
|
||||
this->directiveSubtypeCode = 0b0001;
|
||||
} else {
|
||||
this->directiveSubtypeCode = 0b0000;
|
||||
}
|
||||
cfdp::AckTransactionStatus transactionStatus, uint8_t directiveSubtypeCode)
|
||||
: ackedDirective(ackedDirective),
|
||||
ackedConditionCode(ackedConditionCode),
|
||||
transactionStatus(transactionStatus),
|
||||
directiveSubtypeCode(directiveSubtypeCode) {
|
||||
if (ackedDirective == cfdp::FileDirectives::FINISH) {
|
||||
this->directiveSubtypeCode = 0b0001;
|
||||
} else {
|
||||
this->directiveSubtypeCode = 0b0000;
|
||||
}
|
||||
}
|
||||
|
||||
cfdp::ConditionCode AckInfo::getAckedConditionCode() const {
|
||||
return ackedConditionCode;
|
||||
}
|
||||
cfdp::ConditionCode AckInfo::getAckedConditionCode() const { return ackedConditionCode; }
|
||||
|
||||
void AckInfo::setAckedConditionCode(cfdp::ConditionCode ackedConditionCode) {
|
||||
this->ackedConditionCode = ackedConditionCode;
|
||||
if (ackedDirective == cfdp::FileDirectives::FINISH) {
|
||||
this->directiveSubtypeCode = 0b0001;
|
||||
} else {
|
||||
this->directiveSubtypeCode = 0b0000;
|
||||
}
|
||||
this->ackedConditionCode = ackedConditionCode;
|
||||
if (ackedDirective == cfdp::FileDirectives::FINISH) {
|
||||
this->directiveSubtypeCode = 0b0001;
|
||||
} else {
|
||||
this->directiveSubtypeCode = 0b0000;
|
||||
}
|
||||
}
|
||||
|
||||
cfdp::FileDirectives AckInfo::getAckedDirective() const {
|
||||
return ackedDirective;
|
||||
}
|
||||
cfdp::FileDirectives AckInfo::getAckedDirective() const { return ackedDirective; }
|
||||
|
||||
void AckInfo::setAckedDirective(cfdp::FileDirectives ackedDirective) {
|
||||
this->ackedDirective = ackedDirective;
|
||||
this->ackedDirective = ackedDirective;
|
||||
}
|
||||
|
||||
uint8_t AckInfo::getDirectiveSubtypeCode() const {
|
||||
return directiveSubtypeCode;
|
||||
}
|
||||
uint8_t AckInfo::getDirectiveSubtypeCode() const { return directiveSubtypeCode; }
|
||||
|
||||
void AckInfo::setDirectiveSubtypeCode(uint8_t directiveSubtypeCode) {
|
||||
this->directiveSubtypeCode = directiveSubtypeCode;
|
||||
this->directiveSubtypeCode = directiveSubtypeCode;
|
||||
}
|
||||
|
||||
cfdp::AckTransactionStatus AckInfo::getTransactionStatus() const {
|
||||
return transactionStatus;
|
||||
}
|
||||
cfdp::AckTransactionStatus AckInfo::getTransactionStatus() const { return transactionStatus; }
|
||||
|
||||
AckInfo::AckInfo() {
|
||||
}
|
||||
AckInfo::AckInfo() {}
|
||||
|
||||
void AckInfo::setTransactionStatus(cfdp::AckTransactionStatus transactionStatus) {
|
||||
this->transactionStatus = transactionStatus;
|
||||
this->transactionStatus = transactionStatus;
|
||||
}
|
||||
|
@ -4,30 +4,28 @@
|
||||
#include "../definitions.h"
|
||||
|
||||
class AckInfo {
|
||||
public:
|
||||
AckInfo();
|
||||
AckInfo(cfdp::FileDirectives ackedDirective, cfdp::ConditionCode ackedConditionCode,
|
||||
cfdp::AckTransactionStatus transactionStatus, uint8_t directiveSubtypeCode = 0);
|
||||
public:
|
||||
AckInfo();
|
||||
AckInfo(cfdp::FileDirectives ackedDirective, cfdp::ConditionCode ackedConditionCode,
|
||||
cfdp::AckTransactionStatus transactionStatus, uint8_t directiveSubtypeCode = 0);
|
||||
|
||||
cfdp::ConditionCode getAckedConditionCode() const;
|
||||
void setAckedConditionCode(cfdp::ConditionCode ackedConditionCode);
|
||||
cfdp::ConditionCode getAckedConditionCode() const;
|
||||
void setAckedConditionCode(cfdp::ConditionCode ackedConditionCode);
|
||||
|
||||
cfdp::FileDirectives getAckedDirective() const;
|
||||
void setAckedDirective(cfdp::FileDirectives ackedDirective);
|
||||
cfdp::FileDirectives getAckedDirective() const;
|
||||
void setAckedDirective(cfdp::FileDirectives ackedDirective);
|
||||
|
||||
uint8_t getDirectiveSubtypeCode() const;
|
||||
void setDirectiveSubtypeCode(uint8_t directiveSubtypeCode);
|
||||
uint8_t getDirectiveSubtypeCode() const;
|
||||
void setDirectiveSubtypeCode(uint8_t directiveSubtypeCode);
|
||||
|
||||
cfdp::AckTransactionStatus getTransactionStatus() const;
|
||||
void setTransactionStatus(cfdp::AckTransactionStatus transactionStatus);
|
||||
cfdp::AckTransactionStatus getTransactionStatus() const;
|
||||
void setTransactionStatus(cfdp::AckTransactionStatus transactionStatus);
|
||||
|
||||
private:
|
||||
cfdp::FileDirectives ackedDirective = cfdp::FileDirectives::INVALID_DIRECTIVE;
|
||||
cfdp::ConditionCode ackedConditionCode = cfdp::ConditionCode::NO_CONDITION_FIELD;
|
||||
cfdp::AckTransactionStatus transactionStatus = cfdp::AckTransactionStatus::UNDEFINED;
|
||||
uint8_t directiveSubtypeCode = 0;
|
||||
private:
|
||||
cfdp::FileDirectives ackedDirective = cfdp::FileDirectives::INVALID_DIRECTIVE;
|
||||
cfdp::ConditionCode ackedConditionCode = cfdp::ConditionCode::NO_CONDITION_FIELD;
|
||||
cfdp::AckTransactionStatus transactionStatus = cfdp::AckTransactionStatus::UNDEFINED;
|
||||
uint8_t directiveSubtypeCode = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_ACKINFO_H_ */
|
||||
|
@ -1,38 +1,37 @@
|
||||
#include "AckPduDeserializer.h"
|
||||
|
||||
AckPduDeserializer::AckPduDeserializer(const uint8_t *pduBuf, size_t maxSize, AckInfo& info):
|
||||
FileDirectiveDeserializer(pduBuf, maxSize), info(info) {
|
||||
}
|
||||
AckPduDeserializer::AckPduDeserializer(const uint8_t* pduBuf, size_t maxSize, AckInfo& info)
|
||||
: FileDirectiveDeserializer(pduBuf, maxSize), info(info) {}
|
||||
|
||||
ReturnValue_t AckPduDeserializer::parseData() {
|
||||
ReturnValue_t result = FileDirectiveDeserializer::parseData();
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
size_t currentIdx = FileDirectiveDeserializer::getHeaderSize();
|
||||
if (currentIdx + 2 > this->maxSize) {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
if(not checkAndSetCodes(rawPtr[currentIdx], rawPtr[currentIdx + 1])) {
|
||||
return cfdp::INVALID_ACK_DIRECTIVE_FIELDS;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
ReturnValue_t result = FileDirectiveDeserializer::parseData();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
size_t currentIdx = FileDirectiveDeserializer::getHeaderSize();
|
||||
if (currentIdx + 2 > this->maxSize) {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
if (not checkAndSetCodes(rawPtr[currentIdx], rawPtr[currentIdx + 1])) {
|
||||
return cfdp::INVALID_ACK_DIRECTIVE_FIELDS;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
bool AckPduDeserializer::checkAndSetCodes(uint8_t firstByte, uint8_t secondByte) {
|
||||
uint8_t ackedDirective = static_cast<cfdp::FileDirectives>(firstByte >> 4);
|
||||
uint8_t ackedDirective = static_cast<cfdp::FileDirectives>(firstByte >> 4);
|
||||
|
||||
if(ackedDirective != cfdp::FileDirectives::EOF_DIRECTIVE and
|
||||
ackedDirective != cfdp::FileDirectives::FINISH) {
|
||||
return false;
|
||||
}
|
||||
this->info.setAckedDirective(static_cast<cfdp::FileDirectives>(ackedDirective));
|
||||
uint8_t directiveSubtypeCode = firstByte & 0x0f;
|
||||
if(directiveSubtypeCode != 0b0000 and directiveSubtypeCode != 0b0001) {
|
||||
return false;
|
||||
}
|
||||
this->info.setDirectiveSubtypeCode(directiveSubtypeCode);
|
||||
this->info.setAckedConditionCode(static_cast<cfdp::ConditionCode>(secondByte >> 4));
|
||||
this->info.setTransactionStatus(static_cast<cfdp::AckTransactionStatus>(secondByte & 0x0f));
|
||||
return true;
|
||||
if (ackedDirective != cfdp::FileDirectives::EOF_DIRECTIVE and
|
||||
ackedDirective != cfdp::FileDirectives::FINISH) {
|
||||
return false;
|
||||
}
|
||||
this->info.setAckedDirective(static_cast<cfdp::FileDirectives>(ackedDirective));
|
||||
uint8_t directiveSubtypeCode = firstByte & 0x0f;
|
||||
if (directiveSubtypeCode != 0b0000 and directiveSubtypeCode != 0b0001) {
|
||||
return false;
|
||||
}
|
||||
this->info.setDirectiveSubtypeCode(directiveSubtypeCode);
|
||||
this->info.setAckedConditionCode(static_cast<cfdp::ConditionCode>(secondByte >> 4));
|
||||
this->info.setTransactionStatus(static_cast<cfdp::AckTransactionStatus>(secondByte & 0x0f));
|
||||
return true;
|
||||
}
|
||||
|
@ -1,26 +1,23 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_ACKPDUDESERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_ACKPDUDESERIALIZER_H_
|
||||
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveDeserializer.h"
|
||||
#include "AckInfo.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveDeserializer.h"
|
||||
|
||||
class AckPduDeserializer: public FileDirectiveDeserializer {
|
||||
public:
|
||||
AckPduDeserializer(const uint8_t* pduBuf, size_t maxSize, AckInfo& info);
|
||||
class AckPduDeserializer : public FileDirectiveDeserializer {
|
||||
public:
|
||||
AckPduDeserializer(const uint8_t* pduBuf, size_t maxSize, AckInfo& info);
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
* - cfdp::INVALID_DIRECTIVE_FIELDS: Invalid fields
|
||||
*/
|
||||
ReturnValue_t parseData();
|
||||
|
||||
private:
|
||||
bool checkAndSetCodes(uint8_t rawAckedByte, uint8_t rawAckedConditionCode);
|
||||
AckInfo& info;
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
* - cfdp::INVALID_DIRECTIVE_FIELDS: Invalid fields
|
||||
*/
|
||||
ReturnValue_t parseData();
|
||||
|
||||
private:
|
||||
bool checkAndSetCodes(uint8_t rawAckedByte, uint8_t rawAckedConditionCode);
|
||||
AckInfo& info;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_ACKPDUDESERIALIZER_H_ */
|
||||
|
@ -1,38 +1,36 @@
|
||||
#include "AckPduSerializer.h"
|
||||
|
||||
AckPduSerializer::AckPduSerializer(AckInfo& ackInfo, PduConfig &pduConf):
|
||||
FileDirectiveSerializer(pduConf, cfdp::FileDirectives::ACK, 2),
|
||||
ackInfo(ackInfo) {
|
||||
}
|
||||
AckPduSerializer::AckPduSerializer(AckInfo &ackInfo, PduConfig &pduConf)
|
||||
: FileDirectiveSerializer(pduConf, cfdp::FileDirectives::ACK, 2), ackInfo(ackInfo) {}
|
||||
|
||||
size_t AckPduSerializer::getSerializedSize() const {
|
||||
return FileDirectiveSerializer::getWholePduSize();
|
||||
return FileDirectiveSerializer::getWholePduSize();
|
||||
}
|
||||
|
||||
ReturnValue_t AckPduSerializer::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result = FileDirectiveSerializer::serialize(buffer, size, maxSize,
|
||||
streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
cfdp::FileDirectives ackedDirective = ackInfo.getAckedDirective();
|
||||
uint8_t directiveSubtypeCode = ackInfo.getDirectiveSubtypeCode();
|
||||
cfdp::ConditionCode ackedConditionCode = ackInfo.getAckedConditionCode();
|
||||
cfdp::AckTransactionStatus transactionStatus = ackInfo.getTransactionStatus();
|
||||
if(ackedDirective != cfdp::FileDirectives::FINISH and
|
||||
ackedDirective != cfdp::FileDirectives::EOF_DIRECTIVE) {
|
||||
// TODO: better returncode
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
if(*size + 2 > maxSize) {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = ackedDirective << 4 | directiveSubtypeCode;
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
**buffer = ackedConditionCode << 4 | transactionStatus;
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result =
|
||||
FileDirectiveSerializer::serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
cfdp::FileDirectives ackedDirective = ackInfo.getAckedDirective();
|
||||
uint8_t directiveSubtypeCode = ackInfo.getDirectiveSubtypeCode();
|
||||
cfdp::ConditionCode ackedConditionCode = ackInfo.getAckedConditionCode();
|
||||
cfdp::AckTransactionStatus transactionStatus = ackInfo.getTransactionStatus();
|
||||
if (ackedDirective != cfdp::FileDirectives::FINISH and
|
||||
ackedDirective != cfdp::FileDirectives::EOF_DIRECTIVE) {
|
||||
// TODO: better returncode
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
if (*size + 2 > maxSize) {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = ackedDirective << 4 | directiveSubtypeCode;
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
**buffer = ackedConditionCode << 4 | transactionStatus;
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
@ -5,26 +5,26 @@
|
||||
#include "FileDirectiveDeserializer.h"
|
||||
#include "FileDirectiveSerializer.h"
|
||||
|
||||
class AckPduSerializer: public FileDirectiveSerializer {
|
||||
public:
|
||||
/**
|
||||
* @brief Serializer to pack ACK PDUs
|
||||
* @details
|
||||
* Please note that only Finished PDUs and EOF are acknowledged.
|
||||
* @param ackedDirective
|
||||
* @param ackedConditionCode
|
||||
* @param transactionStatus
|
||||
* @param pduConf
|
||||
*/
|
||||
AckPduSerializer(AckInfo& ackInfo, PduConfig& pduConf);
|
||||
class AckPduSerializer : public FileDirectiveSerializer {
|
||||
public:
|
||||
/**
|
||||
* @brief Serializer to pack ACK PDUs
|
||||
* @details
|
||||
* Please note that only Finished PDUs and EOF are acknowledged.
|
||||
* @param ackedDirective
|
||||
* @param ackedConditionCode
|
||||
* @param transactionStatus
|
||||
* @param pduConf
|
||||
*/
|
||||
AckPduSerializer(AckInfo& ackInfo, PduConfig& pduConf);
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
private:
|
||||
AckInfo& ackInfo;
|
||||
private:
|
||||
AckInfo& ackInfo;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_ACKPDUSERIALIZER_H_ */
|
||||
|
@ -1,58 +1,47 @@
|
||||
#include "EofInfo.h"
|
||||
|
||||
EofInfo::EofInfo(cfdp::ConditionCode conditionCode, uint32_t checksum, cfdp::FileSize fileSize,
|
||||
EntityIdTlv* faultLoc): conditionCode(conditionCode), checksum(checksum),
|
||||
fileSize(fileSize), faultLoc(faultLoc) {
|
||||
}
|
||||
EntityIdTlv* faultLoc)
|
||||
: conditionCode(conditionCode), checksum(checksum), fileSize(fileSize), faultLoc(faultLoc) {}
|
||||
|
||||
EofInfo::EofInfo(EntityIdTlv *faultLoc): conditionCode(cfdp::ConditionCode::NO_CONDITION_FIELD),
|
||||
checksum(0), fileSize(0), faultLoc(faultLoc) {
|
||||
}
|
||||
EofInfo::EofInfo(EntityIdTlv* faultLoc)
|
||||
: conditionCode(cfdp::ConditionCode::NO_CONDITION_FIELD),
|
||||
checksum(0),
|
||||
fileSize(0),
|
||||
faultLoc(faultLoc) {}
|
||||
|
||||
uint32_t EofInfo::getChecksum() const {
|
||||
return checksum;
|
||||
}
|
||||
uint32_t EofInfo::getChecksum() const { return checksum; }
|
||||
|
||||
cfdp::ConditionCode EofInfo::getConditionCode() const {
|
||||
return conditionCode;
|
||||
}
|
||||
cfdp::ConditionCode EofInfo::getConditionCode() const { return conditionCode; }
|
||||
|
||||
EntityIdTlv* EofInfo::getFaultLoc() const {
|
||||
return faultLoc;
|
||||
}
|
||||
EntityIdTlv* EofInfo::getFaultLoc() const { return faultLoc; }
|
||||
|
||||
cfdp::FileSize& EofInfo::getFileSize() {
|
||||
return fileSize;
|
||||
}
|
||||
cfdp::FileSize& EofInfo::getFileSize() { return fileSize; }
|
||||
|
||||
void EofInfo::setChecksum(uint32_t checksum) {
|
||||
this->checksum = checksum;
|
||||
}
|
||||
void EofInfo::setChecksum(uint32_t checksum) { this->checksum = checksum; }
|
||||
|
||||
void EofInfo::setConditionCode(cfdp::ConditionCode conditionCode) {
|
||||
this->conditionCode = conditionCode;
|
||||
this->conditionCode = conditionCode;
|
||||
}
|
||||
|
||||
void EofInfo::setFaultLoc(EntityIdTlv *faultLoc) {
|
||||
this->faultLoc = faultLoc;
|
||||
}
|
||||
void EofInfo::setFaultLoc(EntityIdTlv* faultLoc) { this->faultLoc = faultLoc; }
|
||||
|
||||
size_t EofInfo::getSerializedSize(bool fssLarge) {
|
||||
// Condition code + spare + 4 byte checksum
|
||||
size_t size = 5;
|
||||
if(fssLarge) {
|
||||
size += 8;
|
||||
} else {
|
||||
size += 4;
|
||||
}
|
||||
// Do not account for fault location if the condition code is NO_ERROR. We assume that
|
||||
// a serializer will not serialize the fault location here.
|
||||
if(getFaultLoc() != nullptr and getConditionCode() != cfdp::ConditionCode::NO_ERROR) {
|
||||
size+= faultLoc->getSerializedSize();
|
||||
}
|
||||
return size;
|
||||
// Condition code + spare + 4 byte checksum
|
||||
size_t size = 5;
|
||||
if (fssLarge) {
|
||||
size += 8;
|
||||
} else {
|
||||
size += 4;
|
||||
}
|
||||
// Do not account for fault location if the condition code is NO_ERROR. We assume that
|
||||
// a serializer will not serialize the fault location here.
|
||||
if (getFaultLoc() != nullptr and getConditionCode() != cfdp::ConditionCode::NO_ERROR) {
|
||||
size += faultLoc->getSerializedSize();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
ReturnValue_t EofInfo::setFileSize(size_t fileSize, bool isLarge) {
|
||||
return this->fileSize.setFileSize(fileSize, isLarge);
|
||||
return this->fileSize.setFileSize(fileSize, isLarge);
|
||||
}
|
||||
|
@ -1,33 +1,33 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_EOFINFO_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_EOFINFO_H_
|
||||
|
||||
#include "fsfw/cfdp/tlv/EntityIdTlv.h"
|
||||
#include "../definitions.h"
|
||||
#include "../FileSize.h"
|
||||
#include "../definitions.h"
|
||||
#include "fsfw/cfdp/tlv/EntityIdTlv.h"
|
||||
|
||||
struct EofInfo {
|
||||
public:
|
||||
EofInfo(EntityIdTlv* faultLoc = nullptr);
|
||||
EofInfo(cfdp::ConditionCode conditionCode, uint32_t checksum, cfdp::FileSize fileSize,
|
||||
EntityIdTlv* faultLoc = nullptr);
|
||||
public:
|
||||
EofInfo(EntityIdTlv* faultLoc = nullptr);
|
||||
EofInfo(cfdp::ConditionCode conditionCode, uint32_t checksum, cfdp::FileSize fileSize,
|
||||
EntityIdTlv* faultLoc = nullptr);
|
||||
|
||||
size_t getSerializedSize(bool fssLarge = false);
|
||||
size_t getSerializedSize(bool fssLarge = false);
|
||||
|
||||
uint32_t getChecksum() const;
|
||||
cfdp::ConditionCode getConditionCode() const;
|
||||
uint32_t getChecksum() const;
|
||||
cfdp::ConditionCode getConditionCode() const;
|
||||
|
||||
EntityIdTlv* getFaultLoc() const;
|
||||
cfdp::FileSize& getFileSize();
|
||||
void setChecksum(uint32_t checksum);
|
||||
void setConditionCode(cfdp::ConditionCode conditionCode);
|
||||
void setFaultLoc(EntityIdTlv *faultLoc);
|
||||
ReturnValue_t setFileSize(size_t size, bool isLarge);
|
||||
private:
|
||||
EntityIdTlv* getFaultLoc() const;
|
||||
cfdp::FileSize& getFileSize();
|
||||
void setChecksum(uint32_t checksum);
|
||||
void setConditionCode(cfdp::ConditionCode conditionCode);
|
||||
void setFaultLoc(EntityIdTlv* faultLoc);
|
||||
ReturnValue_t setFileSize(size_t size, bool isLarge);
|
||||
|
||||
cfdp::ConditionCode conditionCode;
|
||||
uint32_t checksum;
|
||||
cfdp::FileSize fileSize;
|
||||
EntityIdTlv* faultLoc = nullptr;
|
||||
private:
|
||||
cfdp::ConditionCode conditionCode;
|
||||
uint32_t checksum;
|
||||
cfdp::FileSize fileSize;
|
||||
EntityIdTlv* faultLoc = nullptr;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_EOFINFO_H_ */
|
||||
|
@ -1,68 +1,69 @@
|
||||
#include "EofPduDeserializer.h"
|
||||
|
||||
#include "fsfw/FSFW.h"
|
||||
#include "fsfw/serviceinterface.h"
|
||||
|
||||
EofPduDeserializer::EofPduDeserializer(const uint8_t *pduBuf, size_t maxSize, EofInfo& eofInfo):
|
||||
FileDirectiveDeserializer(pduBuf, maxSize), info(eofInfo) {
|
||||
}
|
||||
EofPduDeserializer::EofPduDeserializer(const uint8_t* pduBuf, size_t maxSize, EofInfo& eofInfo)
|
||||
: FileDirectiveDeserializer(pduBuf, maxSize), info(eofInfo) {}
|
||||
|
||||
ReturnValue_t EofPduDeserializer::parseData() {
|
||||
ReturnValue_t result = FileDirectiveDeserializer::parseData();
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
ReturnValue_t result = FileDirectiveDeserializer::parseData();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const uint8_t* bufPtr = rawPtr;
|
||||
size_t expectedFileFieldLen = 4;
|
||||
if(this->getLargeFileFlag()) {
|
||||
expectedFileFieldLen = 8;
|
||||
}
|
||||
size_t currentIdx = FileDirectiveDeserializer::getHeaderSize();
|
||||
size_t deserLen = maxSize;
|
||||
if(maxSize < currentIdx + 5 + expectedFileFieldLen) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
const uint8_t* bufPtr = rawPtr;
|
||||
size_t expectedFileFieldLen = 4;
|
||||
if (this->getLargeFileFlag()) {
|
||||
expectedFileFieldLen = 8;
|
||||
}
|
||||
size_t currentIdx = FileDirectiveDeserializer::getHeaderSize();
|
||||
size_t deserLen = maxSize;
|
||||
if (maxSize < currentIdx + 5 + expectedFileFieldLen) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
|
||||
bufPtr += currentIdx;
|
||||
deserLen -= currentIdx;
|
||||
info.setConditionCode(static_cast<cfdp::ConditionCode>(*bufPtr >> 4));
|
||||
bufPtr += 1;
|
||||
deserLen -= 1;
|
||||
uint32_t checksum = 0;
|
||||
auto endianness = getEndianness();
|
||||
result = SerializeAdapter::deSerialize(&checksum, &bufPtr, &deserLen, endianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
info.setChecksum(checksum);
|
||||
if(this->getLargeFileFlag()) {
|
||||
uint64_t fileSizeValue = 0;
|
||||
result = SerializeAdapter::deSerialize(&fileSizeValue, &bufPtr, &deserLen, endianness);
|
||||
info.setFileSize(fileSizeValue, true);
|
||||
}
|
||||
else {
|
||||
uint32_t fileSizeValue = 0;
|
||||
result = SerializeAdapter::deSerialize(&fileSizeValue, &bufPtr, &deserLen, endianness);
|
||||
info.setFileSize(fileSizeValue, false);
|
||||
}
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if(info.getConditionCode() != cfdp::ConditionCode::NO_ERROR) {
|
||||
EntityIdTlv* tlvPtr = info.getFaultLoc();
|
||||
if(tlvPtr == nullptr) {
|
||||
bufPtr += currentIdx;
|
||||
deserLen -= currentIdx;
|
||||
info.setConditionCode(static_cast<cfdp::ConditionCode>(*bufPtr >> 4));
|
||||
bufPtr += 1;
|
||||
deserLen -= 1;
|
||||
uint32_t checksum = 0;
|
||||
auto endianness = getEndianness();
|
||||
result = SerializeAdapter::deSerialize(&checksum, &bufPtr, &deserLen, endianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
info.setChecksum(checksum);
|
||||
if (this->getLargeFileFlag()) {
|
||||
uint64_t fileSizeValue = 0;
|
||||
result = SerializeAdapter::deSerialize(&fileSizeValue, &bufPtr, &deserLen, endianness);
|
||||
info.setFileSize(fileSizeValue, true);
|
||||
} else {
|
||||
uint32_t fileSizeValue = 0;
|
||||
result = SerializeAdapter::deSerialize(&fileSizeValue, &bufPtr, &deserLen, endianness);
|
||||
info.setFileSize(fileSizeValue, false);
|
||||
}
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if (info.getConditionCode() != cfdp::ConditionCode::NO_ERROR) {
|
||||
EntityIdTlv* tlvPtr = info.getFaultLoc();
|
||||
if (tlvPtr == nullptr) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "EofPduDeserializer::parseData: Ca not deserialize fault location,"
|
||||
" given TLV pointer invalid" << std::endl;
|
||||
sif::warning << "EofPduDeserializer::parseData: Ca not deserialize fault location,"
|
||||
" given TLV pointer invalid"
|
||||
<< std::endl;
|
||||
#else
|
||||
sif::printWarning("EofPduDeserializer::parseData: Ca not deserialize fault location,"
|
||||
" given TLV pointer invalid");
|
||||
sif::printWarning(
|
||||
"EofPduDeserializer::parseData: Ca not deserialize fault location,"
|
||||
" given TLV pointer invalid");
|
||||
#endif
|
||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
result = tlvPtr->deSerialize(&bufPtr, &deserLen, endianness);
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return result;
|
||||
result = tlvPtr->deSerialize(&bufPtr, &deserLen, endianness);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -1,18 +1,17 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_EOFPDUDESERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_EOFPDUDESERIALIZER_H_
|
||||
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveDeserializer.h"
|
||||
#include "EofInfo.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveDeserializer.h"
|
||||
|
||||
class EofPduDeserializer: public FileDirectiveDeserializer {
|
||||
public:
|
||||
EofPduDeserializer(const uint8_t* pduBuf, size_t maxSize, EofInfo& eofInfo);
|
||||
class EofPduDeserializer : public FileDirectiveDeserializer {
|
||||
public:
|
||||
EofPduDeserializer(const uint8_t* pduBuf, size_t maxSize, EofInfo& eofInfo);
|
||||
|
||||
virtual ReturnValue_t parseData() override;
|
||||
private:
|
||||
EofInfo& info;
|
||||
virtual ReturnValue_t parseData() override;
|
||||
|
||||
private:
|
||||
EofInfo& info;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_EOFPDUDESERIALIZER_H_ */
|
||||
|
@ -1,46 +1,44 @@
|
||||
#include "fsfw/FSFW.h"
|
||||
#include "fsfw/serviceinterface.h"
|
||||
#include "EofPduSerializer.h"
|
||||
|
||||
EofPduSerializer::EofPduSerializer(PduConfig &conf, EofInfo& info):
|
||||
FileDirectiveSerializer(conf, cfdp::FileDirectives::EOF_DIRECTIVE, 9), info(info) {
|
||||
setDirectiveDataFieldLen(info.getSerializedSize(getLargeFileFlag()));
|
||||
#include "fsfw/FSFW.h"
|
||||
#include "fsfw/serviceinterface.h"
|
||||
|
||||
EofPduSerializer::EofPduSerializer(PduConfig &conf, EofInfo &info)
|
||||
: FileDirectiveSerializer(conf, cfdp::FileDirectives::EOF_DIRECTIVE, 9), info(info) {
|
||||
setDirectiveDataFieldLen(info.getSerializedSize(getLargeFileFlag()));
|
||||
}
|
||||
|
||||
size_t EofPduSerializer::getSerializedSize() const {
|
||||
return FileDirectiveSerializer::getWholePduSize();
|
||||
return FileDirectiveSerializer::getWholePduSize();
|
||||
}
|
||||
|
||||
ReturnValue_t EofPduSerializer::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result = FileDirectiveSerializer::serialize(buffer, size, maxSize,
|
||||
streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if(*size + 1 > maxSize) {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = info.getConditionCode() << 4;
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
uint32_t checksum = info.getChecksum();
|
||||
result = SerializeAdapter::serialize(&checksum, buffer, size, maxSize, streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if(info.getFileSize().isLargeFile()) {
|
||||
uint64_t fileSizeValue = info.getFileSize().getSize();
|
||||
result = SerializeAdapter::serialize(&fileSizeValue, buffer, size,
|
||||
maxSize, streamEndianness);
|
||||
}
|
||||
else {
|
||||
uint32_t fileSizeValue = info.getFileSize().getSize();
|
||||
result = SerializeAdapter::serialize(&fileSizeValue, buffer, size,
|
||||
maxSize, streamEndianness);
|
||||
}
|
||||
if(info.getFaultLoc() != nullptr and info.getConditionCode() != cfdp::ConditionCode::NO_ERROR) {
|
||||
result = info.getFaultLoc()->serialize(buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result =
|
||||
FileDirectiveSerializer::serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if (*size + 1 > maxSize) {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = info.getConditionCode() << 4;
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
uint32_t checksum = info.getChecksum();
|
||||
result = SerializeAdapter::serialize(&checksum, buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if (info.getFileSize().isLargeFile()) {
|
||||
uint64_t fileSizeValue = info.getFileSize().getSize();
|
||||
result = SerializeAdapter::serialize(&fileSizeValue, buffer, size, maxSize, streamEndianness);
|
||||
} else {
|
||||
uint32_t fileSizeValue = info.getFileSize().getSize();
|
||||
result = SerializeAdapter::serialize(&fileSizeValue, buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
if (info.getFaultLoc() != nullptr and info.getConditionCode() != cfdp::ConditionCode::NO_ERROR) {
|
||||
result = info.getFaultLoc()->serialize(buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -1,22 +1,21 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_EOFPDUSERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_EOFPDUSERIALIZER_H_
|
||||
|
||||
#include "EofInfo.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveSerializer.h"
|
||||
#include "fsfw/cfdp/tlv/EntityIdTlv.h"
|
||||
#include "EofInfo.h"
|
||||
|
||||
class EofPduSerializer: public FileDirectiveSerializer {
|
||||
public:
|
||||
EofPduSerializer(PduConfig &conf, EofInfo& info);
|
||||
class EofPduSerializer : public FileDirectiveSerializer {
|
||||
public:
|
||||
EofPduSerializer(PduConfig& conf, EofInfo& info);
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
private:
|
||||
EofInfo& info;
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
private:
|
||||
EofInfo& info;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_EOFPDUSERIALIZER_H_ */
|
||||
|
@ -1,52 +1,48 @@
|
||||
#include "FileDataDeserializer.h"
|
||||
|
||||
FileDataDeserializer::FileDataDeserializer(const uint8_t *pduBuf, size_t maxSize,
|
||||
FileDataInfo& info):
|
||||
HeaderDeserializer(pduBuf, maxSize), info(info) {
|
||||
}
|
||||
FileDataDeserializer::FileDataDeserializer(const uint8_t* pduBuf, size_t maxSize,
|
||||
FileDataInfo& info)
|
||||
: HeaderDeserializer(pduBuf, maxSize), info(info) {}
|
||||
|
||||
ReturnValue_t FileDataDeserializer::parseData() {
|
||||
ReturnValue_t result = HeaderDeserializer::parseData();
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
ReturnValue_t result = HeaderDeserializer::parseData();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
size_t currentIdx = HeaderDeserializer::getHeaderSize();
|
||||
const uint8_t* buf = rawPtr + currentIdx;
|
||||
size_t remSize = HeaderDeserializer::getWholePduSize() - currentIdx;
|
||||
if (remSize < 1) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
if (hasSegmentMetadataFlag()) {
|
||||
info.setSegmentMetadataFlag(true);
|
||||
info.setRecordContinuationState(static_cast<cfdp::RecordContinuationState>((*buf >> 6) & 0b11));
|
||||
size_t segmentMetadataLen = *buf & 0b00111111;
|
||||
info.setSegmentMetadataLen(segmentMetadataLen);
|
||||
if (remSize < segmentMetadataLen + 1) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
size_t currentIdx = HeaderDeserializer::getHeaderSize();
|
||||
const uint8_t* buf = rawPtr + currentIdx;
|
||||
size_t remSize = HeaderDeserializer::getWholePduSize() - currentIdx;
|
||||
if (remSize < 1) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
if (segmentMetadataLen > 0) {
|
||||
buf += 1;
|
||||
remSize -= 1;
|
||||
info.setSegmentMetadata(buf);
|
||||
buf += segmentMetadataLen;
|
||||
remSize -= segmentMetadataLen;
|
||||
}
|
||||
if(hasSegmentMetadataFlag()) {
|
||||
info.setSegmentMetadataFlag(true);
|
||||
info.setRecordContinuationState(static_cast<cfdp::RecordContinuationState>(
|
||||
(*buf >> 6) & 0b11));
|
||||
size_t segmentMetadataLen = *buf & 0b00111111;
|
||||
info.setSegmentMetadataLen(segmentMetadataLen);
|
||||
if(remSize < segmentMetadataLen + 1) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
if(segmentMetadataLen > 0) {
|
||||
buf += 1;
|
||||
remSize -= 1;
|
||||
info.setSegmentMetadata(buf);
|
||||
buf += segmentMetadataLen;
|
||||
remSize -= segmentMetadataLen;
|
||||
}
|
||||
}
|
||||
result = info.getOffset().deSerialize(&buf, &remSize, this->getEndianness());
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if(remSize > 0) {
|
||||
info.setFileData(buf, remSize);
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
result = info.getOffset().deSerialize(&buf, &remSize, this->getEndianness());
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if (remSize > 0) {
|
||||
info.setFileData(buf, remSize);
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
SerializeIF::Endianness FileDataDeserializer::getEndianness() const {
|
||||
return endianness;
|
||||
}
|
||||
SerializeIF::Endianness FileDataDeserializer::getEndianness() const { return endianness; }
|
||||
|
||||
void FileDataDeserializer::setEndianness(SerializeIF::Endianness endianness) {
|
||||
this->endianness = endianness;
|
||||
this->endianness = endianness;
|
||||
}
|
||||
|
@ -1,22 +1,21 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_FILEDATADESERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_FILEDATADESERIALIZER_H_
|
||||
|
||||
#include "../definitions.h"
|
||||
#include "FileDataInfo.h"
|
||||
#include "HeaderDeserializer.h"
|
||||
#include "../definitions.h"
|
||||
|
||||
class FileDataDeserializer: public HeaderDeserializer {
|
||||
public:
|
||||
FileDataDeserializer(const uint8_t* pduBuf, size_t maxSize, FileDataInfo& info);
|
||||
class FileDataDeserializer : public HeaderDeserializer {
|
||||
public:
|
||||
FileDataDeserializer(const uint8_t* pduBuf, size_t maxSize, FileDataInfo& info);
|
||||
|
||||
ReturnValue_t parseData();
|
||||
SerializeIF::Endianness getEndianness() const;
|
||||
void setEndianness(SerializeIF::Endianness endianness = SerializeIF::Endianness::NETWORK);
|
||||
ReturnValue_t parseData();
|
||||
SerializeIF::Endianness getEndianness() const;
|
||||
void setEndianness(SerializeIF::Endianness endianness = SerializeIF::Endianness::NETWORK);
|
||||
|
||||
private:
|
||||
|
||||
SerializeIF::Endianness endianness = SerializeIF::Endianness::NETWORK;
|
||||
FileDataInfo& info;
|
||||
private:
|
||||
SerializeIF::Endianness endianness = SerializeIF::Endianness::NETWORK;
|
||||
FileDataInfo& info;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_FILEDATADESERIALIZER_H_ */
|
||||
|
@ -1,104 +1,93 @@
|
||||
#include "FileDataInfo.h"
|
||||
|
||||
FileDataInfo::FileDataInfo(cfdp::FileSize &offset, const uint8_t *fileData, size_t fileSize):
|
||||
offset(offset), fileData(fileData), fileSize(fileSize) {
|
||||
}
|
||||
FileDataInfo::FileDataInfo(cfdp::FileSize &offset, const uint8_t *fileData, size_t fileSize)
|
||||
: offset(offset), fileData(fileData), fileSize(fileSize) {}
|
||||
|
||||
FileDataInfo::FileDataInfo(cfdp::FileSize &offset): offset(offset) {
|
||||
}
|
||||
FileDataInfo::FileDataInfo(cfdp::FileSize &offset) : offset(offset) {}
|
||||
|
||||
void FileDataInfo::setSegmentMetadataFlag(bool enable) {
|
||||
if(enable) {
|
||||
segmentMetadataFlag = cfdp::SegmentMetadataFlag::PRESENT;
|
||||
} else {
|
||||
segmentMetadataFlag = cfdp::SegmentMetadataFlag::NOT_PRESENT;
|
||||
}
|
||||
if (enable) {
|
||||
segmentMetadataFlag = cfdp::SegmentMetadataFlag::PRESENT;
|
||||
} else {
|
||||
segmentMetadataFlag = cfdp::SegmentMetadataFlag::NOT_PRESENT;
|
||||
}
|
||||
}
|
||||
|
||||
size_t FileDataInfo::getSerializedSize(bool largeFile) const {
|
||||
size_t sz = 0;
|
||||
if(segmentMetadataFlag == cfdp::SegmentMetadataFlag::PRESENT) {
|
||||
sz += 1 + segmentMetadataLen;
|
||||
}
|
||||
if(largeFile) {
|
||||
sz += 8;
|
||||
} else {
|
||||
sz += 4;
|
||||
}
|
||||
sz += fileSize;
|
||||
return sz;
|
||||
size_t sz = 0;
|
||||
if (segmentMetadataFlag == cfdp::SegmentMetadataFlag::PRESENT) {
|
||||
sz += 1 + segmentMetadataLen;
|
||||
}
|
||||
if (largeFile) {
|
||||
sz += 8;
|
||||
} else {
|
||||
sz += 4;
|
||||
}
|
||||
sz += fileSize;
|
||||
return sz;
|
||||
}
|
||||
|
||||
cfdp::SegmentMetadataFlag FileDataInfo::getSegmentMetadataFlag() const {
|
||||
return this->segmentMetadataFlag;
|
||||
return this->segmentMetadataFlag;
|
||||
}
|
||||
|
||||
bool FileDataInfo::hasSegmentMetadata() const {
|
||||
if(segmentMetadataFlag == cfdp::SegmentMetadataFlag::PRESENT) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (segmentMetadataFlag == cfdp::SegmentMetadataFlag::PRESENT) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
cfdp::RecordContinuationState FileDataInfo::getRecordContinuationState() const {
|
||||
return this->recContState;
|
||||
return this->recContState;
|
||||
}
|
||||
|
||||
size_t FileDataInfo::getSegmentMetadataLen() const {
|
||||
return segmentMetadataLen;
|
||||
}
|
||||
size_t FileDataInfo::getSegmentMetadataLen() const { return segmentMetadataLen; }
|
||||
|
||||
ReturnValue_t FileDataInfo::addSegmentMetadataInfo(cfdp::RecordContinuationState recContState,
|
||||
const uint8_t* segmentMetadata, size_t segmentMetadataLen) {
|
||||
this->segmentMetadataFlag = cfdp::SegmentMetadataFlag::PRESENT;
|
||||
this->recContState = recContState;
|
||||
if(segmentMetadataLen > 63) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
this->segmentMetadata = segmentMetadata;
|
||||
this->segmentMetadataLen = segmentMetadataLen;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
const uint8_t *segmentMetadata,
|
||||
size_t segmentMetadataLen) {
|
||||
this->segmentMetadataFlag = cfdp::SegmentMetadataFlag::PRESENT;
|
||||
this->recContState = recContState;
|
||||
if (segmentMetadataLen > 63) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
this->segmentMetadata = segmentMetadata;
|
||||
this->segmentMetadataLen = segmentMetadataLen;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
const uint8_t* FileDataInfo::getFileData(size_t *fileSize) const {
|
||||
if(fileSize != nullptr) {
|
||||
*fileSize = this->fileSize;
|
||||
}
|
||||
return fileData;
|
||||
const uint8_t *FileDataInfo::getFileData(size_t *fileSize) const {
|
||||
if (fileSize != nullptr) {
|
||||
*fileSize = this->fileSize;
|
||||
}
|
||||
return fileData;
|
||||
}
|
||||
|
||||
const uint8_t* FileDataInfo::getSegmentMetadata(size_t *segmentMetadataLen) {
|
||||
if(segmentMetadataLen != nullptr) {
|
||||
*segmentMetadataLen = this->segmentMetadataLen;
|
||||
}
|
||||
return segmentMetadata;
|
||||
const uint8_t *FileDataInfo::getSegmentMetadata(size_t *segmentMetadataLen) {
|
||||
if (segmentMetadataLen != nullptr) {
|
||||
*segmentMetadataLen = this->segmentMetadataLen;
|
||||
}
|
||||
return segmentMetadata;
|
||||
}
|
||||
|
||||
cfdp::FileSize& FileDataInfo::getOffset() {
|
||||
return offset;
|
||||
}
|
||||
cfdp::FileSize &FileDataInfo::getOffset() { return offset; }
|
||||
|
||||
void FileDataInfo::setRecordContinuationState(cfdp::RecordContinuationState recContState) {
|
||||
this->recContState = recContState;
|
||||
this->recContState = recContState;
|
||||
}
|
||||
|
||||
void FileDataInfo::setSegmentMetadataLen(size_t len) {
|
||||
this->segmentMetadataLen = len;
|
||||
}
|
||||
void FileDataInfo::setSegmentMetadataLen(size_t len) { this->segmentMetadataLen = len; }
|
||||
|
||||
void FileDataInfo::setSegmentMetadata(const uint8_t *ptr) {
|
||||
this->segmentMetadata = ptr;
|
||||
}
|
||||
void FileDataInfo::setSegmentMetadata(const uint8_t *ptr) { this->segmentMetadata = ptr; }
|
||||
|
||||
void FileDataInfo::setFileData(const uint8_t *fileData, size_t fileSize) {
|
||||
this->fileData = fileData;
|
||||
this->fileSize = fileSize;
|
||||
this->fileData = fileData;
|
||||
this->fileSize = fileSize;
|
||||
}
|
||||
|
||||
cfdp::SegmentationControl FileDataInfo::getSegmentationControl() const {
|
||||
return segCtrl;
|
||||
}
|
||||
cfdp::SegmentationControl FileDataInfo::getSegmentationControl() const { return segCtrl; }
|
||||
|
||||
void FileDataInfo::setSegmentationControl(cfdp::SegmentationControl segCtrl) {
|
||||
this->segCtrl = segCtrl;
|
||||
this->segCtrl = segCtrl;
|
||||
}
|
||||
|
@ -1,45 +1,44 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_FILEDATAINFO_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_FILEDATAINFO_H_
|
||||
|
||||
#include <fsfw/cfdp/definitions.h>
|
||||
#include <fsfw/cfdp/FileSize.h>
|
||||
#include <fsfw/cfdp/definitions.h>
|
||||
|
||||
class FileDataInfo {
|
||||
public:
|
||||
FileDataInfo(cfdp::FileSize& offset);
|
||||
FileDataInfo(cfdp::FileSize& offset, const uint8_t* fileData, size_t fileSize);
|
||||
public:
|
||||
FileDataInfo(cfdp::FileSize& offset);
|
||||
FileDataInfo(cfdp::FileSize& offset, const uint8_t* fileData, size_t fileSize);
|
||||
|
||||
size_t getSerializedSize(bool largeFile = false) const;
|
||||
size_t getSerializedSize(bool largeFile = false) const;
|
||||
|
||||
cfdp::FileSize& getOffset();
|
||||
const uint8_t* getFileData(size_t* fileSize = nullptr) const;
|
||||
void setFileData(const uint8_t* fileData, size_t fileSize);
|
||||
cfdp::FileSize& getOffset();
|
||||
const uint8_t* getFileData(size_t* fileSize = nullptr) const;
|
||||
void setFileData(const uint8_t* fileData, size_t fileSize);
|
||||
|
||||
cfdp::SegmentMetadataFlag getSegmentMetadataFlag() const;
|
||||
cfdp::SegmentationControl getSegmentationControl() const;
|
||||
cfdp::RecordContinuationState getRecordContinuationState() const;
|
||||
void setRecordContinuationState(cfdp::RecordContinuationState recContState);
|
||||
void setSegmentationControl(cfdp::SegmentationControl segCtrl);
|
||||
cfdp::SegmentMetadataFlag getSegmentMetadataFlag() const;
|
||||
cfdp::SegmentationControl getSegmentationControl() const;
|
||||
cfdp::RecordContinuationState getRecordContinuationState() const;
|
||||
void setRecordContinuationState(cfdp::RecordContinuationState recContState);
|
||||
void setSegmentationControl(cfdp::SegmentationControl segCtrl);
|
||||
|
||||
size_t getSegmentMetadataLen() const;
|
||||
void setSegmentMetadataLen(size_t len);
|
||||
void setSegmentMetadata(const uint8_t* ptr);
|
||||
bool hasSegmentMetadata() const;
|
||||
void setSegmentMetadataFlag(bool enable);
|
||||
ReturnValue_t addSegmentMetadataInfo(cfdp::RecordContinuationState recContState,
|
||||
const uint8_t* segmentMetadata, size_t segmentMetadataLen);
|
||||
const uint8_t* getSegmentMetadata(size_t* segmentMetadataLen = nullptr);
|
||||
size_t getSegmentMetadataLen() const;
|
||||
void setSegmentMetadataLen(size_t len);
|
||||
void setSegmentMetadata(const uint8_t* ptr);
|
||||
bool hasSegmentMetadata() const;
|
||||
void setSegmentMetadataFlag(bool enable);
|
||||
ReturnValue_t addSegmentMetadataInfo(cfdp::RecordContinuationState recContState,
|
||||
const uint8_t* segmentMetadata, size_t segmentMetadataLen);
|
||||
const uint8_t* getSegmentMetadata(size_t* segmentMetadataLen = nullptr);
|
||||
|
||||
private:
|
||||
cfdp::SegmentMetadataFlag segmentMetadataFlag = cfdp::SegmentMetadataFlag::NOT_PRESENT;
|
||||
cfdp::SegmentationControl segCtrl =
|
||||
cfdp::SegmentationControl::NO_RECORD_BOUNDARIES_PRESERVATION;
|
||||
cfdp::FileSize& offset;
|
||||
const uint8_t* fileData = nullptr;
|
||||
size_t fileSize = 0;
|
||||
cfdp::RecordContinuationState recContState = cfdp::RecordContinuationState::NO_START_NO_END;
|
||||
size_t segmentMetadataLen = 0;
|
||||
const uint8_t* segmentMetadata = nullptr;
|
||||
private:
|
||||
cfdp::SegmentMetadataFlag segmentMetadataFlag = cfdp::SegmentMetadataFlag::NOT_PRESENT;
|
||||
cfdp::SegmentationControl segCtrl = cfdp::SegmentationControl::NO_RECORD_BOUNDARIES_PRESERVATION;
|
||||
cfdp::FileSize& offset;
|
||||
const uint8_t* fileData = nullptr;
|
||||
size_t fileSize = 0;
|
||||
cfdp::RecordContinuationState recContState = cfdp::RecordContinuationState::NO_START_NO_END;
|
||||
size_t segmentMetadataLen = 0;
|
||||
const uint8_t* segmentMetadata = nullptr;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_FILEDATAINFO_H_ */
|
||||
|
@ -1,54 +1,55 @@
|
||||
#include "FileDataSerializer.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
FileDataSerializer::FileDataSerializer(PduConfig& conf, FileDataInfo& info):
|
||||
HeaderSerializer(conf, cfdp::PduType::FILE_DATA, 0, info.getSegmentMetadataFlag()),
|
||||
info(info) {
|
||||
update();
|
||||
FileDataSerializer::FileDataSerializer(PduConfig& conf, FileDataInfo& info)
|
||||
: HeaderSerializer(conf, cfdp::PduType::FILE_DATA, 0, info.getSegmentMetadataFlag()),
|
||||
info(info) {
|
||||
update();
|
||||
}
|
||||
|
||||
void FileDataSerializer::update() {
|
||||
this->setSegmentMetadataFlag(info.getSegmentMetadataFlag());
|
||||
this->setSegmentationControl(info.getSegmentationControl());
|
||||
setPduDataFieldLen(info.getSerializedSize(this->getLargeFileFlag()));
|
||||
this->setSegmentMetadataFlag(info.getSegmentMetadataFlag());
|
||||
this->setSegmentationControl(info.getSegmentationControl());
|
||||
setPduDataFieldLen(info.getSerializedSize(this->getLargeFileFlag()));
|
||||
}
|
||||
|
||||
ReturnValue_t FileDataSerializer::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result = HeaderSerializer::serialize(buffer, size, maxSize, streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if(*size + this->getSerializedSize() > maxSize) {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
const uint8_t* readOnlyPtr = nullptr;
|
||||
if (this->hasSegmentMetadataFlag()) {
|
||||
size_t segmentMetadataLen = info.getSegmentMetadataLen();
|
||||
**buffer = info.getRecordContinuationState() << 6 | segmentMetadataLen;
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
readOnlyPtr = info.getSegmentMetadata();
|
||||
std::memcpy(*buffer, readOnlyPtr, segmentMetadataLen);
|
||||
*buffer += segmentMetadataLen;
|
||||
*size += segmentMetadataLen;
|
||||
}
|
||||
cfdp::FileSize& offset = info.getOffset();
|
||||
result = offset.serialize(this->getLargeFileFlag(), buffer, size, maxSize, streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
size_t fileSize = 0;
|
||||
readOnlyPtr = info.getFileData(&fileSize);
|
||||
if(*size + fileSize > maxSize) {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
std::memcpy(*buffer, readOnlyPtr, fileSize);
|
||||
*buffer += fileSize;
|
||||
*size += fileSize;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
ReturnValue_t FileDataSerializer::serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result = HeaderSerializer::serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if (*size + this->getSerializedSize() > maxSize) {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
const uint8_t* readOnlyPtr = nullptr;
|
||||
if (this->hasSegmentMetadataFlag()) {
|
||||
size_t segmentMetadataLen = info.getSegmentMetadataLen();
|
||||
**buffer = info.getRecordContinuationState() << 6 | segmentMetadataLen;
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
readOnlyPtr = info.getSegmentMetadata();
|
||||
std::memcpy(*buffer, readOnlyPtr, segmentMetadataLen);
|
||||
*buffer += segmentMetadataLen;
|
||||
*size += segmentMetadataLen;
|
||||
}
|
||||
cfdp::FileSize& offset = info.getOffset();
|
||||
result = offset.serialize(this->getLargeFileFlag(), buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
size_t fileSize = 0;
|
||||
readOnlyPtr = info.getFileData(&fileSize);
|
||||
if (*size + fileSize > maxSize) {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
std::memcpy(*buffer, readOnlyPtr, fileSize);
|
||||
*buffer += fileSize;
|
||||
*size += fileSize;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
size_t FileDataSerializer::getSerializedSize() const {
|
||||
return HeaderSerializer::getSerializedSize() + info.getSerializedSize(this->getLargeFileFlag());
|
||||
return HeaderSerializer::getSerializedSize() + info.getSerializedSize(this->getLargeFileFlag());
|
||||
}
|
||||
|
@ -1,23 +1,23 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_FILEDATASERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_FILEDATASERIALIZER_H_
|
||||
|
||||
#include "FileDataInfo.h"
|
||||
#include "../definitions.h"
|
||||
#include "FileDataInfo.h"
|
||||
#include "HeaderSerializer.h"
|
||||
|
||||
class FileDataSerializer: public HeaderSerializer {
|
||||
public:
|
||||
FileDataSerializer(PduConfig& conf, FileDataInfo& info);
|
||||
class FileDataSerializer : public HeaderSerializer {
|
||||
public:
|
||||
FileDataSerializer(PduConfig& conf, FileDataInfo& info);
|
||||
|
||||
void update();
|
||||
void update();
|
||||
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
private:
|
||||
FileDataInfo& info;
|
||||
private:
|
||||
FileDataInfo& info;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_FILEDATADESERIALIZER_H_ */
|
||||
|
@ -1,55 +1,49 @@
|
||||
#include "FileDirectiveDeserializer.h"
|
||||
|
||||
FileDirectiveDeserializer::FileDirectiveDeserializer(const uint8_t *pduBuf, size_t maxSize):
|
||||
HeaderDeserializer(pduBuf, maxSize) {
|
||||
}
|
||||
FileDirectiveDeserializer::FileDirectiveDeserializer(const uint8_t *pduBuf, size_t maxSize)
|
||||
: HeaderDeserializer(pduBuf, maxSize) {}
|
||||
|
||||
cfdp::FileDirectives FileDirectiveDeserializer::getFileDirective() const {
|
||||
return fileDirective;
|
||||
}
|
||||
cfdp::FileDirectives FileDirectiveDeserializer::getFileDirective() const { return fileDirective; }
|
||||
|
||||
ReturnValue_t FileDirectiveDeserializer::parseData() {
|
||||
ReturnValue_t result = HeaderDeserializer::parseData();
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if(this->getPduDataFieldLen() < 1) {
|
||||
return cfdp::INVALID_PDU_DATAFIELD_LEN;
|
||||
}
|
||||
if(FileDirectiveDeserializer::getWholePduSize() > maxSize) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
size_t currentIdx = HeaderDeserializer::getHeaderSize();
|
||||
if(not checkFileDirective(rawPtr[currentIdx])) {
|
||||
return cfdp::INVALID_DIRECTIVE_FIELDS;
|
||||
}
|
||||
setFileDirective(static_cast<cfdp::FileDirectives>(rawPtr[currentIdx]));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
ReturnValue_t result = HeaderDeserializer::parseData();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if (this->getPduDataFieldLen() < 1) {
|
||||
return cfdp::INVALID_PDU_DATAFIELD_LEN;
|
||||
}
|
||||
if (FileDirectiveDeserializer::getWholePduSize() > maxSize) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
size_t currentIdx = HeaderDeserializer::getHeaderSize();
|
||||
if (not checkFileDirective(rawPtr[currentIdx])) {
|
||||
return cfdp::INVALID_DIRECTIVE_FIELDS;
|
||||
}
|
||||
setFileDirective(static_cast<cfdp::FileDirectives>(rawPtr[currentIdx]));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
size_t FileDirectiveDeserializer::getHeaderSize() const {
|
||||
// return size of header plus the directive byte
|
||||
return HeaderDeserializer::getHeaderSize() + 1;
|
||||
// return size of header plus the directive byte
|
||||
return HeaderDeserializer::getHeaderSize() + 1;
|
||||
}
|
||||
|
||||
bool FileDirectiveDeserializer::checkFileDirective(uint8_t rawByte) {
|
||||
if(rawByte < cfdp::FileDirectives::EOF_DIRECTIVE or
|
||||
(rawByte > cfdp::FileDirectives::PROMPT and
|
||||
rawByte != cfdp::FileDirectives::KEEP_ALIVE)) {
|
||||
// Invalid directive field. TODO: Custom returnvalue
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
if (rawByte < cfdp::FileDirectives::EOF_DIRECTIVE or
|
||||
(rawByte > cfdp::FileDirectives::PROMPT and rawByte != cfdp::FileDirectives::KEEP_ALIVE)) {
|
||||
// Invalid directive field. TODO: Custom returnvalue
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileDirectiveDeserializer::setFileDirective(cfdp::FileDirectives fileDirective) {
|
||||
this->fileDirective = fileDirective;
|
||||
this->fileDirective = fileDirective;
|
||||
}
|
||||
|
||||
void FileDirectiveDeserializer::setEndianness(SerializeIF::Endianness endianness) {
|
||||
this->endianness = endianness;
|
||||
this->endianness = endianness;
|
||||
}
|
||||
|
||||
SerializeIF::Endianness FileDirectiveDeserializer::getEndianness() const {
|
||||
return endianness;
|
||||
}
|
||||
SerializeIF::Endianness FileDirectiveDeserializer::getEndianness() const { return endianness; }
|
||||
|
@ -11,31 +11,29 @@
|
||||
* This is a zero-copy implementation and #parseData needs to be called to ensure the data is
|
||||
* valid.
|
||||
*/
|
||||
class FileDirectiveDeserializer: public HeaderDeserializer {
|
||||
public:
|
||||
FileDirectiveDeserializer(const uint8_t* pduBuf, size_t maxSize);
|
||||
class FileDirectiveDeserializer : public HeaderDeserializer {
|
||||
public:
|
||||
FileDirectiveDeserializer(const uint8_t* pduBuf, size_t maxSize);
|
||||
|
||||
/**
|
||||
* This needs to be called before accessing the PDU fields to avoid segmentation faults.
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t parseData();
|
||||
size_t getHeaderSize() const;
|
||||
/**
|
||||
* This needs to be called before accessing the PDU fields to avoid segmentation faults.
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t parseData();
|
||||
size_t getHeaderSize() const;
|
||||
|
||||
cfdp::FileDirectives getFileDirective() const;
|
||||
cfdp::FileDirectives getFileDirective() const;
|
||||
|
||||
void setEndianness(SerializeIF::Endianness endianness);
|
||||
SerializeIF::Endianness getEndianness() const;
|
||||
void setEndianness(SerializeIF::Endianness endianness);
|
||||
SerializeIF::Endianness getEndianness() const;
|
||||
|
||||
protected:
|
||||
bool checkFileDirective(uint8_t rawByte);
|
||||
protected:
|
||||
bool checkFileDirective(uint8_t rawByte);
|
||||
|
||||
private:
|
||||
void setFileDirective(cfdp::FileDirectives fileDirective);
|
||||
cfdp::FileDirectives fileDirective = cfdp::FileDirectives::INVALID_DIRECTIVE;
|
||||
SerializeIF::Endianness endianness = SerializeIF::Endianness::NETWORK;
|
||||
private:
|
||||
void setFileDirective(cfdp::FileDirectives fileDirective);
|
||||
cfdp::FileDirectives fileDirective = cfdp::FileDirectives::INVALID_DIRECTIVE;
|
||||
SerializeIF::Endianness endianness = SerializeIF::Endianness::NETWORK;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_FILEDIRECTIVEDESERIALIZER_H_ */
|
||||
|
@ -1,39 +1,38 @@
|
||||
#include "FileDirectiveSerializer.h"
|
||||
|
||||
|
||||
FileDirectiveSerializer::FileDirectiveSerializer(PduConfig &pduConf,
|
||||
cfdp::FileDirectives directiveCode, size_t directiveParamFieldLen):
|
||||
HeaderSerializer(pduConf, cfdp::PduType::FILE_DIRECTIVE, directiveParamFieldLen + 1),
|
||||
directiveCode(directiveCode) {
|
||||
}
|
||||
cfdp::FileDirectives directiveCode,
|
||||
size_t directiveParamFieldLen)
|
||||
: HeaderSerializer(pduConf, cfdp::PduType::FILE_DIRECTIVE, directiveParamFieldLen + 1),
|
||||
directiveCode(directiveCode) {}
|
||||
|
||||
size_t FileDirectiveSerializer::getSerializedSize() const {
|
||||
return HeaderSerializer::getSerializedSize() + 1;
|
||||
return HeaderSerializer::getSerializedSize() + 1;
|
||||
}
|
||||
|
||||
ReturnValue_t FileDirectiveSerializer::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
if(buffer == nullptr or size == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
if(FileDirectiveSerializer::getWholePduSize() > maxSize) {
|
||||
return BUFFER_TOO_SHORT;
|
||||
}
|
||||
ReturnValue_t result = HeaderSerializer::serialize(buffer, size, maxSize, streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
Endianness streamEndianness) const {
|
||||
if (buffer == nullptr or size == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
if (FileDirectiveSerializer::getWholePduSize() > maxSize) {
|
||||
return BUFFER_TOO_SHORT;
|
||||
}
|
||||
ReturnValue_t result = HeaderSerializer::serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if(*size >= maxSize) {
|
||||
return BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = directiveCode;
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
if (*size >= maxSize) {
|
||||
return BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = directiveCode;
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
void FileDirectiveSerializer::setDirectiveDataFieldLen(size_t len) {
|
||||
// Set length of data field plus 1 byte for the directive octet
|
||||
HeaderSerializer::setPduDataFieldLen(len + 1);
|
||||
// Set length of data field plus 1 byte for the directive octet
|
||||
HeaderSerializer::setPduDataFieldLen(len + 1);
|
||||
}
|
||||
|
@ -3,26 +3,26 @@
|
||||
|
||||
#include "fsfw/cfdp/pdu/HeaderSerializer.h"
|
||||
|
||||
class FileDirectiveSerializer: public HeaderSerializer {
|
||||
public:
|
||||
FileDirectiveSerializer(PduConfig& pduConf, cfdp::FileDirectives directiveCode,
|
||||
size_t directiveParamFieldLen);
|
||||
class FileDirectiveSerializer : public HeaderSerializer {
|
||||
public:
|
||||
FileDirectiveSerializer(PduConfig& pduConf, cfdp::FileDirectives directiveCode,
|
||||
size_t directiveParamFieldLen);
|
||||
|
||||
/**
|
||||
* This only returns the size of the PDU header + 1 for the directive code octet.
|
||||
* Use FileDirectiveSerializer::getWholePduSize to get the full packet length, assuming
|
||||
* the length fields was set correctly
|
||||
* @return
|
||||
*/
|
||||
size_t getSerializedSize() const override;
|
||||
/**
|
||||
* This only returns the size of the PDU header + 1 for the directive code octet.
|
||||
* Use FileDirectiveSerializer::getWholePduSize to get the full packet length, assuming
|
||||
* the length fields was set correctly
|
||||
* @return
|
||||
*/
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
void setDirectiveDataFieldLen(size_t len);
|
||||
private:
|
||||
cfdp::FileDirectives directiveCode = cfdp::FileDirectives::INVALID_DIRECTIVE;
|
||||
void setDirectiveDataFieldLen(size_t len);
|
||||
|
||||
private:
|
||||
cfdp::FileDirectives directiveCode = cfdp::FileDirectives::INVALID_DIRECTIVE;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_FILEDIRECTIVESERIALIZER_H_ */
|
||||
|
@ -1,111 +1,102 @@
|
||||
#include "FinishedInfo.h"
|
||||
|
||||
FinishedInfo::FinishedInfo() {
|
||||
}
|
||||
|
||||
FinishedInfo::FinishedInfo() {}
|
||||
|
||||
FinishedInfo::FinishedInfo(cfdp::ConditionCode conditionCode,
|
||||
cfdp::FinishedDeliveryCode deliveryCode, cfdp::FinishedFileStatus fileStatus):
|
||||
conditionCode(conditionCode), deliveryCode(deliveryCode), fileStatus(fileStatus) {
|
||||
}
|
||||
cfdp::FinishedDeliveryCode deliveryCode,
|
||||
cfdp::FinishedFileStatus fileStatus)
|
||||
: conditionCode(conditionCode), deliveryCode(deliveryCode), fileStatus(fileStatus) {}
|
||||
|
||||
size_t FinishedInfo::getSerializedSize() const {
|
||||
size_t size = 1;
|
||||
if(hasFsResponses()) {
|
||||
for(size_t idx = 0; idx < fsResponsesLen; idx++) {
|
||||
size += fsResponses[idx]->getSerializedSize();
|
||||
}
|
||||
size_t size = 1;
|
||||
if (hasFsResponses()) {
|
||||
for (size_t idx = 0; idx < fsResponsesLen; idx++) {
|
||||
size += fsResponses[idx]->getSerializedSize();
|
||||
}
|
||||
if(this->faultLocation != nullptr) {
|
||||
size += faultLocation->getSerializedSize();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
if (this->faultLocation != nullptr) {
|
||||
size += faultLocation->getSerializedSize();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
bool FinishedInfo::hasFsResponses() const {
|
||||
if(fsResponses != nullptr and fsResponsesLen > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (fsResponses != nullptr and fsResponsesLen > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool FinishedInfo::canHoldFsResponses() const {
|
||||
if(fsResponses != nullptr and fsResponsesMaxLen > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (fsResponses != nullptr and fsResponsesMaxLen > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
ReturnValue_t FinishedInfo::setFilestoreResponsesArray(FilestoreResponseTlv** fsResponses,
|
||||
size_t* fsResponsesLen, const size_t* maxFsResponsesLen) {
|
||||
this->fsResponses = fsResponses;
|
||||
if(fsResponsesLen != nullptr) {
|
||||
this->fsResponsesLen = *fsResponsesLen;
|
||||
if(this->fsResponsesMaxLen < *fsResponsesLen) {
|
||||
this->fsResponsesMaxLen = this->fsResponsesLen;
|
||||
}
|
||||
size_t* fsResponsesLen,
|
||||
const size_t* maxFsResponsesLen) {
|
||||
this->fsResponses = fsResponses;
|
||||
if (fsResponsesLen != nullptr) {
|
||||
this->fsResponsesLen = *fsResponsesLen;
|
||||
if (this->fsResponsesMaxLen < *fsResponsesLen) {
|
||||
this->fsResponsesMaxLen = this->fsResponsesLen;
|
||||
}
|
||||
if(maxFsResponsesLen != nullptr) {
|
||||
this->fsResponsesMaxLen = *maxFsResponsesLen;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
if (maxFsResponsesLen != nullptr) {
|
||||
this->fsResponsesMaxLen = *maxFsResponsesLen;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t FinishedInfo::getFilestoreResonses(FilestoreResponseTlv ***fsResponses,
|
||||
size_t *fsResponsesLen, size_t* fsResponsesMaxLen) {
|
||||
if(fsResponses == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
*fsResponses = this->fsResponses;
|
||||
if(fsResponsesLen != nullptr) {
|
||||
*fsResponsesLen = this->fsResponsesLen;
|
||||
}
|
||||
if(fsResponsesMaxLen != nullptr) {
|
||||
*fsResponsesMaxLen = this->fsResponsesMaxLen;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
ReturnValue_t FinishedInfo::getFilestoreResonses(FilestoreResponseTlv*** fsResponses,
|
||||
size_t* fsResponsesLen,
|
||||
size_t* fsResponsesMaxLen) {
|
||||
if (fsResponses == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
*fsResponses = this->fsResponses;
|
||||
if (fsResponsesLen != nullptr) {
|
||||
*fsResponsesLen = this->fsResponsesLen;
|
||||
}
|
||||
if (fsResponsesMaxLen != nullptr) {
|
||||
*fsResponsesMaxLen = this->fsResponsesMaxLen;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
void FinishedInfo::setFaultLocation(EntityIdTlv *faultLocation) {
|
||||
this->faultLocation = faultLocation;
|
||||
void FinishedInfo::setFaultLocation(EntityIdTlv* faultLocation) {
|
||||
this->faultLocation = faultLocation;
|
||||
}
|
||||
|
||||
ReturnValue_t FinishedInfo::getFaultLocation(EntityIdTlv** faultLocation) {
|
||||
if(this->faultLocation == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
*faultLocation = this->faultLocation;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
if (this->faultLocation == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
*faultLocation = this->faultLocation;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
cfdp::ConditionCode FinishedInfo::getConditionCode() const {
|
||||
return conditionCode;
|
||||
}
|
||||
cfdp::ConditionCode FinishedInfo::getConditionCode() const { return conditionCode; }
|
||||
|
||||
void FinishedInfo::setConditionCode(cfdp::ConditionCode conditionCode) {
|
||||
this->conditionCode = conditionCode;
|
||||
this->conditionCode = conditionCode;
|
||||
}
|
||||
|
||||
cfdp::FinishedDeliveryCode FinishedInfo::getDeliveryCode() const {
|
||||
return deliveryCode;
|
||||
}
|
||||
cfdp::FinishedDeliveryCode FinishedInfo::getDeliveryCode() const { return deliveryCode; }
|
||||
|
||||
void FinishedInfo::setDeliveryCode(cfdp::FinishedDeliveryCode deliveryCode) {
|
||||
this->deliveryCode = deliveryCode;
|
||||
this->deliveryCode = deliveryCode;
|
||||
}
|
||||
|
||||
cfdp::FinishedFileStatus FinishedInfo::getFileStatus() const {
|
||||
return fileStatus;
|
||||
}
|
||||
cfdp::FinishedFileStatus FinishedInfo::getFileStatus() const { return fileStatus; }
|
||||
|
||||
void FinishedInfo::setFilestoreResponsesArrayLen(size_t fsResponsesLen) {
|
||||
this->fsResponsesLen = fsResponsesLen;
|
||||
this->fsResponsesLen = fsResponsesLen;
|
||||
}
|
||||
|
||||
size_t FinishedInfo::getFsResponsesLen() const {
|
||||
return fsResponsesLen;
|
||||
}
|
||||
size_t FinishedInfo::getFsResponsesLen() const { return fsResponsesLen; }
|
||||
|
||||
void FinishedInfo::setFileStatus(cfdp::FinishedFileStatus fileStatus) {
|
||||
this->fileStatus = fileStatus;
|
||||
this->fileStatus = fileStatus;
|
||||
}
|
||||
|
@ -1,45 +1,45 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_FINISHINFO_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_FINISHINFO_H_
|
||||
|
||||
#include "../definitions.h"
|
||||
#include "fsfw/cfdp/tlv/EntityIdTlv.h"
|
||||
#include "fsfw/cfdp/tlv/FilestoreResponseTlv.h"
|
||||
#include "../definitions.h"
|
||||
|
||||
class FinishedInfo {
|
||||
public:
|
||||
FinishedInfo();
|
||||
FinishedInfo(cfdp::ConditionCode conditionCode, cfdp::FinishedDeliveryCode deliveryCode,
|
||||
cfdp::FinishedFileStatus fileStatus);
|
||||
public:
|
||||
FinishedInfo();
|
||||
FinishedInfo(cfdp::ConditionCode conditionCode, cfdp::FinishedDeliveryCode deliveryCode,
|
||||
cfdp::FinishedFileStatus fileStatus);
|
||||
|
||||
size_t getSerializedSize() const;
|
||||
size_t getSerializedSize() const;
|
||||
|
||||
bool hasFsResponses() const;
|
||||
bool canHoldFsResponses() const;
|
||||
bool hasFsResponses() const;
|
||||
bool canHoldFsResponses() const;
|
||||
|
||||
ReturnValue_t setFilestoreResponsesArray(FilestoreResponseTlv** fsResponses,
|
||||
size_t* fsResponsesLen, const size_t* maxFsResponseLen);
|
||||
void setFaultLocation(EntityIdTlv* entityId);
|
||||
ReturnValue_t setFilestoreResponsesArray(FilestoreResponseTlv** fsResponses,
|
||||
size_t* fsResponsesLen, const size_t* maxFsResponseLen);
|
||||
void setFaultLocation(EntityIdTlv* entityId);
|
||||
|
||||
ReturnValue_t getFilestoreResonses(FilestoreResponseTlv ***fsResponses,
|
||||
size_t *fsResponsesLen, size_t* fsResponsesMaxLen);
|
||||
size_t getFsResponsesLen() const;
|
||||
void setFilestoreResponsesArrayLen(size_t fsResponsesLen);
|
||||
ReturnValue_t getFaultLocation(EntityIdTlv** entityId);
|
||||
cfdp::ConditionCode getConditionCode() const;
|
||||
void setConditionCode(cfdp::ConditionCode conditionCode);
|
||||
cfdp::FinishedDeliveryCode getDeliveryCode() const;
|
||||
void setDeliveryCode(cfdp::FinishedDeliveryCode deliveryCode);
|
||||
cfdp::FinishedFileStatus getFileStatus() const;
|
||||
void setFileStatus(cfdp::FinishedFileStatus fileStatus);
|
||||
ReturnValue_t getFilestoreResonses(FilestoreResponseTlv*** fsResponses, size_t* fsResponsesLen,
|
||||
size_t* fsResponsesMaxLen);
|
||||
size_t getFsResponsesLen() const;
|
||||
void setFilestoreResponsesArrayLen(size_t fsResponsesLen);
|
||||
ReturnValue_t getFaultLocation(EntityIdTlv** entityId);
|
||||
cfdp::ConditionCode getConditionCode() const;
|
||||
void setConditionCode(cfdp::ConditionCode conditionCode);
|
||||
cfdp::FinishedDeliveryCode getDeliveryCode() const;
|
||||
void setDeliveryCode(cfdp::FinishedDeliveryCode deliveryCode);
|
||||
cfdp::FinishedFileStatus getFileStatus() const;
|
||||
void setFileStatus(cfdp::FinishedFileStatus fileStatus);
|
||||
|
||||
private:
|
||||
cfdp::ConditionCode conditionCode = cfdp::ConditionCode::NO_CONDITION_FIELD;
|
||||
cfdp::FinishedDeliveryCode deliveryCode = cfdp::FinishedDeliveryCode::DATA_COMPLETE;
|
||||
cfdp::FinishedFileStatus fileStatus = cfdp::FinishedFileStatus::DISCARDED_DELIBERATELY;
|
||||
FilestoreResponseTlv** fsResponses = nullptr;
|
||||
size_t fsResponsesLen = 0;
|
||||
size_t fsResponsesMaxLen = 0;
|
||||
EntityIdTlv* faultLocation = nullptr;
|
||||
private:
|
||||
cfdp::ConditionCode conditionCode = cfdp::ConditionCode::NO_CONDITION_FIELD;
|
||||
cfdp::FinishedDeliveryCode deliveryCode = cfdp::FinishedDeliveryCode::DATA_COMPLETE;
|
||||
cfdp::FinishedFileStatus fileStatus = cfdp::FinishedFileStatus::DISCARDED_DELIBERATELY;
|
||||
FilestoreResponseTlv** fsResponses = nullptr;
|
||||
size_t fsResponsesLen = 0;
|
||||
size_t fsResponsesMaxLen = 0;
|
||||
EntityIdTlv* faultLocation = nullptr;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_FINISHINFO_H_ */
|
||||
|
@ -1,90 +1,88 @@
|
||||
#include "FinishedPduDeserializer.h"
|
||||
|
||||
FinishPduDeserializer::FinishPduDeserializer(const uint8_t *pduBuf, size_t maxSize,
|
||||
FinishedInfo &info): FileDirectiveDeserializer(pduBuf, maxSize), finishedInfo(info) {
|
||||
}
|
||||
FinishPduDeserializer::FinishPduDeserializer(const uint8_t* pduBuf, size_t maxSize,
|
||||
FinishedInfo& info)
|
||||
: FileDirectiveDeserializer(pduBuf, maxSize), finishedInfo(info) {}
|
||||
|
||||
ReturnValue_t FinishPduDeserializer::parseData() {
|
||||
ReturnValue_t result = FileDirectiveDeserializer::parseData();
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
ReturnValue_t result = FileDirectiveDeserializer::parseData();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
size_t currentIdx = FileDirectiveDeserializer::getHeaderSize();
|
||||
const uint8_t* buf = rawPtr + currentIdx;
|
||||
size_t remSize = FileDirectiveDeserializer::getWholePduSize() - currentIdx;
|
||||
if (remSize < 1) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
uint8_t firstByte = *buf;
|
||||
cfdp::ConditionCode condCode = static_cast<cfdp::ConditionCode>((firstByte >> 4) & 0x0f);
|
||||
finishedInfo.setConditionCode(condCode);
|
||||
finishedInfo.setDeliveryCode(static_cast<cfdp::FinishedDeliveryCode>(firstByte >> 2 & 0b1));
|
||||
finishedInfo.setFileStatus(static_cast<cfdp::FinishedFileStatus>(firstByte & 0b11));
|
||||
buf += 1;
|
||||
remSize -= 1;
|
||||
currentIdx += 1;
|
||||
if (remSize > 0) {
|
||||
result = parseTlvs(remSize, currentIdx, buf, condCode);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
FinishedInfo& FinishPduDeserializer::getInfo() { return finishedInfo; }
|
||||
|
||||
ReturnValue_t FinishPduDeserializer::parseTlvs(size_t remLen, size_t currentIdx, const uint8_t* buf,
|
||||
cfdp::ConditionCode conditionCode) {
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
size_t fsResponsesIdx = 0;
|
||||
auto endianness = getEndianness();
|
||||
FilestoreResponseTlv** fsResponseArray = nullptr;
|
||||
size_t fsResponseMaxArrayLen = 0;
|
||||
EntityIdTlv* faultLocation = nullptr;
|
||||
cfdp::TlvTypes nextTlv = cfdp::TlvTypes::INVALID_TLV;
|
||||
while (remLen > 0) {
|
||||
// Simply forward parse the TLV type. Every TLV type except the last one must be a Filestore
|
||||
// Response TLV, and even the last one can be a Filestore Response TLV if the fault
|
||||
// location is omitted
|
||||
if (currentIdx + 2 > maxSize) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
nextTlv = static_cast<cfdp::TlvTypes>(*buf);
|
||||
if (nextTlv == cfdp::TlvTypes::FILESTORE_RESPONSE) {
|
||||
if (fsResponseArray == nullptr) {
|
||||
if (not finishedInfo.canHoldFsResponses()) {
|
||||
return cfdp::FINISHED_CANT_PARSE_FS_RESPONSES;
|
||||
}
|
||||
result =
|
||||
finishedInfo.getFilestoreResonses(&fsResponseArray, nullptr, &fsResponseMaxArrayLen);
|
||||
}
|
||||
if (fsResponsesIdx == fsResponseMaxArrayLen) {
|
||||
return cfdp::FINISHED_CANT_PARSE_FS_RESPONSES;
|
||||
}
|
||||
result = fsResponseArray[fsResponsesIdx]->deSerialize(&buf, &remLen, endianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
fsResponsesIdx += 1;
|
||||
} else if (nextTlv == cfdp::TlvTypes::ENTITY_ID) {
|
||||
// This needs to be the last TLV and it should not be here if the condition code
|
||||
// is "No Error" or "Unsupported Checksum Type"
|
||||
if (conditionCode == cfdp::ConditionCode::NO_ERROR or
|
||||
conditionCode == cfdp::ConditionCode::UNSUPPORTED_CHECKSUM_TYPE) {
|
||||
return cfdp::INVALID_TLV_TYPE;
|
||||
}
|
||||
result = finishedInfo.getFaultLocation(&faultLocation);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = faultLocation->deSerialize(&buf, &remLen, endianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
return cfdp::INVALID_TLV_TYPE;
|
||||
}
|
||||
size_t currentIdx = FileDirectiveDeserializer::getHeaderSize();
|
||||
const uint8_t* buf = rawPtr + currentIdx;
|
||||
size_t remSize = FileDirectiveDeserializer::getWholePduSize() - currentIdx;
|
||||
if (remSize < 1) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
uint8_t firstByte = *buf;
|
||||
cfdp::ConditionCode condCode = static_cast<cfdp::ConditionCode>((firstByte >> 4) & 0x0f);
|
||||
finishedInfo.setConditionCode(condCode);
|
||||
finishedInfo.setDeliveryCode(static_cast<cfdp::FinishedDeliveryCode>(firstByte >> 2 & 0b1));
|
||||
finishedInfo.setFileStatus(static_cast<cfdp::FinishedFileStatus>(firstByte & 0b11));
|
||||
buf += 1;
|
||||
remSize -= 1;
|
||||
currentIdx += 1;
|
||||
if(remSize > 0) {
|
||||
result = parseTlvs(remSize, currentIdx, buf, condCode);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
FinishedInfo& FinishPduDeserializer::getInfo() {
|
||||
return finishedInfo;
|
||||
}
|
||||
|
||||
ReturnValue_t FinishPduDeserializer::parseTlvs(size_t remLen, size_t currentIdx,
|
||||
const uint8_t* buf, cfdp::ConditionCode conditionCode) {
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
size_t fsResponsesIdx = 0;
|
||||
auto endianness = getEndianness();
|
||||
FilestoreResponseTlv** fsResponseArray = nullptr;
|
||||
size_t fsResponseMaxArrayLen = 0;
|
||||
EntityIdTlv* faultLocation = nullptr;
|
||||
cfdp::TlvTypes nextTlv = cfdp::TlvTypes::INVALID_TLV;
|
||||
while(remLen > 0) {
|
||||
// Simply forward parse the TLV type. Every TLV type except the last one must be a Filestore
|
||||
// Response TLV, and even the last one can be a Filestore Response TLV if the fault
|
||||
// location is omitted
|
||||
if (currentIdx + 2 > maxSize) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
nextTlv = static_cast<cfdp::TlvTypes>(*buf);
|
||||
if (nextTlv == cfdp::TlvTypes::FILESTORE_RESPONSE) {
|
||||
if(fsResponseArray == nullptr) {
|
||||
if(not finishedInfo.canHoldFsResponses()) {
|
||||
return cfdp::FINISHED_CANT_PARSE_FS_RESPONSES;
|
||||
}
|
||||
result = finishedInfo.getFilestoreResonses(&fsResponseArray, nullptr,
|
||||
&fsResponseMaxArrayLen);
|
||||
}
|
||||
if(fsResponsesIdx == fsResponseMaxArrayLen) {
|
||||
return cfdp::FINISHED_CANT_PARSE_FS_RESPONSES;
|
||||
}
|
||||
result = fsResponseArray[fsResponsesIdx]->deSerialize(&buf, &remLen, endianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
fsResponsesIdx += 1;
|
||||
} else if(nextTlv == cfdp::TlvTypes::ENTITY_ID) {
|
||||
// This needs to be the last TLV and it should not be here if the condition code
|
||||
// is "No Error" or "Unsupported Checksum Type"
|
||||
if(conditionCode == cfdp::ConditionCode::NO_ERROR or
|
||||
conditionCode == cfdp::ConditionCode::UNSUPPORTED_CHECKSUM_TYPE) {
|
||||
return cfdp::INVALID_TLV_TYPE;
|
||||
}
|
||||
result = finishedInfo.getFaultLocation(&faultLocation);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = faultLocation->deSerialize(&buf, &remLen, endianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
return cfdp::INVALID_TLV_TYPE;
|
||||
}
|
||||
}
|
||||
finishedInfo.setFilestoreResponsesArrayLen(fsResponsesIdx);
|
||||
return result;
|
||||
}
|
||||
finishedInfo.setFilestoreResponsesArrayLen(fsResponsesIdx);
|
||||
return result;
|
||||
}
|
||||
|
@ -1,21 +1,22 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_FINISHEDPDUDESERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_FINISHEDPDUDESERIALIZER_H_
|
||||
|
||||
#include "fsfw/cfdp/pdu/FinishedInfo.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveDeserializer.h"
|
||||
#include "fsfw/cfdp/pdu/FinishedInfo.h"
|
||||
|
||||
class FinishPduDeserializer: public FileDirectiveDeserializer {
|
||||
public:
|
||||
FinishPduDeserializer(const uint8_t *pduBuf, size_t maxSize, FinishedInfo& info);
|
||||
class FinishPduDeserializer : public FileDirectiveDeserializer {
|
||||
public:
|
||||
FinishPduDeserializer(const uint8_t* pduBuf, size_t maxSize, FinishedInfo& info);
|
||||
|
||||
ReturnValue_t parseData() override;
|
||||
ReturnValue_t parseData() override;
|
||||
|
||||
FinishedInfo& getInfo();
|
||||
private:
|
||||
FinishedInfo& finishedInfo;
|
||||
FinishedInfo& getInfo();
|
||||
|
||||
ReturnValue_t parseTlvs(size_t remLen, size_t currentIdx, const uint8_t* buf,
|
||||
cfdp::ConditionCode conditionCode);
|
||||
private:
|
||||
FinishedInfo& finishedInfo;
|
||||
|
||||
ReturnValue_t parseTlvs(size_t remLen, size_t currentIdx, const uint8_t* buf,
|
||||
cfdp::ConditionCode conditionCode);
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_FINISHEDPDUDESERIALIZER_H_ */
|
||||
|
@ -1,47 +1,47 @@
|
||||
#include "FinishedPduSerializer.h"
|
||||
|
||||
FinishPduSerializer::FinishPduSerializer(PduConfig &conf, FinishedInfo &finishInfo):
|
||||
FileDirectiveSerializer(conf, cfdp::FileDirectives::FINISH, 0), finishInfo(finishInfo) {
|
||||
updateDirectiveFieldLen();
|
||||
FinishPduSerializer::FinishPduSerializer(PduConfig &conf, FinishedInfo &finishInfo)
|
||||
: FileDirectiveSerializer(conf, cfdp::FileDirectives::FINISH, 0), finishInfo(finishInfo) {
|
||||
updateDirectiveFieldLen();
|
||||
}
|
||||
|
||||
size_t FinishPduSerializer::getSerializedSize() const {
|
||||
return FinishPduSerializer::getWholePduSize();
|
||||
return FinishPduSerializer::getWholePduSize();
|
||||
}
|
||||
|
||||
void FinishPduSerializer::updateDirectiveFieldLen() {
|
||||
setDirectiveDataFieldLen(finishInfo.getSerializedSize());
|
||||
setDirectiveDataFieldLen(finishInfo.getSerializedSize());
|
||||
}
|
||||
|
||||
ReturnValue_t FinishPduSerializer::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result = FileDirectiveSerializer::serialize(buffer, size, maxSize,
|
||||
streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if(*size + 1 >= maxSize) {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = finishInfo.getConditionCode() << 4 | finishInfo.getDeliveryCode() << 2 |
|
||||
finishInfo.getFileStatus();
|
||||
*size += 1;
|
||||
*buffer += 1;
|
||||
|
||||
if(finishInfo.hasFsResponses()) {
|
||||
FilestoreResponseTlv** fsResponsesArray = nullptr;
|
||||
size_t fsResponsesArrayLen = 0;
|
||||
finishInfo.getFilestoreResonses(&fsResponsesArray, &fsResponsesArrayLen, nullptr);
|
||||
for(size_t idx = 0; idx < fsResponsesArrayLen; idx++) {
|
||||
result = fsResponsesArray[idx]->serialize(buffer, size, maxSize, streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
EntityIdTlv* entityId = nullptr;
|
||||
if(finishInfo.getFaultLocation(&entityId) == HasReturnvaluesIF::RETURN_OK) {
|
||||
result = entityId->serialize(buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result =
|
||||
FileDirectiveSerializer::serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if (*size + 1 >= maxSize) {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = finishInfo.getConditionCode() << 4 | finishInfo.getDeliveryCode() << 2 |
|
||||
finishInfo.getFileStatus();
|
||||
*size += 1;
|
||||
*buffer += 1;
|
||||
|
||||
if (finishInfo.hasFsResponses()) {
|
||||
FilestoreResponseTlv **fsResponsesArray = nullptr;
|
||||
size_t fsResponsesArrayLen = 0;
|
||||
finishInfo.getFilestoreResonses(&fsResponsesArray, &fsResponsesArrayLen, nullptr);
|
||||
for (size_t idx = 0; idx < fsResponsesArrayLen; idx++) {
|
||||
result = fsResponsesArray[idx]->serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
EntityIdTlv *entityId = nullptr;
|
||||
if (finishInfo.getFaultLocation(&entityId) == HasReturnvaluesIF::RETURN_OK) {
|
||||
result = entityId->serialize(buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -1,22 +1,23 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_FINISHEDPDUSERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_FINISHEDPDUSERIALIZER_H_
|
||||
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveSerializer.h"
|
||||
#include "fsfw/cfdp/pdu/FileDataSerializer.h"
|
||||
#include "FinishedInfo.h"
|
||||
#include "fsfw/cfdp/pdu/FileDataSerializer.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveSerializer.h"
|
||||
|
||||
class FinishPduSerializer: public FileDirectiveSerializer {
|
||||
public:
|
||||
FinishPduSerializer(PduConfig& pduConf, FinishedInfo& finishInfo);
|
||||
class FinishPduSerializer : public FileDirectiveSerializer {
|
||||
public:
|
||||
FinishPduSerializer(PduConfig& pduConf, FinishedInfo& finishInfo);
|
||||
|
||||
void updateDirectiveFieldLen();
|
||||
void updateDirectiveFieldLen();
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
private:
|
||||
FinishedInfo& finishInfo;
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
private:
|
||||
FinishedInfo& finishInfo;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_FINISHEDPDUSERIALIZER_H_ */
|
||||
|
@ -1,136 +1,128 @@
|
||||
#include <fsfw/serialize/SerializeAdapter.h>
|
||||
#include "HeaderDeserializer.h"
|
||||
|
||||
#include <fsfw/serialize/SerializeAdapter.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
HeaderDeserializer::HeaderDeserializer(const uint8_t *pduBuf, size_t maxSize):
|
||||
rawPtr(pduBuf), maxSize(maxSize) {
|
||||
}
|
||||
HeaderDeserializer::HeaderDeserializer(const uint8_t *pduBuf, size_t maxSize)
|
||||
: rawPtr(pduBuf), maxSize(maxSize) {}
|
||||
|
||||
ReturnValue_t HeaderDeserializer::parseData() {
|
||||
if (maxSize < 7) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
return setData(const_cast<uint8_t*>(rawPtr), maxSize);
|
||||
if (maxSize < 7) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
return setData(const_cast<uint8_t *>(rawPtr), maxSize);
|
||||
}
|
||||
|
||||
ReturnValue_t HeaderDeserializer::setData(uint8_t *dataPtr, size_t maxSize,
|
||||
void* args) {
|
||||
if(dataPtr == nullptr) {
|
||||
// Allowed for now
|
||||
this->fixedHeader = nullptr;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
this->fixedHeader = reinterpret_cast<PduHeaderFixedStruct*>(const_cast<uint8_t*>(dataPtr));
|
||||
sourceIdRaw = static_cast<uint8_t*>(&fixedHeader->variableFieldsStart);
|
||||
cfdp::WidthInBytes widthEntityIds = getLenEntityIds();
|
||||
cfdp::WidthInBytes widthSeqNum = getLenSeqNum();
|
||||
seqNumRaw = static_cast<uint8_t*>(sourceIdRaw) + static_cast<uint8_t>(widthEntityIds);
|
||||
destIdRaw = static_cast<uint8_t*>(seqNumRaw) + static_cast<uint8_t>(widthSeqNum);
|
||||
this->maxSize = maxSize;
|
||||
ReturnValue_t HeaderDeserializer::setData(uint8_t *dataPtr, size_t maxSize, void *args) {
|
||||
if (dataPtr == nullptr) {
|
||||
// Allowed for now
|
||||
this->fixedHeader = nullptr;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
this->fixedHeader = reinterpret_cast<PduHeaderFixedStruct *>(const_cast<uint8_t *>(dataPtr));
|
||||
sourceIdRaw = static_cast<uint8_t *>(&fixedHeader->variableFieldsStart);
|
||||
cfdp::WidthInBytes widthEntityIds = getLenEntityIds();
|
||||
cfdp::WidthInBytes widthSeqNum = getLenSeqNum();
|
||||
seqNumRaw = static_cast<uint8_t *>(sourceIdRaw) + static_cast<uint8_t>(widthEntityIds);
|
||||
destIdRaw = static_cast<uint8_t *>(seqNumRaw) + static_cast<uint8_t>(widthSeqNum);
|
||||
this->maxSize = maxSize;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
size_t HeaderDeserializer::getHeaderSize() const {
|
||||
if(fixedHeader != nullptr) {
|
||||
return getLenEntityIds() * 2 + getLenSeqNum() + 4;
|
||||
}
|
||||
return 0;
|
||||
if (fixedHeader != nullptr) {
|
||||
return getLenEntityIds() * 2 + getLenSeqNum() + 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t HeaderDeserializer::getPduDataFieldLen() const {
|
||||
uint16_t pduFiedlLen = (fixedHeader->pduDataFieldLenH << 8) | fixedHeader->pduDataFieldLenL;
|
||||
return pduFiedlLen;
|
||||
uint16_t pduFiedlLen = (fixedHeader->pduDataFieldLenH << 8) | fixedHeader->pduDataFieldLenL;
|
||||
return pduFiedlLen;
|
||||
}
|
||||
|
||||
size_t HeaderDeserializer::getWholePduSize() const {
|
||||
return getPduDataFieldLen() + getHeaderSize();
|
||||
return getPduDataFieldLen() + getHeaderSize();
|
||||
}
|
||||
|
||||
cfdp::PduType HeaderDeserializer::getPduType() const {
|
||||
return static_cast<cfdp::PduType>((fixedHeader->firstByte >> 4) & 0x01);
|
||||
return static_cast<cfdp::PduType>((fixedHeader->firstByte >> 4) & 0x01);
|
||||
}
|
||||
|
||||
cfdp::Direction HeaderDeserializer::getDirection() const {
|
||||
return static_cast<cfdp::Direction>((fixedHeader->firstByte >> 3) & 0x01);
|
||||
return static_cast<cfdp::Direction>((fixedHeader->firstByte >> 3) & 0x01);
|
||||
}
|
||||
|
||||
cfdp::TransmissionModes HeaderDeserializer::getTransmissionMode() const {
|
||||
return static_cast<cfdp::TransmissionModes>((fixedHeader->firstByte >> 2) & 0x01);
|
||||
return static_cast<cfdp::TransmissionModes>((fixedHeader->firstByte >> 2) & 0x01);
|
||||
}
|
||||
|
||||
bool HeaderDeserializer::getCrcFlag() const {
|
||||
return (fixedHeader->firstByte >> 1) & 0x01;
|
||||
}
|
||||
bool HeaderDeserializer::getCrcFlag() const { return (fixedHeader->firstByte >> 1) & 0x01; }
|
||||
|
||||
bool HeaderDeserializer::getLargeFileFlag() const {
|
||||
return fixedHeader->firstByte & 0x01;
|
||||
}
|
||||
bool HeaderDeserializer::getLargeFileFlag() const { return fixedHeader->firstByte & 0x01; }
|
||||
|
||||
cfdp::SegmentationControl HeaderDeserializer::getSegmentationControl() const {
|
||||
return static_cast<cfdp::SegmentationControl>((fixedHeader->fourthByte >> 7) & 0x01);
|
||||
return static_cast<cfdp::SegmentationControl>((fixedHeader->fourthByte >> 7) & 0x01);
|
||||
}
|
||||
|
||||
cfdp::WidthInBytes HeaderDeserializer::getLenEntityIds() const {
|
||||
return static_cast<cfdp::WidthInBytes>((fixedHeader->fourthByte >> 4) & 0x07);
|
||||
return static_cast<cfdp::WidthInBytes>((fixedHeader->fourthByte >> 4) & 0x07);
|
||||
}
|
||||
|
||||
cfdp::WidthInBytes HeaderDeserializer::getLenSeqNum() const {
|
||||
return static_cast<cfdp::WidthInBytes>(fixedHeader->fourthByte & 0x07);
|
||||
return static_cast<cfdp::WidthInBytes>(fixedHeader->fourthByte & 0x07);
|
||||
}
|
||||
|
||||
cfdp::SegmentMetadataFlag HeaderDeserializer::getSegmentMetadataFlag() const {
|
||||
return static_cast<cfdp::SegmentMetadataFlag>((fixedHeader->fourthByte >> 3) & 0x01);
|
||||
return static_cast<cfdp::SegmentMetadataFlag>((fixedHeader->fourthByte >> 3) & 0x01);
|
||||
}
|
||||
|
||||
void HeaderDeserializer::getSourceId(cfdp::EntityId &sourceId) const {
|
||||
assignVarLenField(dynamic_cast<cfdp::VarLenField*>(&sourceId), getLenEntityIds(),
|
||||
this->sourceIdRaw);
|
||||
assignVarLenField(dynamic_cast<cfdp::VarLenField *>(&sourceId), getLenEntityIds(),
|
||||
this->sourceIdRaw);
|
||||
}
|
||||
|
||||
void HeaderDeserializer::getDestId(cfdp::EntityId &destId) const {
|
||||
assignVarLenField(dynamic_cast<cfdp::VarLenField*>(&destId), getLenEntityIds(),
|
||||
this->destIdRaw);
|
||||
assignVarLenField(dynamic_cast<cfdp::VarLenField *>(&destId), getLenEntityIds(), this->destIdRaw);
|
||||
}
|
||||
|
||||
void HeaderDeserializer::getTransactionSeqNum(cfdp::TransactionSeqNum &seqNum) const {
|
||||
assignVarLenField(dynamic_cast<cfdp::VarLenField*>(&seqNum), getLenSeqNum(),
|
||||
this->seqNumRaw);
|
||||
assignVarLenField(dynamic_cast<cfdp::VarLenField *>(&seqNum), getLenSeqNum(), this->seqNumRaw);
|
||||
}
|
||||
|
||||
void HeaderDeserializer::assignVarLenField(cfdp::VarLenField* field, cfdp::WidthInBytes width,
|
||||
void *sourcePtr) const {
|
||||
switch(width) {
|
||||
case(cfdp::WidthInBytes::ONE_BYTE): {
|
||||
uint8_t* fieldTyped = static_cast<uint8_t*>(sourcePtr);
|
||||
field->setValue(width, *fieldTyped);
|
||||
break;
|
||||
void HeaderDeserializer::assignVarLenField(cfdp::VarLenField *field, cfdp::WidthInBytes width,
|
||||
void *sourcePtr) const {
|
||||
switch (width) {
|
||||
case (cfdp::WidthInBytes::ONE_BYTE): {
|
||||
uint8_t *fieldTyped = static_cast<uint8_t *>(sourcePtr);
|
||||
field->setValue(width, *fieldTyped);
|
||||
break;
|
||||
}
|
||||
case(cfdp::WidthInBytes::TWO_BYTES): {
|
||||
uint16_t fieldTyped = 0;
|
||||
size_t deserSize = 0;
|
||||
SerializeAdapter::deSerialize(&fieldTyped, static_cast<uint8_t*>(sourcePtr), &deserSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
field->setValue(width, fieldTyped);
|
||||
break;
|
||||
}
|
||||
case(cfdp::WidthInBytes::FOUR_BYTES): {
|
||||
uint32_t fieldTyped = 0;
|
||||
size_t deserSize = 0;
|
||||
SerializeAdapter::deSerialize(&fieldTyped, static_cast<uint8_t*>(sourcePtr), &deserSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
field->setValue(width, fieldTyped);
|
||||
break;
|
||||
case (cfdp::WidthInBytes::TWO_BYTES): {
|
||||
uint16_t fieldTyped = 0;
|
||||
size_t deserSize = 0;
|
||||
SerializeAdapter::deSerialize(&fieldTyped, static_cast<uint8_t *>(sourcePtr), &deserSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
field->setValue(width, fieldTyped);
|
||||
break;
|
||||
}
|
||||
case (cfdp::WidthInBytes::FOUR_BYTES): {
|
||||
uint32_t fieldTyped = 0;
|
||||
size_t deserSize = 0;
|
||||
SerializeAdapter::deSerialize(&fieldTyped, static_cast<uint8_t *>(sourcePtr), &deserSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
field->setValue(width, fieldTyped);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t HeaderDeserializer::getMaxSize() const {
|
||||
return maxSize;
|
||||
}
|
||||
size_t HeaderDeserializer::getMaxSize() const { return maxSize; }
|
||||
|
||||
bool HeaderDeserializer::hasSegmentMetadataFlag() const {
|
||||
if(this->getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::PRESENT) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (this->getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::PRESENT) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1,19 +1,20 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_HEADERDESERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_HEADERDESERIALIZER_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#include "PduConfig.h"
|
||||
#include "PduHeaderIF.h"
|
||||
#include "fsfw/serialize/SerializeIF.h"
|
||||
#include "fsfw/tmtcpacket/RedirectableDataPointerIF.h"
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
struct PduHeaderFixedStruct {
|
||||
uint8_t firstByte;
|
||||
uint8_t pduDataFieldLenH;
|
||||
uint8_t pduDataFieldLenL;
|
||||
uint8_t fourthByte;
|
||||
uint8_t variableFieldsStart;
|
||||
uint8_t firstByte;
|
||||
uint8_t pduDataFieldLenH;
|
||||
uint8_t pduDataFieldLenL;
|
||||
uint8_t fourthByte;
|
||||
uint8_t variableFieldsStart;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -22,72 +23,68 @@ struct PduHeaderFixedStruct {
|
||||
* This is a zero-copy implementation and #parseData needs to be called to ensure the data is
|
||||
* valid.
|
||||
*/
|
||||
class HeaderDeserializer:
|
||||
public RedirectableDataPointerIF,
|
||||
public PduHeaderIF {
|
||||
public:
|
||||
/**
|
||||
* Initialize a PDU header from raw data. This is a zero-copy implementation and #parseData
|
||||
* needs to be called to ensure the data is valid
|
||||
* @param pduBuf
|
||||
* @param maxSize
|
||||
*/
|
||||
HeaderDeserializer(const uint8_t* pduBuf, size_t maxSize);
|
||||
class HeaderDeserializer : public RedirectableDataPointerIF, public PduHeaderIF {
|
||||
public:
|
||||
/**
|
||||
* Initialize a PDU header from raw data. This is a zero-copy implementation and #parseData
|
||||
* needs to be called to ensure the data is valid
|
||||
* @param pduBuf
|
||||
* @param maxSize
|
||||
*/
|
||||
HeaderDeserializer(const uint8_t* pduBuf, size_t maxSize);
|
||||
|
||||
/**
|
||||
* This needs to be called before accessing the PDU fields to avoid segmentation faults.
|
||||
* @return
|
||||
* - RETURN_OK on parse success
|
||||
* - RETURN_FAILED Invalid raw data
|
||||
* - SerializeIF::BUFFER_TOO_SHORT if buffer is shorter than expected
|
||||
*/
|
||||
virtual ReturnValue_t parseData();
|
||||
size_t getHeaderSize() const;
|
||||
/**
|
||||
* This needs to be called before accessing the PDU fields to avoid segmentation faults.
|
||||
* @return
|
||||
* - RETURN_OK on parse success
|
||||
* - RETURN_FAILED Invalid raw data
|
||||
* - SerializeIF::BUFFER_TOO_SHORT if buffer is shorter than expected
|
||||
*/
|
||||
virtual ReturnValue_t parseData();
|
||||
size_t getHeaderSize() const;
|
||||
|
||||
size_t getPduDataFieldLen() const override;
|
||||
size_t getWholePduSize() const override;
|
||||
size_t getPduDataFieldLen() const override;
|
||||
size_t getWholePduSize() const override;
|
||||
|
||||
cfdp::PduType getPduType() const override;
|
||||
cfdp::Direction getDirection() const override;
|
||||
cfdp::TransmissionModes getTransmissionMode() const override;
|
||||
bool getCrcFlag() const override;
|
||||
bool getLargeFileFlag() const override;
|
||||
cfdp::SegmentationControl getSegmentationControl() const override;
|
||||
cfdp::WidthInBytes getLenEntityIds() const override;
|
||||
cfdp::WidthInBytes getLenSeqNum() const override;
|
||||
cfdp::SegmentMetadataFlag getSegmentMetadataFlag() const override;
|
||||
bool hasSegmentMetadataFlag() const override;
|
||||
cfdp::PduType getPduType() const override;
|
||||
cfdp::Direction getDirection() const override;
|
||||
cfdp::TransmissionModes getTransmissionMode() const override;
|
||||
bool getCrcFlag() const override;
|
||||
bool getLargeFileFlag() const override;
|
||||
cfdp::SegmentationControl getSegmentationControl() const override;
|
||||
cfdp::WidthInBytes getLenEntityIds() const override;
|
||||
cfdp::WidthInBytes getLenSeqNum() const override;
|
||||
cfdp::SegmentMetadataFlag getSegmentMetadataFlag() const override;
|
||||
bool hasSegmentMetadataFlag() const override;
|
||||
|
||||
void getSourceId(cfdp::EntityId& sourceId) const override;
|
||||
void getDestId(cfdp::EntityId& destId) const override;
|
||||
void getTransactionSeqNum(cfdp::TransactionSeqNum& seqNum) const override;
|
||||
void getSourceId(cfdp::EntityId& sourceId) const override;
|
||||
void getDestId(cfdp::EntityId& destId) const override;
|
||||
void getTransactionSeqNum(cfdp::TransactionSeqNum& seqNum) const override;
|
||||
|
||||
ReturnValue_t deserResult = HasReturnvaluesIF::RETURN_OK;
|
||||
ReturnValue_t deserResult = HasReturnvaluesIF::RETURN_OK;
|
||||
|
||||
/**
|
||||
* Can also be used to reset the pointer to a nullptr, but the getter functions will not
|
||||
* perform nullptr checks!
|
||||
* @param dataPtr
|
||||
* @param maxSize
|
||||
* @param args
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t setData(uint8_t* dataPtr, size_t maxSize,
|
||||
void* args = nullptr) override;
|
||||
/**
|
||||
* Can also be used to reset the pointer to a nullptr, but the getter functions will not
|
||||
* perform nullptr checks!
|
||||
* @param dataPtr
|
||||
* @param maxSize
|
||||
* @param args
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t setData(uint8_t* dataPtr, size_t maxSize, void* args = nullptr) override;
|
||||
|
||||
size_t getMaxSize() const;
|
||||
protected:
|
||||
PduHeaderFixedStruct* fixedHeader = nullptr;
|
||||
const uint8_t* rawPtr = nullptr;
|
||||
size_t maxSize = 0;
|
||||
size_t getMaxSize() const;
|
||||
|
||||
private:
|
||||
protected:
|
||||
PduHeaderFixedStruct* fixedHeader = nullptr;
|
||||
const uint8_t* rawPtr = nullptr;
|
||||
size_t maxSize = 0;
|
||||
|
||||
void assignVarLenField(cfdp::VarLenField* field, cfdp::WidthInBytes width,
|
||||
void* sourcePtr) const;
|
||||
void* sourceIdRaw = nullptr;
|
||||
void* seqNumRaw = nullptr;
|
||||
void* destIdRaw = nullptr;
|
||||
private:
|
||||
void assignVarLenField(cfdp::VarLenField* field, cfdp::WidthInBytes width, void* sourcePtr) const;
|
||||
void* sourceIdRaw = nullptr;
|
||||
void* seqNumRaw = nullptr;
|
||||
void* destIdRaw = nullptr;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_HEADERDESERIALIZER_H_ */
|
||||
|
@ -1,135 +1,117 @@
|
||||
#include "HeaderSerializer.h"
|
||||
|
||||
#include "HeaderDeserializer.h"
|
||||
|
||||
HeaderSerializer::HeaderSerializer(PduConfig& pduConf, cfdp::PduType pduType,
|
||||
size_t initPduDataFieldLen, cfdp::SegmentMetadataFlag segmentMetadataFlag,
|
||||
cfdp::SegmentationControl segCtrl):
|
||||
pduType(pduType), segmentMetadataFlag(segmentMetadataFlag), segmentationCtrl(segCtrl),
|
||||
pduDataFieldLen(initPduDataFieldLen), pduConf(pduConf) {
|
||||
}
|
||||
HeaderSerializer::HeaderSerializer(PduConfig &pduConf, cfdp::PduType pduType,
|
||||
size_t initPduDataFieldLen,
|
||||
cfdp::SegmentMetadataFlag segmentMetadataFlag,
|
||||
cfdp::SegmentationControl segCtrl)
|
||||
: pduType(pduType),
|
||||
segmentMetadataFlag(segmentMetadataFlag),
|
||||
segmentationCtrl(segCtrl),
|
||||
pduDataFieldLen(initPduDataFieldLen),
|
||||
pduConf(pduConf) {}
|
||||
|
||||
ReturnValue_t HeaderSerializer::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
if(buffer == nullptr or size == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
if(maxSize < this->getSerializedSize()) {
|
||||
return BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = cfdp::VERSION_BITS | this->pduType << 4 | pduConf.direction << 3 |
|
||||
pduConf.mode << 2 | pduConf.crcFlag << 1 | pduConf.largeFile;
|
||||
*buffer += 1;
|
||||
**buffer = (pduDataFieldLen & 0xff00) >> 8;
|
||||
*buffer += 1;
|
||||
**buffer = pduDataFieldLen & 0x00ff;
|
||||
*buffer += 1;
|
||||
**buffer = segmentationCtrl << 7 | pduConf.sourceId.getWidth() << 4 |
|
||||
segmentMetadataFlag << 3 | pduConf.seqNum.getWidth();
|
||||
*buffer += 1;
|
||||
*size += 4;
|
||||
ReturnValue_t result = pduConf.sourceId.serialize(buffer, size, maxSize, streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = pduConf.seqNum.serialize(buffer, size, maxSize, streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = pduConf.destId.serialize(buffer, size, maxSize, streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
Endianness streamEndianness) const {
|
||||
if (buffer == nullptr or size == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
if (maxSize < this->getSerializedSize()) {
|
||||
return BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = cfdp::VERSION_BITS | this->pduType << 4 | pduConf.direction << 3 | pduConf.mode << 2 |
|
||||
pduConf.crcFlag << 1 | pduConf.largeFile;
|
||||
*buffer += 1;
|
||||
**buffer = (pduDataFieldLen & 0xff00) >> 8;
|
||||
*buffer += 1;
|
||||
**buffer = pduDataFieldLen & 0x00ff;
|
||||
*buffer += 1;
|
||||
**buffer = segmentationCtrl << 7 | pduConf.sourceId.getWidth() << 4 | segmentMetadataFlag << 3 |
|
||||
pduConf.seqNum.getWidth();
|
||||
*buffer += 1;
|
||||
*size += 4;
|
||||
ReturnValue_t result = pduConf.sourceId.serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = pduConf.seqNum.serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = pduConf.destId.serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
size_t HeaderSerializer::getSerializedSize() const {
|
||||
size_t shit = pduConf.seqNum.getWidth() + pduConf.sourceId.getWidth() * 2 + 4;
|
||||
return shit;
|
||||
size_t shit = pduConf.seqNum.getWidth() + pduConf.sourceId.getWidth() * 2 + 4;
|
||||
return shit;
|
||||
}
|
||||
|
||||
ReturnValue_t HeaderSerializer::deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) {
|
||||
// We could implement this, but I prefer dedicated classes
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
Endianness streamEndianness) {
|
||||
// We could implement this, but I prefer dedicated classes
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
size_t HeaderSerializer::getWholePduSize() const {
|
||||
// Return size of header plus the PDU data field length
|
||||
return pduDataFieldLen + HeaderSerializer::getSerializedSize();
|
||||
// Return size of header plus the PDU data field length
|
||||
return pduDataFieldLen + HeaderSerializer::getSerializedSize();
|
||||
}
|
||||
|
||||
size_t HeaderSerializer::getPduDataFieldLen() const {
|
||||
return pduDataFieldLen;
|
||||
}
|
||||
size_t HeaderSerializer::getPduDataFieldLen() const { return pduDataFieldLen; }
|
||||
|
||||
void HeaderSerializer::setPduDataFieldLen(size_t pduDataFieldLen) {
|
||||
this->pduDataFieldLen = pduDataFieldLen;
|
||||
this->pduDataFieldLen = pduDataFieldLen;
|
||||
}
|
||||
|
||||
void HeaderSerializer::setPduType(cfdp::PduType pduType) {
|
||||
this->pduType = pduType;
|
||||
}
|
||||
void HeaderSerializer::setPduType(cfdp::PduType pduType) { this->pduType = pduType; }
|
||||
|
||||
void HeaderSerializer::setSegmentMetadataFlag(cfdp::SegmentMetadataFlag segmentMetadataFlag) {
|
||||
this->segmentMetadataFlag = segmentMetadataFlag;
|
||||
this->segmentMetadataFlag = segmentMetadataFlag;
|
||||
}
|
||||
|
||||
cfdp::PduType HeaderSerializer::getPduType() const {
|
||||
return pduType;
|
||||
}
|
||||
cfdp::PduType HeaderSerializer::getPduType() const { return pduType; }
|
||||
|
||||
cfdp::Direction HeaderSerializer::getDirection() const {
|
||||
return pduConf.direction;
|
||||
}
|
||||
cfdp::Direction HeaderSerializer::getDirection() const { return pduConf.direction; }
|
||||
|
||||
cfdp::TransmissionModes HeaderSerializer::getTransmissionMode() const {
|
||||
return pduConf.mode;
|
||||
}
|
||||
cfdp::TransmissionModes HeaderSerializer::getTransmissionMode() const { return pduConf.mode; }
|
||||
|
||||
bool HeaderSerializer::getCrcFlag() const {
|
||||
return pduConf.crcFlag;
|
||||
}
|
||||
bool HeaderSerializer::getCrcFlag() const { return pduConf.crcFlag; }
|
||||
|
||||
bool HeaderSerializer::getLargeFileFlag() const {
|
||||
return pduConf.largeFile;
|
||||
}
|
||||
bool HeaderSerializer::getLargeFileFlag() const { return pduConf.largeFile; }
|
||||
|
||||
cfdp::SegmentationControl HeaderSerializer::getSegmentationControl() const {
|
||||
return segmentationCtrl;
|
||||
return segmentationCtrl;
|
||||
}
|
||||
|
||||
cfdp::WidthInBytes HeaderSerializer::getLenEntityIds() const {
|
||||
return pduConf.sourceId.getWidth();
|
||||
}
|
||||
cfdp::WidthInBytes HeaderSerializer::getLenEntityIds() const { return pduConf.sourceId.getWidth(); }
|
||||
|
||||
cfdp::WidthInBytes HeaderSerializer::getLenSeqNum() const {
|
||||
return pduConf.seqNum.getWidth();
|
||||
}
|
||||
cfdp::WidthInBytes HeaderSerializer::getLenSeqNum() const { return pduConf.seqNum.getWidth(); }
|
||||
|
||||
cfdp::SegmentMetadataFlag HeaderSerializer::getSegmentMetadataFlag() const {
|
||||
return segmentMetadataFlag;
|
||||
return segmentMetadataFlag;
|
||||
}
|
||||
|
||||
void HeaderSerializer::getSourceId(cfdp::EntityId &sourceId) const {
|
||||
sourceId = pduConf.sourceId;
|
||||
}
|
||||
void HeaderSerializer::getSourceId(cfdp::EntityId &sourceId) const { sourceId = pduConf.sourceId; }
|
||||
|
||||
void HeaderSerializer::getDestId(cfdp::EntityId &destId) const {
|
||||
destId = pduConf.destId;
|
||||
}
|
||||
void HeaderSerializer::getDestId(cfdp::EntityId &destId) const { destId = pduConf.destId; }
|
||||
|
||||
void HeaderSerializer::setSegmentationControl(cfdp::SegmentationControl segmentationControl) {
|
||||
this->segmentationCtrl = segmentationControl;
|
||||
this->segmentationCtrl = segmentationControl;
|
||||
}
|
||||
|
||||
void HeaderSerializer::getTransactionSeqNum(cfdp::TransactionSeqNum &seqNum) const {
|
||||
seqNum = pduConf.seqNum;
|
||||
seqNum = pduConf.seqNum;
|
||||
}
|
||||
|
||||
bool HeaderSerializer::hasSegmentMetadataFlag() const {
|
||||
if(this->segmentMetadataFlag == cfdp::SegmentMetadataFlag::PRESENT) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (this->segmentMetadataFlag == cfdp::SegmentMetadataFlag::PRESENT) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1,64 +1,63 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_HEADERSERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_HEADERSERIALIZER_H_
|
||||
|
||||
#include "PduHeaderIF.h"
|
||||
#include "fsfw/serialize/SerializeIF.h"
|
||||
#include "../definitions.h"
|
||||
#include "PduConfig.h"
|
||||
#include "PduHeaderIF.h"
|
||||
#include "fsfw/serialize/SerializeIF.h"
|
||||
|
||||
class HeaderSerializer: public SerializeIF, public PduHeaderIF {
|
||||
public:
|
||||
class HeaderSerializer : public SerializeIF, public PduHeaderIF {
|
||||
public:
|
||||
HeaderSerializer(
|
||||
PduConfig& pduConf, cfdp::PduType pduType, size_t initPduDataFieldLen,
|
||||
cfdp::SegmentMetadataFlag segmentMetadataFlag = cfdp::SegmentMetadataFlag::NOT_PRESENT,
|
||||
cfdp::SegmentationControl segCtrl =
|
||||
cfdp::SegmentationControl::NO_RECORD_BOUNDARIES_PRESERVATION);
|
||||
|
||||
HeaderSerializer(PduConfig& pduConf, cfdp::PduType pduType,
|
||||
size_t initPduDataFieldLen,
|
||||
cfdp::SegmentMetadataFlag segmentMetadataFlag = cfdp::SegmentMetadataFlag::NOT_PRESENT,
|
||||
cfdp::SegmentationControl segCtrl =
|
||||
cfdp::SegmentationControl::NO_RECORD_BOUNDARIES_PRESERVATION);
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
/**
|
||||
* This only returns the length of the serialized hader.
|
||||
* Use #getWholePduSize to get the length of the full packet, assuming that the PDU
|
||||
* data field length was not properly.
|
||||
* @return
|
||||
*/
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
/**
|
||||
* This only returns the length of the serialized hader.
|
||||
* Use #getWholePduSize to get the length of the full packet, assuming that the PDU
|
||||
* data field length was not properly.
|
||||
* @return
|
||||
*/
|
||||
size_t getSerializedSize() const override;
|
||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override;
|
||||
void setPduDataFieldLen(size_t pduDataFieldLen);
|
||||
void setPduType(cfdp::PduType pduType);
|
||||
void setSegmentMetadataFlag(cfdp::SegmentMetadataFlag);
|
||||
|
||||
void setPduDataFieldLen(size_t pduDataFieldLen);
|
||||
void setPduType(cfdp::PduType pduType);
|
||||
void setSegmentMetadataFlag(cfdp::SegmentMetadataFlag);
|
||||
size_t getPduDataFieldLen() const override;
|
||||
size_t getWholePduSize() const override;
|
||||
|
||||
size_t getPduDataFieldLen() const override;
|
||||
size_t getWholePduSize() const override;
|
||||
cfdp::PduType getPduType() const override;
|
||||
cfdp::Direction getDirection() const override;
|
||||
cfdp::TransmissionModes getTransmissionMode() const override;
|
||||
bool getCrcFlag() const override;
|
||||
bool getLargeFileFlag() const override;
|
||||
cfdp::SegmentationControl getSegmentationControl() const override;
|
||||
cfdp::WidthInBytes getLenEntityIds() const override;
|
||||
cfdp::WidthInBytes getLenSeqNum() const override;
|
||||
cfdp::SegmentMetadataFlag getSegmentMetadataFlag() const override;
|
||||
bool hasSegmentMetadataFlag() const;
|
||||
void setSegmentationControl(cfdp::SegmentationControl);
|
||||
|
||||
cfdp::PduType getPduType() const override;
|
||||
cfdp::Direction getDirection() const override;
|
||||
cfdp::TransmissionModes getTransmissionMode() const override;
|
||||
bool getCrcFlag() const override;
|
||||
bool getLargeFileFlag() const override;
|
||||
cfdp::SegmentationControl getSegmentationControl() const override;
|
||||
cfdp::WidthInBytes getLenEntityIds() const override;
|
||||
cfdp::WidthInBytes getLenSeqNum() const override;
|
||||
cfdp::SegmentMetadataFlag getSegmentMetadataFlag() const override;
|
||||
bool hasSegmentMetadataFlag() const;
|
||||
void setSegmentationControl(cfdp::SegmentationControl);
|
||||
void getSourceId(cfdp::EntityId& sourceId) const override;
|
||||
void getDestId(cfdp::EntityId& destId) const override;
|
||||
void getTransactionSeqNum(cfdp::TransactionSeqNum& seqNum) const override;
|
||||
|
||||
void getSourceId(cfdp::EntityId& sourceId) const override;
|
||||
void getDestId(cfdp::EntityId& destId) const override;
|
||||
void getTransactionSeqNum(cfdp::TransactionSeqNum& seqNum) const override;
|
||||
private:
|
||||
cfdp::PduType pduType;
|
||||
cfdp::SegmentMetadataFlag segmentMetadataFlag;
|
||||
cfdp::SegmentationControl segmentationCtrl;
|
||||
size_t pduDataFieldLen;
|
||||
private:
|
||||
cfdp::PduType pduType;
|
||||
cfdp::SegmentMetadataFlag segmentMetadataFlag;
|
||||
cfdp::SegmentationControl segmentationCtrl;
|
||||
size_t pduDataFieldLen;
|
||||
|
||||
PduConfig& pduConf;
|
||||
PduConfig& pduConf;
|
||||
};
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_HEADERSERIALIZER_H_ */
|
||||
|
@ -1,20 +1,18 @@
|
||||
#include "KeepAlivePduDeserializer.h"
|
||||
|
||||
KeepAlivePduDeserializer::KeepAlivePduDeserializer(const uint8_t *pduBuf, size_t maxSize,
|
||||
cfdp::FileSize &progress): FileDirectiveDeserializer(pduBuf, maxSize), progress(progress) {
|
||||
}
|
||||
KeepAlivePduDeserializer::KeepAlivePduDeserializer(const uint8_t* pduBuf, size_t maxSize,
|
||||
cfdp::FileSize& progress)
|
||||
: FileDirectiveDeserializer(pduBuf, maxSize), progress(progress) {}
|
||||
|
||||
ReturnValue_t KeepAlivePduDeserializer::parseData() {
|
||||
ReturnValue_t result = FileDirectiveDeserializer::parseData();
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
size_t currentIdx = FileDirectiveDeserializer::getHeaderSize();
|
||||
size_t remLen = FileDirectiveDeserializer::getWholePduSize() - currentIdx;
|
||||
const uint8_t* buffer = rawPtr + currentIdx;
|
||||
return progress.deSerialize(&buffer, &remLen, getEndianness());
|
||||
ReturnValue_t result = FileDirectiveDeserializer::parseData();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
size_t currentIdx = FileDirectiveDeserializer::getHeaderSize();
|
||||
size_t remLen = FileDirectiveDeserializer::getWholePduSize() - currentIdx;
|
||||
const uint8_t* buffer = rawPtr + currentIdx;
|
||||
return progress.deSerialize(&buffer, &remLen, getEndianness());
|
||||
}
|
||||
|
||||
cfdp::FileSize& KeepAlivePduDeserializer::getProgress() {
|
||||
return progress;
|
||||
}
|
||||
cfdp::FileSize& KeepAlivePduDeserializer::getProgress() { return progress; }
|
||||
|
@ -4,15 +4,16 @@
|
||||
#include "fsfw/cfdp/FileSize.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveDeserializer.h"
|
||||
|
||||
class KeepAlivePduDeserializer: public FileDirectiveDeserializer {
|
||||
public:
|
||||
KeepAlivePduDeserializer(const uint8_t *pduBuf, size_t maxSize, cfdp::FileSize& progress);
|
||||
class KeepAlivePduDeserializer : public FileDirectiveDeserializer {
|
||||
public:
|
||||
KeepAlivePduDeserializer(const uint8_t* pduBuf, size_t maxSize, cfdp::FileSize& progress);
|
||||
|
||||
ReturnValue_t parseData() override;
|
||||
ReturnValue_t parseData() override;
|
||||
|
||||
cfdp::FileSize& getProgress();
|
||||
private:
|
||||
cfdp::FileSize& progress;
|
||||
cfdp::FileSize& getProgress();
|
||||
|
||||
private:
|
||||
cfdp::FileSize& progress;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_KEEPALIVEPDUDESERIALIZER_H_ */
|
||||
|
@ -1,26 +1,26 @@
|
||||
#include "KeepAlivePduSerializer.h"
|
||||
|
||||
KeepAlivePduSerializer::KeepAlivePduSerializer(PduConfig &conf, cfdp::FileSize& progress):
|
||||
FileDirectiveSerializer(conf, cfdp::FileDirectives::KEEP_ALIVE, 4), progress(progress) {
|
||||
updateDirectiveFieldLen();
|
||||
KeepAlivePduSerializer::KeepAlivePduSerializer(PduConfig &conf, cfdp::FileSize &progress)
|
||||
: FileDirectiveSerializer(conf, cfdp::FileDirectives::KEEP_ALIVE, 4), progress(progress) {
|
||||
updateDirectiveFieldLen();
|
||||
}
|
||||
|
||||
size_t KeepAlivePduSerializer::getSerializedSize() const {
|
||||
return FileDirectiveSerializer::getWholePduSize();
|
||||
return FileDirectiveSerializer::getWholePduSize();
|
||||
}
|
||||
|
||||
void KeepAlivePduSerializer::updateDirectiveFieldLen() {
|
||||
if(this->getLargeFileFlag()) {
|
||||
this->setDirectiveDataFieldLen(8);
|
||||
}
|
||||
if (this->getLargeFileFlag()) {
|
||||
this->setDirectiveDataFieldLen(8);
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t KeepAlivePduSerializer::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result = FileDirectiveSerializer::serialize(buffer, size, maxSize,
|
||||
streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return progress.serialize(this->getLargeFileFlag(), buffer, size, maxSize, streamEndianness);
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result =
|
||||
FileDirectiveSerializer::serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return progress.serialize(this->getLargeFileFlag(), buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
|
@ -4,18 +4,19 @@
|
||||
#include "fsfw/cfdp/FileSize.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveSerializer.h"
|
||||
|
||||
class KeepAlivePduSerializer: public FileDirectiveSerializer {
|
||||
public:
|
||||
KeepAlivePduSerializer(PduConfig& conf, cfdp::FileSize& progress);
|
||||
class KeepAlivePduSerializer : public FileDirectiveSerializer {
|
||||
public:
|
||||
KeepAlivePduSerializer(PduConfig& conf, cfdp::FileSize& progress);
|
||||
|
||||
void updateDirectiveFieldLen();
|
||||
void updateDirectiveFieldLen();
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
private:
|
||||
cfdp::FileSize& progress;
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
private:
|
||||
cfdp::FileSize& progress;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_KEEPALIVEPDUSERIALIZER_H_ */
|
||||
|
@ -1,115 +1,98 @@
|
||||
#include "MetadataInfo.h"
|
||||
|
||||
MetadataInfo::MetadataInfo(bool closureRequested, cfdp::ChecksumType checksumType,
|
||||
cfdp::FileSize& fileSize, cfdp::Lv& sourceFileName, cfdp::Lv& destFileName):
|
||||
closureRequested(closureRequested), checksumType(checksumType), fileSize(fileSize),
|
||||
sourceFileName(sourceFileName), destFileName(destFileName) {
|
||||
}
|
||||
cfdp::FileSize& fileSize, cfdp::Lv& sourceFileName,
|
||||
cfdp::Lv& destFileName)
|
||||
: closureRequested(closureRequested),
|
||||
checksumType(checksumType),
|
||||
fileSize(fileSize),
|
||||
sourceFileName(sourceFileName),
|
||||
destFileName(destFileName) {}
|
||||
|
||||
void MetadataInfo::setOptionsArray(cfdp::Tlv** optionsArray, size_t* optionsLen,
|
||||
size_t* maxOptionsLen) {
|
||||
this->optionsArray = optionsArray;
|
||||
if(maxOptionsLen != nullptr) {
|
||||
this->maxOptionsLen = *maxOptionsLen;
|
||||
}
|
||||
if(optionsLen != nullptr) {
|
||||
this->optionsLen = *optionsLen;
|
||||
}
|
||||
size_t* maxOptionsLen) {
|
||||
this->optionsArray = optionsArray;
|
||||
if (maxOptionsLen != nullptr) {
|
||||
this->maxOptionsLen = *maxOptionsLen;
|
||||
}
|
||||
if (optionsLen != nullptr) {
|
||||
this->optionsLen = *optionsLen;
|
||||
}
|
||||
}
|
||||
|
||||
cfdp::ChecksumType MetadataInfo::getChecksumType() const {
|
||||
return checksumType;
|
||||
}
|
||||
cfdp::ChecksumType MetadataInfo::getChecksumType() const { return checksumType; }
|
||||
|
||||
void MetadataInfo::setChecksumType(cfdp::ChecksumType checksumType) {
|
||||
this->checksumType = checksumType;
|
||||
this->checksumType = checksumType;
|
||||
}
|
||||
|
||||
bool MetadataInfo::isClosureRequested() const {
|
||||
return closureRequested;
|
||||
}
|
||||
bool MetadataInfo::isClosureRequested() const { return closureRequested; }
|
||||
|
||||
void MetadataInfo::setClosureRequested(bool closureRequested) {
|
||||
this->closureRequested = closureRequested;
|
||||
this->closureRequested = closureRequested;
|
||||
}
|
||||
|
||||
cfdp::Lv& MetadataInfo::getDestFileName() {
|
||||
return destFileName;
|
||||
}
|
||||
cfdp::Lv& MetadataInfo::getDestFileName() { return destFileName; }
|
||||
|
||||
cfdp::FileSize& MetadataInfo::getFileSize() {
|
||||
return fileSize;
|
||||
}
|
||||
cfdp::FileSize& MetadataInfo::getFileSize() { return fileSize; }
|
||||
|
||||
ReturnValue_t MetadataInfo::getOptions(cfdp::Tlv*** optionsArray, size_t *optionsLen,
|
||||
size_t* maxOptsLen) {
|
||||
if(optionsArray == nullptr or this->optionsArray == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
*optionsArray = this->optionsArray;
|
||||
if(optionsLen != nullptr) {
|
||||
*optionsLen = this->optionsLen;
|
||||
}
|
||||
if(maxOptsLen != nullptr) {
|
||||
*maxOptsLen = this->maxOptionsLen;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
ReturnValue_t MetadataInfo::getOptions(cfdp::Tlv*** optionsArray, size_t* optionsLen,
|
||||
size_t* maxOptsLen) {
|
||||
if (optionsArray == nullptr or this->optionsArray == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
*optionsArray = this->optionsArray;
|
||||
if (optionsLen != nullptr) {
|
||||
*optionsLen = this->optionsLen;
|
||||
}
|
||||
if (maxOptsLen != nullptr) {
|
||||
*maxOptsLen = this->maxOptionsLen;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
bool MetadataInfo::hasOptions() const {
|
||||
if (optionsArray != nullptr and optionsLen > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (optionsArray != nullptr and optionsLen > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MetadataInfo::canHoldOptions() const {
|
||||
if (optionsArray != nullptr and maxOptionsLen > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (optionsArray != nullptr and maxOptionsLen > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t MetadataInfo::getSerializedSize(bool fssLarge) {
|
||||
// 1 byte + minimal FSS 4 bytes
|
||||
size_t size = 5;
|
||||
if(fssLarge) {
|
||||
size += 4;
|
||||
// 1 byte + minimal FSS 4 bytes
|
||||
size_t size = 5;
|
||||
if (fssLarge) {
|
||||
size += 4;
|
||||
}
|
||||
size += sourceFileName.getSerializedSize();
|
||||
size += destFileName.getSerializedSize();
|
||||
if (hasOptions()) {
|
||||
for (size_t idx = 0; idx < optionsLen; idx++) {
|
||||
size += optionsArray[idx]->getSerializedSize();
|
||||
}
|
||||
size += sourceFileName.getSerializedSize();
|
||||
size += destFileName.getSerializedSize();
|
||||
if(hasOptions()) {
|
||||
for(size_t idx = 0; idx < optionsLen; idx++) {
|
||||
size += optionsArray[idx]->getSerializedSize();
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
void MetadataInfo::setDestFileName(cfdp::Lv &destFileName) {
|
||||
this->destFileName = destFileName;
|
||||
void MetadataInfo::setDestFileName(cfdp::Lv& destFileName) { this->destFileName = destFileName; }
|
||||
|
||||
void MetadataInfo::setSourceFileName(cfdp::Lv& sourceFileName) {
|
||||
this->sourceFileName = sourceFileName;
|
||||
}
|
||||
|
||||
void MetadataInfo::setSourceFileName(cfdp::Lv &sourceFileName) {
|
||||
this->sourceFileName = sourceFileName;
|
||||
}
|
||||
size_t MetadataInfo::getMaxOptionsLen() const { return maxOptionsLen; }
|
||||
|
||||
size_t MetadataInfo::getMaxOptionsLen() const {
|
||||
return maxOptionsLen;
|
||||
}
|
||||
void MetadataInfo::setMaxOptionsLen(size_t maxOptionsLen) { this->maxOptionsLen = maxOptionsLen; }
|
||||
|
||||
void MetadataInfo::setMaxOptionsLen(size_t maxOptionsLen) {
|
||||
this->maxOptionsLen = maxOptionsLen;
|
||||
}
|
||||
size_t MetadataInfo::getOptionsLen() const { return optionsLen; }
|
||||
|
||||
size_t MetadataInfo::getOptionsLen() const {
|
||||
return optionsLen;
|
||||
}
|
||||
void MetadataInfo::setOptionsLen(size_t optionsLen) { this->optionsLen = optionsLen; }
|
||||
|
||||
void MetadataInfo::setOptionsLen(size_t optionsLen) {
|
||||
this->optionsLen = optionsLen;
|
||||
}
|
||||
|
||||
cfdp::Lv& MetadataInfo::getSourceFileName() {
|
||||
return sourceFileName;
|
||||
}
|
||||
cfdp::Lv& MetadataInfo::getSourceFileName() { return sourceFileName; }
|
||||
|
@ -1,49 +1,49 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_METADATAINFO_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_METADATAINFO_H_
|
||||
|
||||
#include "fsfw/cfdp/tlv/Tlv.h"
|
||||
#include "fsfw/cfdp/tlv/Lv.h"
|
||||
#include "fsfw/cfdp/FileSize.h"
|
||||
#include "fsfw/cfdp/definitions.h"
|
||||
#include "fsfw/cfdp/tlv/Lv.h"
|
||||
#include "fsfw/cfdp/tlv/Tlv.h"
|
||||
|
||||
class MetadataInfo {
|
||||
public:
|
||||
MetadataInfo(bool closureRequested, cfdp::ChecksumType checksumType, cfdp::FileSize& fileSize,
|
||||
cfdp::Lv& sourceFileName, cfdp::Lv& destFileName);
|
||||
public:
|
||||
MetadataInfo(bool closureRequested, cfdp::ChecksumType checksumType, cfdp::FileSize& fileSize,
|
||||
cfdp::Lv& sourceFileName, cfdp::Lv& destFileName);
|
||||
|
||||
size_t getSerializedSize(bool fssLarge = false);
|
||||
size_t getSerializedSize(bool fssLarge = false);
|
||||
|
||||
void setOptionsArray(cfdp::Tlv** optionsArray, size_t* optionsLen, size_t* maxOptionsLen);
|
||||
cfdp::ChecksumType getChecksumType() const;
|
||||
void setChecksumType(cfdp::ChecksumType checksumType);
|
||||
bool isClosureRequested() const;
|
||||
void setClosureRequested(bool closureRequested = false);
|
||||
void setOptionsArray(cfdp::Tlv** optionsArray, size_t* optionsLen, size_t* maxOptionsLen);
|
||||
cfdp::ChecksumType getChecksumType() const;
|
||||
void setChecksumType(cfdp::ChecksumType checksumType);
|
||||
bool isClosureRequested() const;
|
||||
void setClosureRequested(bool closureRequested = false);
|
||||
|
||||
void setDestFileName(cfdp::Lv& destFileName);
|
||||
void setSourceFileName(cfdp::Lv& sourceFileName);
|
||||
void setDestFileName(cfdp::Lv& destFileName);
|
||||
void setSourceFileName(cfdp::Lv& sourceFileName);
|
||||
|
||||
cfdp::Lv& getDestFileName();
|
||||
cfdp::Lv& getSourceFileName();
|
||||
cfdp::FileSize& getFileSize();
|
||||
cfdp::Lv& getDestFileName();
|
||||
cfdp::Lv& getSourceFileName();
|
||||
cfdp::FileSize& getFileSize();
|
||||
|
||||
bool hasOptions() const;
|
||||
bool canHoldOptions() const;
|
||||
ReturnValue_t getOptions(cfdp::Tlv*** optionsArray, size_t* optionsLen, size_t* maxOptsLen);
|
||||
void setOptionsLen(size_t optionsLen);
|
||||
size_t getOptionsLen() const;
|
||||
void setMaxOptionsLen(size_t maxOptionsLen);
|
||||
size_t getMaxOptionsLen() const;
|
||||
bool hasOptions() const;
|
||||
bool canHoldOptions() const;
|
||||
ReturnValue_t getOptions(cfdp::Tlv*** optionsArray, size_t* optionsLen, size_t* maxOptsLen);
|
||||
void setOptionsLen(size_t optionsLen);
|
||||
size_t getOptionsLen() const;
|
||||
void setMaxOptionsLen(size_t maxOptionsLen);
|
||||
size_t getMaxOptionsLen() const;
|
||||
|
||||
private:
|
||||
bool closureRequested = false;
|
||||
cfdp::ChecksumType checksumType;
|
||||
cfdp::FileSize& fileSize;
|
||||
cfdp::Lv& sourceFileName;
|
||||
cfdp::Lv& destFileName;
|
||||
private:
|
||||
bool closureRequested = false;
|
||||
cfdp::ChecksumType checksumType;
|
||||
cfdp::FileSize& fileSize;
|
||||
cfdp::Lv& sourceFileName;
|
||||
cfdp::Lv& destFileName;
|
||||
|
||||
cfdp::Tlv** optionsArray = nullptr;
|
||||
size_t optionsLen = 0;
|
||||
size_t maxOptionsLen = 0;
|
||||
cfdp::Tlv** optionsArray = nullptr;
|
||||
size_t optionsLen = 0;
|
||||
size_t maxOptionsLen = 0;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_METADATAINFO_H_ */
|
||||
|
@ -1,58 +1,58 @@
|
||||
#include "MetadataPduDeserializer.h"
|
||||
|
||||
MetadataPduDeserializer::MetadataPduDeserializer(const uint8_t *pduBuf, size_t maxSize,
|
||||
MetadataInfo &info): FileDirectiveDeserializer(pduBuf, maxSize), info(info) {
|
||||
}
|
||||
MetadataPduDeserializer::MetadataPduDeserializer(const uint8_t* pduBuf, size_t maxSize,
|
||||
MetadataInfo& info)
|
||||
: FileDirectiveDeserializer(pduBuf, maxSize), info(info) {}
|
||||
|
||||
ReturnValue_t MetadataPduDeserializer::parseData() {
|
||||
ReturnValue_t result = FileDirectiveDeserializer::parseData();
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
size_t currentIdx = FileDirectiveDeserializer::getHeaderSize();
|
||||
const uint8_t* buf = rawPtr + currentIdx;
|
||||
size_t remSize = FileDirectiveDeserializer::getWholePduSize() - currentIdx;
|
||||
if (remSize < 1) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
info.setClosureRequested((*buf >> 6) & 0x01);
|
||||
info.setChecksumType(static_cast<cfdp::ChecksumType>(*buf & 0x0f));
|
||||
remSize -= 1;
|
||||
buf += 1;
|
||||
auto endianness = getEndianness();
|
||||
result = info.getFileSize().deSerialize(&buf, &remSize, endianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = info.getSourceFileName().deSerialize(&buf, &remSize, endianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = info.getDestFileName().deSerialize(&buf, &remSize, endianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
info.setOptionsLen(0);
|
||||
if (remSize > 0) {
|
||||
if(not info.canHoldOptions()) {
|
||||
return cfdp::METADATA_CANT_PARSE_OPTIONS;
|
||||
}
|
||||
cfdp::Tlv** optionsArray = nullptr;
|
||||
size_t optsMaxLen = 0;
|
||||
size_t optsIdx = 0;
|
||||
info.getOptions(&optionsArray, nullptr, &optsMaxLen);
|
||||
while(remSize > 0) {
|
||||
if(optsIdx > optsMaxLen) {
|
||||
return cfdp::METADATA_CANT_PARSE_OPTIONS;
|
||||
}
|
||||
result = optionsArray[optsIdx]->deSerialize(&buf, &remSize, endianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
optsIdx++;
|
||||
}
|
||||
info.setOptionsLen(optsIdx);
|
||||
}
|
||||
ReturnValue_t result = FileDirectiveDeserializer::parseData();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
size_t currentIdx = FileDirectiveDeserializer::getHeaderSize();
|
||||
const uint8_t* buf = rawPtr + currentIdx;
|
||||
size_t remSize = FileDirectiveDeserializer::getWholePduSize() - currentIdx;
|
||||
if (remSize < 1) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
info.setClosureRequested((*buf >> 6) & 0x01);
|
||||
info.setChecksumType(static_cast<cfdp::ChecksumType>(*buf & 0x0f));
|
||||
remSize -= 1;
|
||||
buf += 1;
|
||||
auto endianness = getEndianness();
|
||||
result = info.getFileSize().deSerialize(&buf, &remSize, endianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = info.getSourceFileName().deSerialize(&buf, &remSize, endianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = info.getDestFileName().deSerialize(&buf, &remSize, endianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
info.setOptionsLen(0);
|
||||
if (remSize > 0) {
|
||||
if (not info.canHoldOptions()) {
|
||||
return cfdp::METADATA_CANT_PARSE_OPTIONS;
|
||||
}
|
||||
cfdp::Tlv** optionsArray = nullptr;
|
||||
size_t optsMaxLen = 0;
|
||||
size_t optsIdx = 0;
|
||||
info.getOptions(&optionsArray, nullptr, &optsMaxLen);
|
||||
while (remSize > 0) {
|
||||
if (optsIdx > optsMaxLen) {
|
||||
return cfdp::METADATA_CANT_PARSE_OPTIONS;
|
||||
}
|
||||
result = optionsArray[optsIdx]->deSerialize(&buf, &remSize, endianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
optsIdx++;
|
||||
}
|
||||
info.setOptionsLen(optsIdx);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -4,15 +4,14 @@
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveDeserializer.h"
|
||||
#include "fsfw/cfdp/pdu/MetadataInfo.h"
|
||||
|
||||
class MetadataPduDeserializer: public FileDirectiveDeserializer {
|
||||
public:
|
||||
MetadataPduDeserializer(const uint8_t* pduBuf, size_t maxSize, MetadataInfo& info);
|
||||
class MetadataPduDeserializer : public FileDirectiveDeserializer {
|
||||
public:
|
||||
MetadataPduDeserializer(const uint8_t* pduBuf, size_t maxSize, MetadataInfo& info);
|
||||
|
||||
ReturnValue_t parseData() override;
|
||||
private:
|
||||
MetadataInfo& info;
|
||||
ReturnValue_t parseData() override;
|
||||
|
||||
private:
|
||||
MetadataInfo& info;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_METADATAPDUDESERIALIZER_H_ */
|
||||
|
@ -1,54 +1,54 @@
|
||||
#include "MetadataPduSerializer.h"
|
||||
|
||||
MetadataPduSerializer::MetadataPduSerializer(PduConfig &conf, MetadataInfo &info):
|
||||
FileDirectiveSerializer(conf, cfdp::FileDirectives::METADATA, 5), info(info) {
|
||||
updateDirectiveFieldLen();
|
||||
MetadataPduSerializer::MetadataPduSerializer(PduConfig &conf, MetadataInfo &info)
|
||||
: FileDirectiveSerializer(conf, cfdp::FileDirectives::METADATA, 5), info(info) {
|
||||
updateDirectiveFieldLen();
|
||||
}
|
||||
|
||||
void MetadataPduSerializer::updateDirectiveFieldLen() {
|
||||
setDirectiveDataFieldLen(info.getSerializedSize(getLargeFileFlag()));
|
||||
setDirectiveDataFieldLen(info.getSerializedSize(getLargeFileFlag()));
|
||||
}
|
||||
|
||||
size_t MetadataPduSerializer::getSerializedSize() const {
|
||||
return FileDirectiveSerializer::getWholePduSize();
|
||||
return FileDirectiveSerializer::getWholePduSize();
|
||||
}
|
||||
|
||||
ReturnValue_t MetadataPduSerializer::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result = FileDirectiveSerializer::serialize(buffer, size, maxSize,
|
||||
streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if(*size + 1 >= maxSize) {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = info.isClosureRequested() << 6 | info.getChecksumType();
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
result = info.getFileSize().serialize(buffer, size, maxSize, streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = info.getSourceFileName().serialize(buffer, size, maxSize, streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = info.getDestFileName().serialize(buffer, size, maxSize, streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if(info.hasOptions()) {
|
||||
cfdp::Tlv** optsArray = nullptr;
|
||||
size_t optsLen = 0;
|
||||
info.getOptions(&optsArray, &optsLen, nullptr);
|
||||
for(size_t idx = 0; idx < optsLen; idx++) {
|
||||
result = optsArray[idx]->serialize(buffer, size, maxSize, streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result =
|
||||
FileDirectiveSerializer::serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if (*size + 1 >= maxSize) {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = info.isClosureRequested() << 6 | info.getChecksumType();
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
result = info.getFileSize().serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = info.getSourceFileName().serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = info.getDestFileName().serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (info.hasOptions()) {
|
||||
cfdp::Tlv **optsArray = nullptr;
|
||||
size_t optsLen = 0;
|
||||
info.getOptions(&optsArray, &optsLen, nullptr);
|
||||
for (size_t idx = 0; idx < optsLen; idx++) {
|
||||
result = optsArray[idx]->serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -1,23 +1,22 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_METADATAPDUSERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_METADATAPDUSERIALIZER_H_
|
||||
|
||||
#include "fsfw/cfdp/pdu/MetadataInfo.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveSerializer.h"
|
||||
#include "fsfw/cfdp/pdu/MetadataInfo.h"
|
||||
|
||||
class MetadataPduSerializer: public FileDirectiveSerializer {
|
||||
public:
|
||||
MetadataPduSerializer(PduConfig &conf, MetadataInfo& info);
|
||||
class MetadataPduSerializer : public FileDirectiveSerializer {
|
||||
public:
|
||||
MetadataPduSerializer(PduConfig& conf, MetadataInfo& info);
|
||||
|
||||
void updateDirectiveFieldLen();
|
||||
void updateDirectiveFieldLen();
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
private:
|
||||
MetadataInfo& info;
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
private:
|
||||
MetadataInfo& info;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_METADATAPDUSERIALIZER_H_ */
|
||||
|
@ -1,83 +1,70 @@
|
||||
#include "NakInfo.h"
|
||||
|
||||
NakInfo::NakInfo(cfdp::FileSize startOfScope, cfdp::FileSize endOfScope):
|
||||
startOfScope(startOfScope), endOfScope(endOfScope) {
|
||||
}
|
||||
NakInfo::NakInfo(cfdp::FileSize startOfScope, cfdp::FileSize endOfScope)
|
||||
: startOfScope(startOfScope), endOfScope(endOfScope) {}
|
||||
|
||||
size_t NakInfo::getSerializedSize(bool fssLarge) {
|
||||
size_t size = 8;
|
||||
if(fssLarge) {
|
||||
size += 8;
|
||||
size_t size = 8;
|
||||
if (fssLarge) {
|
||||
size += 8;
|
||||
}
|
||||
if (hasSegmentRequests()) {
|
||||
if (fssLarge) {
|
||||
size += segmentRequestsLen * 16;
|
||||
} else {
|
||||
size += segmentRequestsLen * 8;
|
||||
}
|
||||
if(hasSegmentRequests()) {
|
||||
if(fssLarge) {
|
||||
size += segmentRequestsLen * 16;
|
||||
} else {
|
||||
size += segmentRequestsLen * 8;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
bool NakInfo::hasSegmentRequests() const {
|
||||
if(this->segmentRequests != nullptr and segmentRequestsLen > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (this->segmentRequests != nullptr and segmentRequestsLen > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NakInfo::canHoldSegmentRequests() const {
|
||||
if(this->segmentRequests != nullptr and maxSegmentRequestsLen > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NakInfo::getSegmentRequests(SegmentRequest **segmentRequestPtr,
|
||||
size_t *segmentRequestLen, size_t* maxSegmentRequestsLen) {
|
||||
if(this->segmentRequests != nullptr) {
|
||||
*segmentRequestPtr = this->segmentRequests;
|
||||
}
|
||||
if(segmentRequestLen != nullptr) {
|
||||
*segmentRequestLen = this->segmentRequestsLen;
|
||||
}
|
||||
if(maxSegmentRequestsLen != nullptr) {
|
||||
*maxSegmentRequestsLen = this->maxSegmentRequestsLen;
|
||||
}
|
||||
if (this->segmentRequests != nullptr and maxSegmentRequestsLen > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void NakInfo::setSegmentRequests(SegmentRequest *segmentRequests, size_t* segmentRequestLen,
|
||||
size_t* maxSegmentRequestLen) {
|
||||
this->segmentRequests = segmentRequests;
|
||||
if(segmentRequestLen != nullptr) {
|
||||
this->segmentRequestsLen = *segmentRequestLen;
|
||||
}
|
||||
if(maxSegmentRequestLen != nullptr) {
|
||||
this->maxSegmentRequestsLen = *maxSegmentRequestLen;
|
||||
}
|
||||
bool NakInfo::getSegmentRequests(SegmentRequest** segmentRequestPtr, size_t* segmentRequestLen,
|
||||
size_t* maxSegmentRequestsLen) {
|
||||
if (this->segmentRequests != nullptr) {
|
||||
*segmentRequestPtr = this->segmentRequests;
|
||||
}
|
||||
if (segmentRequestLen != nullptr) {
|
||||
*segmentRequestLen = this->segmentRequestsLen;
|
||||
}
|
||||
if (maxSegmentRequestsLen != nullptr) {
|
||||
*maxSegmentRequestsLen = this->maxSegmentRequestsLen;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
cfdp::FileSize& NakInfo::getStartOfScope() {
|
||||
return startOfScope;
|
||||
void NakInfo::setSegmentRequests(SegmentRequest* segmentRequests, size_t* segmentRequestLen,
|
||||
size_t* maxSegmentRequestLen) {
|
||||
this->segmentRequests = segmentRequests;
|
||||
if (segmentRequestLen != nullptr) {
|
||||
this->segmentRequestsLen = *segmentRequestLen;
|
||||
}
|
||||
if (maxSegmentRequestLen != nullptr) {
|
||||
this->maxSegmentRequestsLen = *maxSegmentRequestLen;
|
||||
}
|
||||
}
|
||||
|
||||
cfdp::FileSize& NakInfo::getEndOfScope() {
|
||||
return endOfScope;
|
||||
}
|
||||
cfdp::FileSize& NakInfo::getStartOfScope() { return startOfScope; }
|
||||
|
||||
size_t NakInfo::getSegmentRequestsLen() const {
|
||||
return segmentRequestsLen;
|
||||
}
|
||||
cfdp::FileSize& NakInfo::getEndOfScope() { return endOfScope; }
|
||||
|
||||
size_t NakInfo::getSegmentRequestsMaxLen() const {
|
||||
return maxSegmentRequestsLen;
|
||||
}
|
||||
size_t NakInfo::getSegmentRequestsLen() const { return segmentRequestsLen; }
|
||||
|
||||
void NakInfo::setSegmentRequestLen(size_t readLen) {
|
||||
this->segmentRequestsLen = readLen;
|
||||
}
|
||||
size_t NakInfo::getSegmentRequestsMaxLen() const { return maxSegmentRequestsLen; }
|
||||
|
||||
void NakInfo::setMaxSegmentRequestLen(size_t maxSize) {
|
||||
this->maxSegmentRequestsLen = maxSize;
|
||||
}
|
||||
void NakInfo::setSegmentRequestLen(size_t readLen) { this->segmentRequestsLen = readLen; }
|
||||
|
||||
void NakInfo::setMaxSegmentRequestLen(size_t maxSize) { this->maxSegmentRequestsLen = maxSize; }
|
||||
|
@ -1,40 +1,41 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_NAKINFO_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_NAKINFO_H_
|
||||
|
||||
#include "fsfw/cfdp/FileSize.h"
|
||||
#include <utility>
|
||||
|
||||
#include "fsfw/cfdp/FileSize.h"
|
||||
|
||||
class NakInfo {
|
||||
public:
|
||||
using SegmentRequest = std::pair<cfdp::FileSize, cfdp::FileSize>;
|
||||
public:
|
||||
using SegmentRequest = std::pair<cfdp::FileSize, cfdp::FileSize>;
|
||||
|
||||
NakInfo(cfdp::FileSize startOfScope, cfdp::FileSize endOfScope);
|
||||
NakInfo(cfdp::FileSize startOfScope, cfdp::FileSize endOfScope);
|
||||
|
||||
void setSegmentRequests(SegmentRequest* segmentRequests, size_t* segmentRequestLen,
|
||||
size_t* maxSegmentRequestLen);
|
||||
void setSegmentRequests(SegmentRequest* segmentRequests, size_t* segmentRequestLen,
|
||||
size_t* maxSegmentRequestLen);
|
||||
|
||||
size_t getSerializedSize(bool fssLarge = false);
|
||||
size_t getSerializedSize(bool fssLarge = false);
|
||||
|
||||
cfdp::FileSize& getStartOfScope();
|
||||
cfdp::FileSize& getEndOfScope();
|
||||
cfdp::FileSize& getStartOfScope();
|
||||
cfdp::FileSize& getEndOfScope();
|
||||
|
||||
bool hasSegmentRequests() const;
|
||||
bool canHoldSegmentRequests() const;
|
||||
void setMaxSegmentRequestLen(size_t maxSize);
|
||||
bool getSegmentRequests(SegmentRequest** segmentRequestPtr, size_t* segmentRequestLen,
|
||||
size_t* maxSegmentRequestsLen);
|
||||
size_t getSegmentRequestsLen() const;
|
||||
size_t getSegmentRequestsMaxLen() const;
|
||||
bool hasSegmentRequests() const;
|
||||
bool canHoldSegmentRequests() const;
|
||||
void setMaxSegmentRequestLen(size_t maxSize);
|
||||
bool getSegmentRequests(SegmentRequest** segmentRequestPtr, size_t* segmentRequestLen,
|
||||
size_t* maxSegmentRequestsLen);
|
||||
size_t getSegmentRequestsLen() const;
|
||||
size_t getSegmentRequestsMaxLen() const;
|
||||
|
||||
//! This functions is more relevant for deserializers
|
||||
void setSegmentRequestLen(size_t readLen);
|
||||
//! This functions is more relevant for deserializers
|
||||
void setSegmentRequestLen(size_t readLen);
|
||||
|
||||
private:
|
||||
cfdp::FileSize startOfScope;
|
||||
cfdp::FileSize endOfScope;
|
||||
SegmentRequest* segmentRequests = nullptr;
|
||||
size_t segmentRequestsLen = 0;
|
||||
size_t maxSegmentRequestsLen = 0;
|
||||
private:
|
||||
cfdp::FileSize startOfScope;
|
||||
cfdp::FileSize endOfScope;
|
||||
SegmentRequest* segmentRequests = nullptr;
|
||||
size_t segmentRequestsLen = 0;
|
||||
size_t maxSegmentRequestsLen = 0;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_NAKINFO_H_ */
|
||||
|
@ -1,58 +1,56 @@
|
||||
#include "NakPduDeserializer.h"
|
||||
|
||||
NakPduDeserializer::NakPduDeserializer(const uint8_t *pduBuf, size_t maxSize, NakInfo &info):
|
||||
FileDirectiveDeserializer(pduBuf, maxSize), nakInfo(info) {
|
||||
}
|
||||
NakPduDeserializer::NakPduDeserializer(const uint8_t* pduBuf, size_t maxSize, NakInfo& info)
|
||||
: FileDirectiveDeserializer(pduBuf, maxSize), nakInfo(info) {}
|
||||
|
||||
ReturnValue_t NakPduDeserializer::parseData() {
|
||||
ReturnValue_t result = FileDirectiveDeserializer::parseData();
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
size_t currentIdx = FileDirectiveDeserializer::getHeaderSize();
|
||||
const uint8_t* buffer = rawPtr + currentIdx;
|
||||
size_t remSize = FileDirectiveDeserializer::getWholePduSize() - currentIdx;
|
||||
if (remSize < 1) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
result = nakInfo.getStartOfScope().deSerialize(&buffer, &remSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = nakInfo.getEndOfScope().deSerialize(&buffer, &remSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
nakInfo.setSegmentRequestLen(0);
|
||||
if(remSize > 0) {
|
||||
if(not nakInfo.canHoldSegmentRequests()) {
|
||||
return cfdp::NAK_CANT_PARSE_OPTIONS;
|
||||
}
|
||||
NakInfo::SegmentRequest* segReqs = nullptr;
|
||||
size_t maxSegReqs = 0;
|
||||
nakInfo.getSegmentRequests(&segReqs, nullptr, &maxSegReqs);
|
||||
if(segReqs != nullptr) {
|
||||
size_t idx = 0;
|
||||
while(remSize > 0) {
|
||||
if(idx == maxSegReqs) {
|
||||
return cfdp::NAK_CANT_PARSE_OPTIONS;
|
||||
}
|
||||
result = segReqs[idx].first.deSerialize(&buffer, &remSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = segReqs[idx].second.deSerialize(&buffer, &remSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
nakInfo.setSegmentRequestLen(idx);
|
||||
}
|
||||
}
|
||||
ReturnValue_t result = FileDirectiveDeserializer::parseData();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
size_t currentIdx = FileDirectiveDeserializer::getHeaderSize();
|
||||
const uint8_t* buffer = rawPtr + currentIdx;
|
||||
size_t remSize = FileDirectiveDeserializer::getWholePduSize() - currentIdx;
|
||||
if (remSize < 1) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
result =
|
||||
nakInfo.getStartOfScope().deSerialize(&buffer, &remSize, SerializeIF::Endianness::NETWORK);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = nakInfo.getEndOfScope().deSerialize(&buffer, &remSize, SerializeIF::Endianness::NETWORK);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
nakInfo.setSegmentRequestLen(0);
|
||||
if (remSize > 0) {
|
||||
if (not nakInfo.canHoldSegmentRequests()) {
|
||||
return cfdp::NAK_CANT_PARSE_OPTIONS;
|
||||
}
|
||||
NakInfo::SegmentRequest* segReqs = nullptr;
|
||||
size_t maxSegReqs = 0;
|
||||
nakInfo.getSegmentRequests(&segReqs, nullptr, &maxSegReqs);
|
||||
if (segReqs != nullptr) {
|
||||
size_t idx = 0;
|
||||
while (remSize > 0) {
|
||||
if (idx == maxSegReqs) {
|
||||
return cfdp::NAK_CANT_PARSE_OPTIONS;
|
||||
}
|
||||
result =
|
||||
segReqs[idx].first.deSerialize(&buffer, &remSize, SerializeIF::Endianness::NETWORK);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result =
|
||||
segReqs[idx].second.deSerialize(&buffer, &remSize, SerializeIF::Endianness::NETWORK);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
nakInfo.setSegmentRequestLen(idx);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -4,19 +4,18 @@
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveDeserializer.h"
|
||||
#include "fsfw/cfdp/pdu/NakInfo.h"
|
||||
|
||||
class NakPduDeserializer: public FileDirectiveDeserializer {
|
||||
public:
|
||||
NakPduDeserializer(const uint8_t* pduBuf, size_t maxSize, NakInfo& info);
|
||||
class NakPduDeserializer : public FileDirectiveDeserializer {
|
||||
public:
|
||||
NakPduDeserializer(const uint8_t* pduBuf, size_t maxSize, NakInfo& info);
|
||||
|
||||
/**
|
||||
* This needs to be called before accessing the PDU fields to avoid segmentation faults.
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t parseData() override;
|
||||
private:
|
||||
NakInfo& nakInfo;
|
||||
/**
|
||||
* This needs to be called before accessing the PDU fields to avoid segmentation faults.
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t parseData() override;
|
||||
|
||||
private:
|
||||
NakInfo& nakInfo;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_NAKPDUDESERIALIZER_H_ */
|
||||
|
@ -1,49 +1,47 @@
|
||||
#include "NakPduSerializer.h"
|
||||
|
||||
NakPduSerializer::NakPduSerializer(PduConfig& pduConf, NakInfo& nakInfo):
|
||||
FileDirectiveSerializer(pduConf, cfdp::FileDirectives::NAK, 0), nakInfo(nakInfo) {
|
||||
updateDirectiveFieldLen();
|
||||
NakPduSerializer::NakPduSerializer(PduConfig &pduConf, NakInfo &nakInfo)
|
||||
: FileDirectiveSerializer(pduConf, cfdp::FileDirectives::NAK, 0), nakInfo(nakInfo) {
|
||||
updateDirectiveFieldLen();
|
||||
}
|
||||
|
||||
void NakPduSerializer::updateDirectiveFieldLen() {
|
||||
this->setDirectiveDataFieldLen(nakInfo.getSerializedSize(getLargeFileFlag()));
|
||||
this->setDirectiveDataFieldLen(nakInfo.getSerializedSize(getLargeFileFlag()));
|
||||
}
|
||||
|
||||
size_t NakPduSerializer::getSerializedSize() const {
|
||||
return FileDirectiveSerializer::getWholePduSize();
|
||||
return FileDirectiveSerializer::getWholePduSize();
|
||||
}
|
||||
|
||||
ReturnValue_t NakPduSerializer::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result = FileDirectiveSerializer::serialize(buffer, size, maxSize,
|
||||
streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = nakInfo.getStartOfScope().serialize(buffer, size, maxSize, streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = nakInfo.getEndOfScope().serialize(buffer, size, maxSize, streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if(nakInfo.hasSegmentRequests()) {
|
||||
NakInfo::SegmentRequest *segmentRequests = nullptr;
|
||||
size_t segmentRequestLen = 0;
|
||||
nakInfo.getSegmentRequests(&segmentRequests, &segmentRequestLen, nullptr);
|
||||
for(size_t idx = 0; idx < segmentRequestLen; idx++) {
|
||||
result = segmentRequests[idx].first.serialize(buffer, size, maxSize,
|
||||
streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = segmentRequests[idx].second.serialize(buffer, size, maxSize,
|
||||
streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result =
|
||||
FileDirectiveSerializer::serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = nakInfo.getStartOfScope().serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = nakInfo.getEndOfScope().serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if (nakInfo.hasSegmentRequests()) {
|
||||
NakInfo::SegmentRequest *segmentRequests = nullptr;
|
||||
size_t segmentRequestLen = 0;
|
||||
nakInfo.getSegmentRequests(&segmentRequests, &segmentRequestLen, nullptr);
|
||||
for (size_t idx = 0; idx < segmentRequestLen; idx++) {
|
||||
result = segmentRequests[idx].first.serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = segmentRequests[idx].second.serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -1,41 +1,38 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_NAKPDUSERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_NAKPDUSERIALIZER_H_
|
||||
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveSerializer.h"
|
||||
#include "fsfw/cfdp/definitions.h"
|
||||
#include "fsfw/cfdp/FileSize.h"
|
||||
#include "NakInfo.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class NakPduSerializer: public FileDirectiveSerializer {
|
||||
public:
|
||||
#include "NakInfo.h"
|
||||
#include "fsfw/cfdp/FileSize.h"
|
||||
#include "fsfw/cfdp/definitions.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveSerializer.h"
|
||||
|
||||
/**
|
||||
*
|
||||
* @param PduConf
|
||||
* @param startOfScope
|
||||
* @param endOfScope
|
||||
* @param [in] segmentRequests Pointer to the start of a list of segment requests
|
||||
* @param segmentRequestLen Length of the segment request list to be serialized
|
||||
*/
|
||||
NakPduSerializer(PduConfig& PduConf, NakInfo& nakInfo);
|
||||
class NakPduSerializer : public FileDirectiveSerializer {
|
||||
public:
|
||||
/**
|
||||
*
|
||||
* @param PduConf
|
||||
* @param startOfScope
|
||||
* @param endOfScope
|
||||
* @param [in] segmentRequests Pointer to the start of a list of segment requests
|
||||
* @param segmentRequestLen Length of the segment request list to be serialized
|
||||
*/
|
||||
NakPduSerializer(PduConfig& PduConf, NakInfo& nakInfo);
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
/**
|
||||
* If you change the info struct, you might need to update the directive field length
|
||||
* manually
|
||||
*/
|
||||
void updateDirectiveFieldLen();
|
||||
private:
|
||||
NakInfo& nakInfo;
|
||||
/**
|
||||
* If you change the info struct, you might need to update the directive field length
|
||||
* manually
|
||||
*/
|
||||
void updateDirectiveFieldLen();
|
||||
|
||||
private:
|
||||
NakInfo& nakInfo;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_NAKPDUSERIALIZER_H_ */
|
||||
|
@ -1,8 +1,12 @@
|
||||
#include "PduConfig.h"
|
||||
|
||||
PduConfig::PduConfig(cfdp::TransmissionModes mode, cfdp::TransactionSeqNum seqNum,
|
||||
cfdp::EntityId sourceId, cfdp::EntityId destId, bool crcFlag,
|
||||
bool largeFile, cfdp::Direction direction):
|
||||
mode(mode), seqNum(seqNum), sourceId(sourceId), destId(destId),
|
||||
crcFlag(crcFlag), largeFile(largeFile), direction(direction) {
|
||||
}
|
||||
cfdp::EntityId sourceId, cfdp::EntityId destId, bool crcFlag, bool largeFile,
|
||||
cfdp::Direction direction)
|
||||
: mode(mode),
|
||||
seqNum(seqNum),
|
||||
sourceId(sourceId),
|
||||
destId(destId),
|
||||
crcFlag(crcFlag),
|
||||
largeFile(largeFile),
|
||||
direction(direction) {}
|
||||
|
@ -5,32 +5,32 @@
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
struct EntityId: public VarLenField {
|
||||
public:
|
||||
EntityId(): VarLenField() {}
|
||||
EntityId(cfdp::WidthInBytes width, size_t entityId): VarLenField(width, entityId) {}
|
||||
struct EntityId : public VarLenField {
|
||||
public:
|
||||
EntityId() : VarLenField() {}
|
||||
EntityId(cfdp::WidthInBytes width, size_t entityId) : VarLenField(width, entityId) {}
|
||||
};
|
||||
|
||||
struct TransactionSeqNum: public VarLenField {
|
||||
public:
|
||||
TransactionSeqNum(): VarLenField() {}
|
||||
TransactionSeqNum(cfdp::WidthInBytes width, size_t seqNum): VarLenField(width, seqNum) {}
|
||||
struct TransactionSeqNum : public VarLenField {
|
||||
public:
|
||||
TransactionSeqNum() : VarLenField() {}
|
||||
TransactionSeqNum(cfdp::WidthInBytes width, size_t seqNum) : VarLenField(width, seqNum) {}
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace cfdp
|
||||
|
||||
class PduConfig {
|
||||
public:
|
||||
PduConfig(cfdp::TransmissionModes mode, cfdp::TransactionSeqNum seqNum,
|
||||
cfdp::EntityId sourceId, cfdp::EntityId destId, bool crcFlag = false,
|
||||
bool largeFile = false, cfdp::Direction direction = cfdp::Direction::TOWARDS_RECEIVER);
|
||||
cfdp::TransmissionModes mode;
|
||||
cfdp::TransactionSeqNum seqNum;
|
||||
cfdp::EntityId sourceId;
|
||||
cfdp::EntityId destId;
|
||||
bool crcFlag;
|
||||
bool largeFile;
|
||||
cfdp::Direction direction;
|
||||
public:
|
||||
PduConfig(cfdp::TransmissionModes mode, cfdp::TransactionSeqNum seqNum, cfdp::EntityId sourceId,
|
||||
cfdp::EntityId destId, bool crcFlag = false, bool largeFile = false,
|
||||
cfdp::Direction direction = cfdp::Direction::TOWARDS_RECEIVER);
|
||||
cfdp::TransmissionModes mode;
|
||||
cfdp::TransactionSeqNum seqNum;
|
||||
cfdp::EntityId sourceId;
|
||||
cfdp::EntityId destId;
|
||||
bool crcFlag;
|
||||
bool largeFile;
|
||||
cfdp::Direction direction;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_PDUCONFIG_H_ */
|
||||
|
@ -1,37 +1,37 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_PDUHEADERIF_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_PDUHEADERIF_H_
|
||||
|
||||
#include "PduConfig.h"
|
||||
#include "../definitions.h"
|
||||
#include <cstddef>
|
||||
|
||||
#include "../definitions.h"
|
||||
#include "PduConfig.h"
|
||||
|
||||
/**
|
||||
* @brief Generic interface to access all fields of a PDU header
|
||||
* @details
|
||||
* See CCSDS 727.0-B-5 pp.75 for more information about these fields
|
||||
*/
|
||||
class PduHeaderIF {
|
||||
public:
|
||||
virtual~ PduHeaderIF() {};
|
||||
public:
|
||||
virtual ~PduHeaderIF(){};
|
||||
|
||||
virtual size_t getWholePduSize() const = 0;
|
||||
virtual size_t getPduDataFieldLen() const = 0;
|
||||
virtual cfdp::PduType getPduType() const = 0;
|
||||
virtual cfdp::Direction getDirection() const = 0;
|
||||
virtual cfdp::TransmissionModes getTransmissionMode() const = 0;
|
||||
virtual bool getCrcFlag() const = 0;
|
||||
virtual bool getLargeFileFlag() const = 0;
|
||||
virtual cfdp::SegmentationControl getSegmentationControl() const = 0;
|
||||
virtual cfdp::WidthInBytes getLenEntityIds() const = 0;
|
||||
virtual cfdp::WidthInBytes getLenSeqNum() const = 0;
|
||||
virtual cfdp::SegmentMetadataFlag getSegmentMetadataFlag() const = 0;
|
||||
virtual bool hasSegmentMetadataFlag() const = 0;
|
||||
virtual void getSourceId(cfdp::EntityId& sourceId) const = 0;
|
||||
virtual void getDestId(cfdp::EntityId& destId) const = 0;
|
||||
virtual void getTransactionSeqNum(cfdp::TransactionSeqNum& seqNum) const = 0;
|
||||
private:
|
||||
virtual size_t getWholePduSize() const = 0;
|
||||
virtual size_t getPduDataFieldLen() const = 0;
|
||||
virtual cfdp::PduType getPduType() const = 0;
|
||||
virtual cfdp::Direction getDirection() const = 0;
|
||||
virtual cfdp::TransmissionModes getTransmissionMode() const = 0;
|
||||
virtual bool getCrcFlag() const = 0;
|
||||
virtual bool getLargeFileFlag() const = 0;
|
||||
virtual cfdp::SegmentationControl getSegmentationControl() const = 0;
|
||||
virtual cfdp::WidthInBytes getLenEntityIds() const = 0;
|
||||
virtual cfdp::WidthInBytes getLenSeqNum() const = 0;
|
||||
virtual cfdp::SegmentMetadataFlag getSegmentMetadataFlag() const = 0;
|
||||
virtual bool hasSegmentMetadataFlag() const = 0;
|
||||
virtual void getSourceId(cfdp::EntityId& sourceId) const = 0;
|
||||
virtual void getDestId(cfdp::EntityId& destId) const = 0;
|
||||
virtual void getTransactionSeqNum(cfdp::TransactionSeqNum& seqNum) const = 0;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_PDUHEADERIF_H_ */
|
||||
|
@ -1,22 +1,21 @@
|
||||
#include "PromptPduDeserializer.h"
|
||||
|
||||
PromptPduDeserializer::PromptPduDeserializer(const uint8_t *pduBuf, size_t maxSize):
|
||||
FileDirectiveDeserializer(pduBuf, maxSize) {
|
||||
}
|
||||
PromptPduDeserializer::PromptPduDeserializer(const uint8_t *pduBuf, size_t maxSize)
|
||||
: FileDirectiveDeserializer(pduBuf, maxSize) {}
|
||||
|
||||
cfdp::PromptResponseRequired PromptPduDeserializer::getPromptResponseRequired() const {
|
||||
return responseRequired;
|
||||
return responseRequired;
|
||||
}
|
||||
|
||||
ReturnValue_t PromptPduDeserializer::parseData() {
|
||||
ReturnValue_t result = FileDirectiveDeserializer::parseData();
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
size_t currentIdx = FileDirectiveDeserializer::getHeaderSize();
|
||||
if (FileDirectiveDeserializer::getWholePduSize() - currentIdx < 1) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
responseRequired = static_cast<cfdp::PromptResponseRequired>((rawPtr[currentIdx] >> 7) & 0x01);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
ReturnValue_t result = FileDirectiveDeserializer::parseData();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
size_t currentIdx = FileDirectiveDeserializer::getHeaderSize();
|
||||
if (FileDirectiveDeserializer::getWholePduSize() - currentIdx < 1) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
responseRequired = static_cast<cfdp::PromptResponseRequired>((rawPtr[currentIdx] >> 7) & 0x01);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
@ -3,16 +3,15 @@
|
||||
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveDeserializer.h"
|
||||
|
||||
class PromptPduDeserializer: public FileDirectiveDeserializer {
|
||||
public:
|
||||
PromptPduDeserializer(const uint8_t *pduBuf, size_t maxSize);
|
||||
class PromptPduDeserializer : public FileDirectiveDeserializer {
|
||||
public:
|
||||
PromptPduDeserializer(const uint8_t *pduBuf, size_t maxSize);
|
||||
|
||||
cfdp::PromptResponseRequired getPromptResponseRequired() const;
|
||||
ReturnValue_t parseData() override;
|
||||
private:
|
||||
cfdp::PromptResponseRequired responseRequired = cfdp::PromptResponseRequired::PROMPT_NAK;
|
||||
cfdp::PromptResponseRequired getPromptResponseRequired() const;
|
||||
ReturnValue_t parseData() override;
|
||||
|
||||
private:
|
||||
cfdp::PromptResponseRequired responseRequired = cfdp::PromptResponseRequired::PROMPT_NAK;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_PROMPTPDUDESERIALIZER_H_ */
|
||||
|
@ -1,27 +1,26 @@
|
||||
#include "PromptPduSerializer.h"
|
||||
|
||||
PromptPduSerializer::PromptPduSerializer(PduConfig &conf,
|
||||
cfdp::PromptResponseRequired responseRequired):
|
||||
FileDirectiveSerializer(conf, cfdp::FileDirectives::PROMPT, 1),
|
||||
responseRequired(responseRequired) {
|
||||
}
|
||||
cfdp::PromptResponseRequired responseRequired)
|
||||
: FileDirectiveSerializer(conf, cfdp::FileDirectives::PROMPT, 1),
|
||||
responseRequired(responseRequired) {}
|
||||
|
||||
size_t PromptPduSerializer::getSerializedSize() const {
|
||||
return FileDirectiveSerializer::getWholePduSize();
|
||||
return FileDirectiveSerializer::getWholePduSize();
|
||||
}
|
||||
|
||||
ReturnValue_t PromptPduSerializer::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result = FileDirectiveSerializer::serialize(buffer, size, maxSize,
|
||||
streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if(*size + 1 > maxSize) {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = this->responseRequired << 7;
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result =
|
||||
FileDirectiveSerializer::serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if (*size + 1 > maxSize) {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = this->responseRequired << 7;
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
return result;
|
||||
}
|
||||
|
@ -3,16 +3,17 @@
|
||||
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveSerializer.h"
|
||||
|
||||
class PromptPduSerializer: public FileDirectiveSerializer {
|
||||
public:
|
||||
PromptPduSerializer(PduConfig& conf, cfdp::PromptResponseRequired responseRequired);
|
||||
class PromptPduSerializer : public FileDirectiveSerializer {
|
||||
public:
|
||||
PromptPduSerializer(PduConfig& conf, cfdp::PromptResponseRequired responseRequired);
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
private:
|
||||
cfdp::PromptResponseRequired responseRequired;
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
private:
|
||||
cfdp::PromptResponseRequired responseRequired;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_PROMPTPDUSERIALIZER_H_ */
|
||||
|
@ -1,127 +1,120 @@
|
||||
#include "VarLenField.h"
|
||||
#include "fsfw/FSFW.h"
|
||||
#include "fsfw/serviceinterface.h"
|
||||
#include "fsfw/serialize/SerializeAdapter.h"
|
||||
|
||||
cfdp::VarLenField::VarLenField(cfdp::WidthInBytes width, size_t value): VarLenField() {
|
||||
ReturnValue_t result = this->setValue(width, value);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
#include "fsfw/FSFW.h"
|
||||
#include "fsfw/serialize/SerializeAdapter.h"
|
||||
#include "fsfw/serviceinterface.h"
|
||||
|
||||
cfdp::VarLenField::VarLenField(cfdp::WidthInBytes width, size_t value) : VarLenField() {
|
||||
ReturnValue_t result = this->setValue(width, value);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
#if FSFW_DISABLE_PRINTOUT == 0
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "cfdp::VarLenField: Setting value failed" << std::endl;
|
||||
sif::warning << "cfdp::VarLenField: Setting value failed" << std::endl;
|
||||
#else
|
||||
sif::printWarning("cfdp::VarLenField: Setting value failed\n");
|
||||
sif::printWarning("cfdp::VarLenField: Setting value failed\n");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cfdp::VarLenField::VarLenField(): width(cfdp::WidthInBytes::ONE_BYTE) {
|
||||
value.oneByte = 0;
|
||||
}
|
||||
cfdp::VarLenField::VarLenField() : width(cfdp::WidthInBytes::ONE_BYTE) { value.oneByte = 0; }
|
||||
|
||||
cfdp::WidthInBytes cfdp::VarLenField::getWidth() const {
|
||||
return width;
|
||||
}
|
||||
cfdp::WidthInBytes cfdp::VarLenField::getWidth() const { return width; }
|
||||
|
||||
ReturnValue_t cfdp::VarLenField::setValue(cfdp::WidthInBytes widthInBytes, size_t value) {
|
||||
switch(widthInBytes) {
|
||||
case(cfdp::WidthInBytes::ONE_BYTE): {
|
||||
if(value > UINT8_MAX) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
this->value.oneByte = value;
|
||||
break;
|
||||
switch (widthInBytes) {
|
||||
case (cfdp::WidthInBytes::ONE_BYTE): {
|
||||
if (value > UINT8_MAX) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
this->value.oneByte = value;
|
||||
break;
|
||||
}
|
||||
case(cfdp::WidthInBytes::TWO_BYTES): {
|
||||
if(value > UINT16_MAX) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
this->value.twoBytes = value;
|
||||
break;
|
||||
case (cfdp::WidthInBytes::TWO_BYTES): {
|
||||
if (value > UINT16_MAX) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
this->value.twoBytes = value;
|
||||
break;
|
||||
}
|
||||
case(cfdp::WidthInBytes::FOUR_BYTES): {
|
||||
if(value > UINT32_MAX) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
this->value.fourBytes = value;
|
||||
break;
|
||||
case (cfdp::WidthInBytes::FOUR_BYTES): {
|
||||
if (value > UINT32_MAX) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
this->value.fourBytes = value;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this->width = widthInBytes;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
this->width = widthInBytes;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
size_t cfdp::VarLenField::getValue() const {
|
||||
switch(width) {
|
||||
case(cfdp::WidthInBytes::ONE_BYTE): {
|
||||
return value.oneByte;
|
||||
switch (width) {
|
||||
case (cfdp::WidthInBytes::ONE_BYTE): {
|
||||
return value.oneByte;
|
||||
}
|
||||
case(cfdp::WidthInBytes::TWO_BYTES): {
|
||||
return value.twoBytes;
|
||||
case (cfdp::WidthInBytes::TWO_BYTES): {
|
||||
return value.twoBytes;
|
||||
}
|
||||
case(cfdp::WidthInBytes::FOUR_BYTES): {
|
||||
return value.fourBytes;
|
||||
case (cfdp::WidthInBytes::FOUR_BYTES): {
|
||||
return value.fourBytes;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ReturnValue_t cfdp::VarLenField::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
switch(width) {
|
||||
case(cfdp::WidthInBytes::ONE_BYTE): {
|
||||
if (*size + 1 > maxSize) {
|
||||
return BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = value.oneByte;
|
||||
*size += 1;
|
||||
*buffer += 1;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
Endianness streamEndianness) const {
|
||||
switch (width) {
|
||||
case (cfdp::WidthInBytes::ONE_BYTE): {
|
||||
if (*size + 1 > maxSize) {
|
||||
return BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = value.oneByte;
|
||||
*size += 1;
|
||||
*buffer += 1;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
case(cfdp::WidthInBytes::TWO_BYTES): {
|
||||
return SerializeAdapter::serialize(&value.twoBytes, buffer, size, maxSize,
|
||||
streamEndianness);
|
||||
case (cfdp::WidthInBytes::TWO_BYTES): {
|
||||
return SerializeAdapter::serialize(&value.twoBytes, buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
case(cfdp::WidthInBytes::FOUR_BYTES): {
|
||||
return SerializeAdapter::serialize(&value.fourBytes, buffer, size, maxSize,
|
||||
streamEndianness);
|
||||
case (cfdp::WidthInBytes::FOUR_BYTES): {
|
||||
return SerializeAdapter::serialize(&value.fourBytes, buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
default: {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t cfdp::VarLenField::getSerializedSize() const {
|
||||
return width;
|
||||
}
|
||||
size_t cfdp::VarLenField::getSerializedSize() const { return width; }
|
||||
|
||||
ReturnValue_t cfdp::VarLenField::deSerialize(cfdp::WidthInBytes width, const uint8_t **buffer,
|
||||
size_t *size, Endianness streamEndianness) {
|
||||
this->width = width;
|
||||
return deSerialize(buffer, size, streamEndianness);
|
||||
size_t *size, Endianness streamEndianness) {
|
||||
this->width = width;
|
||||
return deSerialize(buffer, size, streamEndianness);
|
||||
}
|
||||
|
||||
ReturnValue_t cfdp::VarLenField::deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) {
|
||||
switch(width) {
|
||||
case(cfdp::WidthInBytes::ONE_BYTE): {
|
||||
value.oneByte = **buffer;
|
||||
*size += 1;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
Endianness streamEndianness) {
|
||||
switch (width) {
|
||||
case (cfdp::WidthInBytes::ONE_BYTE): {
|
||||
value.oneByte = **buffer;
|
||||
*size += 1;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
case(cfdp::WidthInBytes::TWO_BYTES): {
|
||||
return SerializeAdapter::deSerialize(&value.twoBytes, buffer, size, streamEndianness);
|
||||
case (cfdp::WidthInBytes::TWO_BYTES): {
|
||||
return SerializeAdapter::deSerialize(&value.twoBytes, buffer, size, streamEndianness);
|
||||
}
|
||||
case(cfdp::WidthInBytes::FOUR_BYTES): {
|
||||
return SerializeAdapter::deSerialize(&value.fourBytes, buffer, size, streamEndianness);
|
||||
case (cfdp::WidthInBytes::FOUR_BYTES): {
|
||||
return SerializeAdapter::deSerialize(&value.fourBytes, buffer, size, streamEndianness);
|
||||
}
|
||||
default: {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,45 +1,47 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_VARLENFIELD_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_VARLENFIELD_H_
|
||||
|
||||
#include "../definitions.h"
|
||||
#include "fsfw/serialize/SerializeIF.h"
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#include "../definitions.h"
|
||||
#include "fsfw/serialize/SerializeIF.h"
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
class VarLenField: public SerializeIF {
|
||||
public:
|
||||
union LengthFieldLen {
|
||||
uint8_t oneByte;
|
||||
uint16_t twoBytes;
|
||||
uint32_t fourBytes;
|
||||
uint64_t eightBytes;
|
||||
};
|
||||
class VarLenField : public SerializeIF {
|
||||
public:
|
||||
union LengthFieldLen {
|
||||
uint8_t oneByte;
|
||||
uint16_t twoBytes;
|
||||
uint32_t fourBytes;
|
||||
uint64_t eightBytes;
|
||||
};
|
||||
|
||||
VarLenField();
|
||||
VarLenField(cfdp::WidthInBytes width, size_t value);
|
||||
VarLenField();
|
||||
VarLenField(cfdp::WidthInBytes width, size_t value);
|
||||
|
||||
ReturnValue_t setValue(cfdp::WidthInBytes, size_t value);
|
||||
ReturnValue_t setValue(cfdp::WidthInBytes, size_t value);
|
||||
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
ReturnValue_t deSerialize(cfdp::WidthInBytes width, const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness);
|
||||
ReturnValue_t deSerialize(cfdp::WidthInBytes width, const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness);
|
||||
|
||||
cfdp::WidthInBytes getWidth() const;
|
||||
size_t getValue() const;
|
||||
private:
|
||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override;
|
||||
cfdp::WidthInBytes getWidth() const;
|
||||
size_t getValue() const;
|
||||
|
||||
cfdp::WidthInBytes width;
|
||||
LengthFieldLen value;
|
||||
private:
|
||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
cfdp::WidthInBytes width;
|
||||
LengthFieldLen value;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace cfdp
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_VARLENFIELD_H_ */
|
||||
|
@ -1,68 +1,59 @@
|
||||
#include "EntityIdTlv.h"
|
||||
|
||||
#include <array>
|
||||
|
||||
EntityIdTlv::EntityIdTlv(cfdp::EntityId& entityId): entityId(entityId) {
|
||||
}
|
||||
EntityIdTlv::EntityIdTlv(cfdp::EntityId &entityId) : entityId(entityId) {}
|
||||
|
||||
EntityIdTlv::~EntityIdTlv() {
|
||||
}
|
||||
EntityIdTlv::~EntityIdTlv() {}
|
||||
|
||||
ReturnValue_t EntityIdTlv::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
if(maxSize < this->getSerializedSize()) {
|
||||
return BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = cfdp::TlvTypes::ENTITY_ID;
|
||||
*size += 1;
|
||||
*buffer += 1;
|
||||
size_t serLen = entityId.getSerializedSize();
|
||||
**buffer = serLen;
|
||||
*size += 1;
|
||||
*buffer += 1;
|
||||
return entityId.serialize(buffer, size, maxSize, streamEndianness);
|
||||
Endianness streamEndianness) const {
|
||||
if (maxSize < this->getSerializedSize()) {
|
||||
return BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = cfdp::TlvTypes::ENTITY_ID;
|
||||
*size += 1;
|
||||
*buffer += 1;
|
||||
size_t serLen = entityId.getSerializedSize();
|
||||
**buffer = serLen;
|
||||
*size += 1;
|
||||
*buffer += 1;
|
||||
return entityId.serialize(buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
|
||||
size_t EntityIdTlv::getSerializedSize() const {
|
||||
return getLengthField() + 1;
|
||||
}
|
||||
size_t EntityIdTlv::getSerializedSize() const { return getLengthField() + 1; }
|
||||
|
||||
ReturnValue_t EntityIdTlv::deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) {
|
||||
if(*size < 3) {
|
||||
return STREAM_TOO_SHORT;
|
||||
}
|
||||
cfdp::TlvTypes type = static_cast<cfdp::TlvTypes>(**buffer);
|
||||
if(type != cfdp::TlvTypes::ENTITY_ID) {
|
||||
return cfdp::INVALID_TLV_TYPE;
|
||||
}
|
||||
*buffer += 1;
|
||||
*size -= 1;
|
||||
Endianness streamEndianness) {
|
||||
if (*size < 3) {
|
||||
return STREAM_TOO_SHORT;
|
||||
}
|
||||
cfdp::TlvTypes type = static_cast<cfdp::TlvTypes>(**buffer);
|
||||
if (type != cfdp::TlvTypes::ENTITY_ID) {
|
||||
return cfdp::INVALID_TLV_TYPE;
|
||||
}
|
||||
*buffer += 1;
|
||||
*size -= 1;
|
||||
|
||||
cfdp::WidthInBytes width = static_cast<cfdp::WidthInBytes>(**buffer);
|
||||
if (*size < static_cast<size_t>(1 + width)) {
|
||||
return STREAM_TOO_SHORT;
|
||||
}
|
||||
*buffer += 1;
|
||||
*size -= 1;
|
||||
cfdp::WidthInBytes width = static_cast<cfdp::WidthInBytes>(**buffer);
|
||||
if (*size < static_cast<size_t>(1 + width)) {
|
||||
return STREAM_TOO_SHORT;
|
||||
}
|
||||
*buffer += 1;
|
||||
*size -= 1;
|
||||
|
||||
return entityId.deSerialize(width, buffer, size, streamEndianness);
|
||||
return entityId.deSerialize(width, buffer, size, streamEndianness);
|
||||
}
|
||||
|
||||
ReturnValue_t EntityIdTlv::deSerialize(cfdp::Tlv &tlv, Endianness endianness) {
|
||||
const uint8_t* ptr = tlv.getValue() + 2;
|
||||
size_t remSz = tlv.getSerializedSize() - 2;
|
||||
cfdp::WidthInBytes width = static_cast<cfdp::WidthInBytes>(remSz);
|
||||
return entityId.deSerialize(width, &ptr, &remSz, endianness);
|
||||
const uint8_t *ptr = tlv.getValue() + 2;
|
||||
size_t remSz = tlv.getSerializedSize() - 2;
|
||||
cfdp::WidthInBytes width = static_cast<cfdp::WidthInBytes>(remSz);
|
||||
return entityId.deSerialize(width, &ptr, &remSz, endianness);
|
||||
}
|
||||
|
||||
uint8_t EntityIdTlv::getLengthField() const {
|
||||
return 1 + entityId.getSerializedSize();
|
||||
}
|
||||
uint8_t EntityIdTlv::getLengthField() const { return 1 + entityId.getSerializedSize(); }
|
||||
|
||||
cfdp::TlvTypes EntityIdTlv::getType() const {
|
||||
return cfdp::TlvTypes::ENTITY_ID;
|
||||
}
|
||||
cfdp::TlvTypes EntityIdTlv::getType() const { return cfdp::TlvTypes::ENTITY_ID; }
|
||||
|
||||
cfdp::EntityId& EntityIdTlv::getEntityId() {
|
||||
return entityId;
|
||||
}
|
||||
cfdp::EntityId &EntityIdTlv::getEntityId() { return entityId; }
|
||||
|
@ -1,39 +1,38 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_ENTITYIDTLV_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_ENTITYIDTLV_H_
|
||||
|
||||
#include "fsfw/cfdp/tlv/Tlv.h"
|
||||
#include "fsfw/cfdp/pdu/PduConfig.h"
|
||||
#include "TlvIF.h"
|
||||
#include "fsfw/cfdp/pdu/PduConfig.h"
|
||||
#include "fsfw/cfdp/tlv/Tlv.h"
|
||||
|
||||
class EntityIdTlv: public TlvIF {
|
||||
public:
|
||||
EntityIdTlv(cfdp::EntityId& entityId);
|
||||
virtual~ EntityIdTlv();
|
||||
class EntityIdTlv : public TlvIF {
|
||||
public:
|
||||
EntityIdTlv(cfdp::EntityId& entityId);
|
||||
virtual ~EntityIdTlv();
|
||||
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size,
|
||||
size_t maxSize, Endianness streamEndianness) const override;
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
/**
|
||||
* Deserialize an entity ID from a raw TLV object
|
||||
* @param tlv
|
||||
* @param endianness
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t deSerialize(cfdp::Tlv& tlv, Endianness endianness);
|
||||
/**
|
||||
* Deserialize an entity ID from a raw TLV object
|
||||
* @param tlv
|
||||
* @param endianness
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t deSerialize(cfdp::Tlv& tlv, Endianness endianness);
|
||||
|
||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override;
|
||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
uint8_t getLengthField() const override;
|
||||
cfdp::TlvTypes getType() const override;
|
||||
uint8_t getLengthField() const override;
|
||||
cfdp::TlvTypes getType() const override;
|
||||
|
||||
cfdp::EntityId& getEntityId();
|
||||
private:
|
||||
cfdp::EntityId& entityId;
|
||||
cfdp::EntityId& getEntityId();
|
||||
|
||||
private:
|
||||
cfdp::EntityId& entityId;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_ENTITYIDTLV_H_ */
|
||||
|
@ -1,64 +1,54 @@
|
||||
#include "FaultHandlerOverrideTlv.h"
|
||||
|
||||
FaultHandlerOverrideTlv::FaultHandlerOverrideTlv(cfdp::ConditionCode conditionCode,
|
||||
cfdp::FaultHandlerCode handlerCode):
|
||||
conditionCode(conditionCode), handlerCode(handlerCode) {
|
||||
}
|
||||
cfdp::FaultHandlerCode handlerCode)
|
||||
: conditionCode(conditionCode), handlerCode(handlerCode) {}
|
||||
|
||||
FaultHandlerOverrideTlv::FaultHandlerOverrideTlv() {
|
||||
}
|
||||
|
||||
uint8_t FaultHandlerOverrideTlv::getLengthField() const {
|
||||
return 1;
|
||||
}
|
||||
FaultHandlerOverrideTlv::FaultHandlerOverrideTlv() {}
|
||||
|
||||
uint8_t FaultHandlerOverrideTlv::getLengthField() const { return 1; }
|
||||
|
||||
ReturnValue_t FaultHandlerOverrideTlv::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
if((maxSize < 3) or ((*size + 3) > maxSize)) {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = getType();
|
||||
*size += 1;
|
||||
*buffer += 1;
|
||||
**buffer = getLengthField();
|
||||
*size += 1;
|
||||
*buffer += 1;
|
||||
**buffer = this->conditionCode << 4 | this->handlerCode;
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
Endianness streamEndianness) const {
|
||||
if ((maxSize < 3) or ((*size + 3) > maxSize)) {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = getType();
|
||||
*size += 1;
|
||||
*buffer += 1;
|
||||
**buffer = getLengthField();
|
||||
*size += 1;
|
||||
*buffer += 1;
|
||||
**buffer = this->conditionCode << 4 | this->handlerCode;
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
size_t FaultHandlerOverrideTlv::getSerializedSize() const {
|
||||
return getLengthField() + 2;
|
||||
}
|
||||
size_t FaultHandlerOverrideTlv::getSerializedSize() const { return getLengthField() + 2; }
|
||||
|
||||
ReturnValue_t FaultHandlerOverrideTlv::deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) {
|
||||
if(*size < 3) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
auto detectedType = static_cast<cfdp::TlvTypes>(**buffer);
|
||||
if(detectedType != cfdp::TlvTypes::FAULT_HANDLER) {
|
||||
return cfdp::INVALID_TLV_TYPE;
|
||||
}
|
||||
*buffer += 1;
|
||||
*size -= 1;
|
||||
size_t detectedSize = **buffer;
|
||||
if(detectedSize != getLengthField()) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
this->conditionCode = static_cast<cfdp::ConditionCode>((**buffer >> 4) & 0x0f);
|
||||
this->handlerCode = static_cast<cfdp::FaultHandlerCode>(**buffer & 0x0f);
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
Endianness streamEndianness) {
|
||||
if (*size < 3) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
auto detectedType = static_cast<cfdp::TlvTypes>(**buffer);
|
||||
if (detectedType != cfdp::TlvTypes::FAULT_HANDLER) {
|
||||
return cfdp::INVALID_TLV_TYPE;
|
||||
}
|
||||
*buffer += 1;
|
||||
*size -= 1;
|
||||
size_t detectedSize = **buffer;
|
||||
if (detectedSize != getLengthField()) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
this->conditionCode = static_cast<cfdp::ConditionCode>((**buffer >> 4) & 0x0f);
|
||||
this->handlerCode = static_cast<cfdp::FaultHandlerCode>(**buffer & 0x0f);
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
|
||||
cfdp::TlvTypes FaultHandlerOverrideTlv::getType() const {
|
||||
return cfdp::TlvTypes::FAULT_HANDLER;
|
||||
}
|
||||
cfdp::TlvTypes FaultHandlerOverrideTlv::getType() const { return cfdp::TlvTypes::FAULT_HANDLER; }
|
||||
|
@ -6,34 +6,33 @@
|
||||
namespace cfdp {
|
||||
|
||||
enum FaultHandlerCode {
|
||||
RESERVED = 0b0000,
|
||||
NOTICE_OF_CANCELLATION = 0b0001,
|
||||
NOTICE_OF_SUSPENSION = 0b0010,
|
||||
IGNORE_ERROR = 0b0011,
|
||||
ABANDON_TRANSACTION = 0b0100
|
||||
RESERVED = 0b0000,
|
||||
NOTICE_OF_CANCELLATION = 0b0001,
|
||||
NOTICE_OF_SUSPENSION = 0b0010,
|
||||
IGNORE_ERROR = 0b0011,
|
||||
ABANDON_TRANSACTION = 0b0100
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
class FaultHandlerOverrideTlv: public TlvIF {
|
||||
public:
|
||||
class FaultHandlerOverrideTlv : public TlvIF {
|
||||
public:
|
||||
FaultHandlerOverrideTlv();
|
||||
FaultHandlerOverrideTlv(cfdp::ConditionCode conditionCode, cfdp::FaultHandlerCode handlerCode);
|
||||
|
||||
FaultHandlerOverrideTlv();
|
||||
FaultHandlerOverrideTlv(cfdp::ConditionCode conditionCode, cfdp::FaultHandlerCode handlerCode);
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size,
|
||||
size_t maxSize, Endianness streamEndianness) const override;
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override;
|
||||
uint8_t getLengthField() const override;
|
||||
cfdp::TlvTypes getType() const override;
|
||||
|
||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override;
|
||||
uint8_t getLengthField() const override;
|
||||
cfdp::TlvTypes getType() const override;
|
||||
|
||||
private:
|
||||
cfdp::ConditionCode conditionCode = cfdp::ConditionCode::NO_CONDITION_FIELD;
|
||||
cfdp::FaultHandlerCode handlerCode = cfdp::FaultHandlerCode::RESERVED;
|
||||
private:
|
||||
cfdp::ConditionCode conditionCode = cfdp::ConditionCode::NO_CONDITION_FIELD;
|
||||
cfdp::FaultHandlerCode handlerCode = cfdp::FaultHandlerCode::RESERVED;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_TLV_FAULTHANDLEROVERRIDETLV_H_ */
|
||||
|
@ -1,83 +1,79 @@
|
||||
#include "fsfw/cfdp/tlv/FilestoreRequestTlv.h"
|
||||
|
||||
#include "fsfw/FSFW.h"
|
||||
|
||||
FilestoreRequestTlv::FilestoreRequestTlv(cfdp::FilestoreActionCode actionCode,
|
||||
cfdp::Lv& firstFileName): FilestoreTlvBase(actionCode, firstFileName) {
|
||||
}
|
||||
cfdp::Lv &firstFileName)
|
||||
: FilestoreTlvBase(actionCode, firstFileName) {}
|
||||
|
||||
FilestoreRequestTlv::FilestoreRequestTlv(cfdp::Lv &firstFileName):
|
||||
FilestoreTlvBase(cfdp::FilestoreActionCode::INVALID, firstFileName) {
|
||||
}
|
||||
FilestoreRequestTlv::FilestoreRequestTlv(cfdp::Lv &firstFileName)
|
||||
: FilestoreTlvBase(cfdp::FilestoreActionCode::INVALID, firstFileName) {}
|
||||
|
||||
void FilestoreRequestTlv::setSecondFileName(cfdp::Lv *secondFileName) {
|
||||
this->secondFileName = secondFileName;
|
||||
this->secondFileName = secondFileName;
|
||||
}
|
||||
|
||||
ReturnValue_t FilestoreRequestTlv::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result = commonSerialize(buffer, size, maxSize, streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result = commonSerialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = firstFileName.serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if (requiresSecondFileName()) {
|
||||
if (secondFileName == nullptr) {
|
||||
secondFileNameMissing();
|
||||
return cfdp::FILESTORE_REQUIRES_SECOND_FILE;
|
||||
}
|
||||
result = firstFileName.serialize(buffer, size, maxSize,
|
||||
streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if(requiresSecondFileName()) {
|
||||
if(secondFileName == nullptr) {
|
||||
secondFileNameMissing();
|
||||
return cfdp::FILESTORE_REQUIRES_SECOND_FILE;
|
||||
}
|
||||
secondFileName->serialize(buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
secondFileName->serialize(buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t FilestoreRequestTlv::deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) {
|
||||
ReturnValue_t result = commonDeserialize(buffer, size, streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return deSerializeFromValue(buffer, size, streamEndianness);
|
||||
Endianness streamEndianness) {
|
||||
ReturnValue_t result = commonDeserialize(buffer, size, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return deSerializeFromValue(buffer, size, streamEndianness);
|
||||
}
|
||||
|
||||
ReturnValue_t FilestoreRequestTlv::deSerialize(cfdp::Tlv &tlv,
|
||||
SerializeIF::Endianness endianness) {
|
||||
const uint8_t* ptr = tlv.getValue();
|
||||
size_t remSz = tlv.getSerializedSize();
|
||||
ReturnValue_t FilestoreRequestTlv::deSerialize(cfdp::Tlv &tlv, SerializeIF::Endianness endianness) {
|
||||
const uint8_t *ptr = tlv.getValue();
|
||||
size_t remSz = tlv.getSerializedSize();
|
||||
|
||||
return deSerializeFromValue(&ptr, &remSz, endianness);
|
||||
return deSerializeFromValue(&ptr, &remSz, endianness);
|
||||
}
|
||||
|
||||
uint8_t FilestoreRequestTlv::getLengthField() const {
|
||||
size_t secondFileNameLen = 0;
|
||||
if(secondFileName != nullptr and requiresSecondFileName()) {
|
||||
secondFileNameLen = secondFileName->getSerializedSize();
|
||||
}
|
||||
return 1 + firstFileName.getSerializedSize() + secondFileNameLen;
|
||||
size_t secondFileNameLen = 0;
|
||||
if (secondFileName != nullptr and requiresSecondFileName()) {
|
||||
secondFileNameLen = secondFileName->getSerializedSize();
|
||||
}
|
||||
return 1 + firstFileName.getSerializedSize() + secondFileNameLen;
|
||||
}
|
||||
|
||||
ReturnValue_t FilestoreRequestTlv::deSerializeFromValue(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) {
|
||||
this->actionCode = static_cast<cfdp::FilestoreActionCode>((**buffer >> 4) & 0x0f);
|
||||
*buffer += 1;
|
||||
*size -= 1;
|
||||
ReturnValue_t result = firstFileName.deSerialize(buffer, size, streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if(requiresSecondFileName()) {
|
||||
if(secondFileName == nullptr) {
|
||||
secondFileNameMissing();
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
result = secondFileName->deSerialize(buffer, size, streamEndianness);
|
||||
}
|
||||
Endianness streamEndianness) {
|
||||
this->actionCode = static_cast<cfdp::FilestoreActionCode>((**buffer >> 4) & 0x0f);
|
||||
*buffer += 1;
|
||||
*size -= 1;
|
||||
ReturnValue_t result = firstFileName.deSerialize(buffer, size, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if (requiresSecondFileName()) {
|
||||
if (secondFileName == nullptr) {
|
||||
secondFileNameMissing();
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
result = secondFileName->deSerialize(buffer, size, streamEndianness);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
cfdp::TlvTypes FilestoreRequestTlv::getType() const {
|
||||
return cfdp::TlvTypes::FILESTORE_REQUEST;
|
||||
}
|
||||
cfdp::TlvTypes FilestoreRequestTlv::getType() const { return cfdp::TlvTypes::FILESTORE_REQUEST; }
|
||||
|
@ -1,45 +1,42 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_FILESTOREREQUESTTLV_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_FILESTOREREQUESTTLV_H_
|
||||
|
||||
#include "../definitions.h"
|
||||
#include "Lv.h"
|
||||
#include "TlvIF.h"
|
||||
#include "fsfw/cfdp/tlv/FilestoreTlvBase.h"
|
||||
#include "fsfw/cfdp/tlv/Tlv.h"
|
||||
#include "TlvIF.h"
|
||||
#include "Lv.h"
|
||||
#include "../definitions.h"
|
||||
|
||||
class FilestoreRequestTlv:
|
||||
public cfdp::FilestoreTlvBase {
|
||||
public:
|
||||
FilestoreRequestTlv(cfdp::FilestoreActionCode actionCode, cfdp::Lv& firstFileName);
|
||||
class FilestoreRequestTlv : public cfdp::FilestoreTlvBase {
|
||||
public:
|
||||
FilestoreRequestTlv(cfdp::FilestoreActionCode actionCode, cfdp::Lv &firstFileName);
|
||||
|
||||
FilestoreRequestTlv(cfdp::Lv& firstFileName);
|
||||
FilestoreRequestTlv(cfdp::Lv &firstFileName);
|
||||
|
||||
void setSecondFileName(cfdp::Lv* secondFileName);
|
||||
void setSecondFileName(cfdp::Lv *secondFileName);
|
||||
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size,
|
||||
size_t maxSize, Endianness streamEndianness) const override;
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
/**
|
||||
* Deserialize a FS request from a raw TLV object
|
||||
* @param tlv
|
||||
* @param endianness
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t deSerialize(cfdp::Tlv& tlv, Endianness endianness);
|
||||
/**
|
||||
* Deserialize a FS request from a raw TLV object
|
||||
* @param tlv
|
||||
* @param endianness
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t deSerialize(cfdp::Tlv &tlv, Endianness endianness);
|
||||
|
||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override;
|
||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
uint8_t getLengthField() const override;
|
||||
cfdp::TlvTypes getType() const override;
|
||||
uint8_t getLengthField() const override;
|
||||
cfdp::TlvTypes getType() const override;
|
||||
|
||||
private:
|
||||
cfdp::Lv* secondFileName = nullptr;
|
||||
private:
|
||||
cfdp::Lv *secondFileName = nullptr;
|
||||
|
||||
ReturnValue_t deSerializeFromValue(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness);
|
||||
ReturnValue_t deSerializeFromValue(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_FILESTOREREQUESTTLV_H_ */
|
||||
|
@ -1,124 +1,115 @@
|
||||
#include "FilestoreResponseTlv.h"
|
||||
|
||||
FilestoreResponseTlv::FilestoreResponseTlv(cfdp::FilestoreActionCode actionCode, uint8_t statusCode,
|
||||
cfdp::Lv& firstFileName, cfdp::Lv* fsMsg): FilestoreTlvBase(actionCode, firstFileName),
|
||||
statusCode(statusCode), filestoreMsg(fsMsg) {
|
||||
}
|
||||
cfdp::Lv &firstFileName, cfdp::Lv *fsMsg)
|
||||
: FilestoreTlvBase(actionCode, firstFileName), statusCode(statusCode), filestoreMsg(fsMsg) {}
|
||||
|
||||
FilestoreResponseTlv::FilestoreResponseTlv(cfdp::Lv &firstFileName, cfdp::Lv* fsMsg):
|
||||
FilestoreTlvBase(firstFileName), statusCode(0), filestoreMsg(fsMsg) {
|
||||
}
|
||||
FilestoreResponseTlv::FilestoreResponseTlv(cfdp::Lv &firstFileName, cfdp::Lv *fsMsg)
|
||||
: FilestoreTlvBase(firstFileName), statusCode(0), filestoreMsg(fsMsg) {}
|
||||
|
||||
uint8_t FilestoreResponseTlv::getLengthField() const {
|
||||
size_t optFieldsLen = 0;
|
||||
if(secondFileName != nullptr) {
|
||||
optFieldsLen += secondFileName->getSerializedSize();
|
||||
}
|
||||
if(filestoreMsg != nullptr) {
|
||||
optFieldsLen += filestoreMsg->getSerializedSize();
|
||||
} else {
|
||||
optFieldsLen += 1;
|
||||
}
|
||||
return 1 + firstFileName.getSerializedSize() + optFieldsLen;
|
||||
size_t optFieldsLen = 0;
|
||||
if (secondFileName != nullptr) {
|
||||
optFieldsLen += secondFileName->getSerializedSize();
|
||||
}
|
||||
if (filestoreMsg != nullptr) {
|
||||
optFieldsLen += filestoreMsg->getSerializedSize();
|
||||
} else {
|
||||
optFieldsLen += 1;
|
||||
}
|
||||
return 1 + firstFileName.getSerializedSize() + optFieldsLen;
|
||||
}
|
||||
|
||||
void FilestoreResponseTlv::setSecondFileName(cfdp::Lv *secondFileName) {
|
||||
this->secondFileName = secondFileName;
|
||||
this->secondFileName = secondFileName;
|
||||
}
|
||||
|
||||
void FilestoreResponseTlv::setFilestoreMessage(cfdp::Lv *filestoreMsg) {
|
||||
this->filestoreMsg = filestoreMsg;
|
||||
this->filestoreMsg = filestoreMsg;
|
||||
}
|
||||
|
||||
ReturnValue_t FilestoreResponseTlv::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result = commonSerialize(buffer, size, maxSize, streamEndianness,
|
||||
true, this->statusCode);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = firstFileName.serialize(buffer, size, maxSize, streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if(requiresSecondFileName()) {
|
||||
if(secondFileName == nullptr) {
|
||||
secondFileNameMissing();
|
||||
return cfdp::FILESTORE_REQUIRES_SECOND_FILE;
|
||||
}
|
||||
}
|
||||
if(filestoreMsg != nullptr) {
|
||||
result = filestoreMsg->serialize(buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
else {
|
||||
if(*size == maxSize) {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = 0;
|
||||
*buffer += 1;
|
||||
*size +=1;
|
||||
}
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result =
|
||||
commonSerialize(buffer, size, maxSize, streamEndianness, true, this->statusCode);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = firstFileName.serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if (requiresSecondFileName()) {
|
||||
if (secondFileName == nullptr) {
|
||||
secondFileNameMissing();
|
||||
return cfdp::FILESTORE_REQUIRES_SECOND_FILE;
|
||||
}
|
||||
}
|
||||
if (filestoreMsg != nullptr) {
|
||||
result = filestoreMsg->serialize(buffer, size, maxSize, streamEndianness);
|
||||
} else {
|
||||
if (*size == maxSize) {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = 0;
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t FilestoreResponseTlv::deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) {
|
||||
ReturnValue_t result = commonDeserialize(buffer, size, streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return deSerializeFromValue(buffer, size, streamEndianness);
|
||||
Endianness streamEndianness) {
|
||||
ReturnValue_t result = commonDeserialize(buffer, size, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return deSerializeFromValue(buffer, size, streamEndianness);
|
||||
}
|
||||
|
||||
ReturnValue_t FilestoreResponseTlv::deSerializeFromValue(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) {
|
||||
|
||||
// The common function above checks whether at least one byte is remaining
|
||||
this->actionCode = static_cast<cfdp::FilestoreActionCode>((**buffer >> 4) & 0x0f);
|
||||
this->statusCode = **buffer & 0x0f;
|
||||
*buffer += 1;
|
||||
Endianness streamEndianness) {
|
||||
// The common function above checks whether at least one byte is remaining
|
||||
this->actionCode = static_cast<cfdp::FilestoreActionCode>((**buffer >> 4) & 0x0f);
|
||||
this->statusCode = **buffer & 0x0f;
|
||||
*buffer += 1;
|
||||
*size -= 1;
|
||||
ReturnValue_t result = firstFileName.deSerialize(buffer, size, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if (requiresSecondFileName()) {
|
||||
if (secondFileName == nullptr) {
|
||||
return cfdp::FILESTORE_REQUIRES_SECOND_FILE;
|
||||
}
|
||||
result = secondFileName->deSerialize(buffer, size, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// If the filestore message is not empty, the deserialization is only considered successfully
|
||||
// if the filestore message can be parsed. Also, if data follows after the FS response,
|
||||
// the FS msg needs to be set as well.
|
||||
if (*size == 0 or (*size > 1 and filestoreMsg == nullptr)) {
|
||||
// Filestore message missing or can't parse it
|
||||
return cfdp::FILESTORE_RESPONSE_CANT_PARSE_FS_MESSAGE;
|
||||
}
|
||||
if (filestoreMsg == nullptr) {
|
||||
*size -= 1;
|
||||
ReturnValue_t result = firstFileName.deSerialize(buffer, size, streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if(requiresSecondFileName()) {
|
||||
if(secondFileName == nullptr) {
|
||||
return cfdp::FILESTORE_REQUIRES_SECOND_FILE;
|
||||
}
|
||||
result = secondFileName->deSerialize(buffer, size, streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// If the filestore message is not empty, the deserialization is only considered successfully
|
||||
// if the filestore message can be parsed. Also, if data follows after the FS response,
|
||||
// the FS msg needs to be set as well.
|
||||
if(*size == 0 or (*size > 1 and filestoreMsg == nullptr)) {
|
||||
// Filestore message missing or can't parse it
|
||||
return cfdp::FILESTORE_RESPONSE_CANT_PARSE_FS_MESSAGE;
|
||||
}
|
||||
if(filestoreMsg == nullptr) {
|
||||
*size -= 1;
|
||||
*buffer += 1;
|
||||
// Ignore empty filestore message
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
return filestoreMsg->deSerialize(buffer, size, streamEndianness);
|
||||
*buffer += 1;
|
||||
// Ignore empty filestore message
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
return filestoreMsg->deSerialize(buffer, size, streamEndianness);
|
||||
}
|
||||
|
||||
ReturnValue_t FilestoreResponseTlv::deSerialize(const cfdp::Tlv &tlv, Endianness endianness) {
|
||||
const uint8_t* ptr = tlv.getValue();
|
||||
size_t remSz = tlv.getSerializedSize();
|
||||
const uint8_t *ptr = tlv.getValue();
|
||||
size_t remSz = tlv.getSerializedSize();
|
||||
|
||||
return deSerializeFromValue(&ptr, &remSz, endianness);
|
||||
return deSerializeFromValue(&ptr, &remSz, endianness);
|
||||
}
|
||||
|
||||
uint8_t FilestoreResponseTlv::getStatusCode() const {
|
||||
return statusCode;
|
||||
}
|
||||
uint8_t FilestoreResponseTlv::getStatusCode() const { return statusCode; }
|
||||
|
||||
|
||||
cfdp::TlvTypes FilestoreResponseTlv::getType() const {
|
||||
return cfdp::TlvTypes::FILESTORE_RESPONSE;
|
||||
}
|
||||
cfdp::TlvTypes FilestoreResponseTlv::getType() const { return cfdp::TlvTypes::FILESTORE_RESPONSE; }
|
||||
|
@ -1,50 +1,46 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_FILESTORERESPONSETLV_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_FILESTORERESPONSETLV_H_
|
||||
|
||||
#include "Lv.h"
|
||||
#include "TlvIF.h"
|
||||
#include "fsfw/cfdp/tlv/FilestoreTlvBase.h"
|
||||
#include "fsfw/cfdp/tlv/Tlv.h"
|
||||
#include "TlvIF.h"
|
||||
#include "Lv.h"
|
||||
|
||||
class FilestoreResponseTlv:
|
||||
public cfdp::FilestoreTlvBase {
|
||||
public:
|
||||
class FilestoreResponseTlv : public cfdp::FilestoreTlvBase {
|
||||
public:
|
||||
FilestoreResponseTlv(cfdp::Lv& firstFileName, cfdp::Lv* fsMsg);
|
||||
|
||||
FilestoreResponseTlv(cfdp::Lv& firstFileName, cfdp::Lv* fsMsg);
|
||||
FilestoreResponseTlv(cfdp::FilestoreActionCode actionCode, uint8_t statusCode,
|
||||
cfdp::Lv& firstFileName, cfdp::Lv* fsMsg);
|
||||
|
||||
FilestoreResponseTlv(cfdp::FilestoreActionCode actionCode, uint8_t statusCode,
|
||||
cfdp::Lv& firstFileName, cfdp::Lv* fsMsg);
|
||||
uint8_t getStatusCode() const;
|
||||
void setSecondFileName(cfdp::Lv* secondFileName);
|
||||
void setFilestoreMessage(cfdp::Lv* filestoreMsg);
|
||||
|
||||
uint8_t getStatusCode() const;
|
||||
void setSecondFileName(cfdp::Lv* secondFileName);
|
||||
void setFilestoreMessage(cfdp::Lv* filestoreMsg);
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size,
|
||||
size_t maxSize, Endianness streamEndianness) const override;
|
||||
/**
|
||||
* Deserialize a filestore response from a raw TLV object
|
||||
* @param tlv
|
||||
* @param endianness
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t deSerialize(const cfdp::Tlv& tlv, Endianness endianness);
|
||||
|
||||
/**
|
||||
* Deserialize a filestore response from a raw TLV object
|
||||
* @param tlv
|
||||
* @param endianness
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t deSerialize(const cfdp::Tlv& tlv, Endianness endianness);
|
||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override;
|
||||
uint8_t getLengthField() const override;
|
||||
cfdp::TlvTypes getType() const override;
|
||||
|
||||
uint8_t getLengthField() const override;
|
||||
cfdp::TlvTypes getType() const override;
|
||||
private:
|
||||
uint8_t statusCode;
|
||||
cfdp::Lv* secondFileName = nullptr;
|
||||
cfdp::Lv* filestoreMsg = nullptr;
|
||||
|
||||
private:
|
||||
uint8_t statusCode;
|
||||
cfdp::Lv* secondFileName = nullptr;
|
||||
cfdp::Lv* filestoreMsg = nullptr;
|
||||
|
||||
ReturnValue_t deSerializeFromValue(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness);
|
||||
ReturnValue_t deSerializeFromValue(const uint8_t** buffer, size_t* size,
|
||||
Endianness streamEndianness);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_FILESTORERESPONSETLV_H_ */
|
||||
|
@ -6,27 +6,28 @@
|
||||
#include <fsfw/cfdp/tlv/Tlv.h>
|
||||
#include <fsfw/cfdp/tlv/TlvIF.h>
|
||||
#include <fsfw/serialize/SerializeIF.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
enum FilestoreActionCode {
|
||||
CREATE_FILE = 0b0000,
|
||||
DELETE_FILE = 0b0001,
|
||||
// Second file name present
|
||||
RENAME_FILE = 0b0010,
|
||||
// Second file name present
|
||||
APPEND_FILE = 0b0011,
|
||||
// Second file name present
|
||||
REPLACE_FILE = 0b0100,
|
||||
CREATE_DIRECTORY = 0b0101,
|
||||
REMOVE_DIRECTORY = 0b0110,
|
||||
// Delete file if present
|
||||
DENY_FILE = 0b0111,
|
||||
// Remove directory if present
|
||||
DNEY_DIRECTORY = 0b1000,
|
||||
INVALID = 0b1111
|
||||
CREATE_FILE = 0b0000,
|
||||
DELETE_FILE = 0b0001,
|
||||
// Second file name present
|
||||
RENAME_FILE = 0b0010,
|
||||
// Second file name present
|
||||
APPEND_FILE = 0b0011,
|
||||
// Second file name present
|
||||
REPLACE_FILE = 0b0100,
|
||||
CREATE_DIRECTORY = 0b0101,
|
||||
REMOVE_DIRECTORY = 0b0110,
|
||||
// Delete file if present
|
||||
DENY_FILE = 0b0111,
|
||||
// Remove directory if present
|
||||
DNEY_DIRECTORY = 0b1000,
|
||||
INVALID = 0b1111
|
||||
};
|
||||
|
||||
// FSR = Filestore Response
|
||||
@ -59,118 +60,110 @@ static constexpr uint8_t FSR_DENY_FILE_NOT_ALLOWED = 0b0010;
|
||||
|
||||
static constexpr uint8_t FSR_DENY_DIR_NOT_ALLOWED = 0b0010;
|
||||
|
||||
class FilestoreTlvBase: public TlvIF {
|
||||
public:
|
||||
class FilestoreTlvBase : public TlvIF {
|
||||
public:
|
||||
FilestoreTlvBase(cfdp::Lv& firstFileName) : firstFileName(firstFileName){};
|
||||
FilestoreTlvBase(FilestoreActionCode actionCode, cfdp::Lv& firstFileName)
|
||||
: actionCode(actionCode), firstFileName(firstFileName){};
|
||||
|
||||
FilestoreTlvBase(cfdp::Lv& firstFileName): firstFileName(firstFileName) {};
|
||||
FilestoreTlvBase(FilestoreActionCode actionCode, cfdp::Lv& firstFileName):
|
||||
actionCode(actionCode), firstFileName(firstFileName) {};
|
||||
|
||||
ReturnValue_t commonSerialize(uint8_t **buffer, size_t *size,
|
||||
size_t maxSize, Endianness streamEndianness,
|
||||
bool isResponse = false, uint8_t responseStatusCode = 0) const {
|
||||
if(buffer == nullptr or size == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
if(maxSize < 3) {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = getType();
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
**buffer = getLengthField();
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
**buffer = this->actionCode << 4;
|
||||
if(isResponse) {
|
||||
**buffer |= responseStatusCode;
|
||||
}
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
ReturnValue_t commonSerialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness, bool isResponse = false,
|
||||
uint8_t responseStatusCode = 0) const {
|
||||
if (buffer == nullptr or size == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
ReturnValue_t commonDeserialize(const uint8_t **buffer, size_t *size,
|
||||
SerializeIF::Endianness streamEndianness) {
|
||||
if(buffer == nullptr or size == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
if(*size < 3) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
cfdp::TlvTypes type = static_cast<cfdp::TlvTypes>(**buffer);
|
||||
if(type != getType()) {
|
||||
return cfdp::INVALID_TLV_TYPE;
|
||||
}
|
||||
*size -= 1;
|
||||
*buffer += 1;
|
||||
|
||||
size_t remainingLength = **buffer;
|
||||
*size -= 1;
|
||||
*buffer += 1;
|
||||
if(remainingLength == 0) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
if (maxSize < 3) {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
|
||||
bool requiresSecondFileName() const {
|
||||
using namespace cfdp;
|
||||
if(actionCode == FilestoreActionCode::RENAME_FILE or
|
||||
actionCode == FilestoreActionCode::APPEND_FILE or
|
||||
actionCode == FilestoreActionCode::REPLACE_FILE) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
**buffer = getType();
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
**buffer = getLengthField();
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
**buffer = this->actionCode << 4;
|
||||
if (isResponse) {
|
||||
**buffer |= responseStatusCode;
|
||||
}
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
void secondFileNameMissing() const {
|
||||
ReturnValue_t commonDeserialize(const uint8_t** buffer, size_t* size,
|
||||
SerializeIF::Endianness streamEndianness) {
|
||||
if (buffer == nullptr or size == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
if (*size < 3) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
cfdp::TlvTypes type = static_cast<cfdp::TlvTypes>(**buffer);
|
||||
if (type != getType()) {
|
||||
return cfdp::INVALID_TLV_TYPE;
|
||||
}
|
||||
*size -= 1;
|
||||
*buffer += 1;
|
||||
|
||||
size_t remainingLength = **buffer;
|
||||
*size -= 1;
|
||||
*buffer += 1;
|
||||
if (remainingLength == 0) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
bool requiresSecondFileName() const {
|
||||
using namespace cfdp;
|
||||
if (actionCode == FilestoreActionCode::RENAME_FILE or
|
||||
actionCode == FilestoreActionCode::APPEND_FILE or
|
||||
actionCode == FilestoreActionCode::REPLACE_FILE) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void secondFileNameMissing() const {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "FilestoreRequestTlv::deSerialize: Second file name required"
|
||||
" but TLV pointer not set" << std::endl;
|
||||
sif::warning << "FilestoreRequestTlv::deSerialize: Second file name required"
|
||||
" but TLV pointer not set"
|
||||
<< std::endl;
|
||||
#else
|
||||
sif::printWarning("FilestoreRequestTlv::deSerialize: Second file name required"
|
||||
" but TLV pointer not set\n");
|
||||
sif::printWarning(
|
||||
"FilestoreRequestTlv::deSerialize: Second file name required"
|
||||
" but TLV pointer not set\n");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
FilestoreActionCode getActionCode() const {
|
||||
return actionCode;
|
||||
}
|
||||
FilestoreActionCode getActionCode() const { return actionCode; }
|
||||
|
||||
void setActionCode(FilestoreActionCode actionCode) {
|
||||
this->actionCode = actionCode;
|
||||
}
|
||||
void setActionCode(FilestoreActionCode actionCode) { this->actionCode = actionCode; }
|
||||
|
||||
cfdp::Lv& getFirstFileName() {
|
||||
return firstFileName;
|
||||
}
|
||||
cfdp::Lv& getFirstFileName() { return firstFileName; }
|
||||
|
||||
ReturnValue_t convertToTlv(cfdp::Tlv& tlv, uint8_t *buffer, size_t maxSize,
|
||||
Endianness streamEndianness) {
|
||||
size_t serSize = 0;
|
||||
uint8_t* valueStart = buffer + 2;
|
||||
ReturnValue_t result = this->serialize(&buffer, &serSize, maxSize, streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
tlv.setValue(valueStart, serSize - 2);
|
||||
tlv.setType(getType());
|
||||
return result;
|
||||
ReturnValue_t convertToTlv(cfdp::Tlv& tlv, uint8_t* buffer, size_t maxSize,
|
||||
Endianness streamEndianness) {
|
||||
size_t serSize = 0;
|
||||
uint8_t* valueStart = buffer + 2;
|
||||
ReturnValue_t result = this->serialize(&buffer, &serSize, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
tlv.setValue(valueStart, serSize - 2);
|
||||
tlv.setType(getType());
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t getSerializedSize() const override {
|
||||
return getLengthField() + 2;
|
||||
}
|
||||
protected:
|
||||
FilestoreActionCode actionCode = FilestoreActionCode::INVALID;
|
||||
cfdp::Lv& firstFileName;
|
||||
size_t getSerializedSize() const override { return getLengthField() + 2; }
|
||||
|
||||
protected:
|
||||
FilestoreActionCode actionCode = FilestoreActionCode::INVALID;
|
||||
cfdp::Lv& firstFileName;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // namespace cfdp
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_FILESTOREREQUESTBASE_H_ */
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "FlowLabelTlv.h"
|
||||
|
||||
FlowLabelTlv::FlowLabelTlv(uint8_t* value, size_t size):
|
||||
Tlv(cfdp::TlvTypes::FLOW_LABEL, value, size) {
|
||||
}
|
||||
FlowLabelTlv::FlowLabelTlv(uint8_t* value, size_t size)
|
||||
: Tlv(cfdp::TlvTypes::FLOW_LABEL, value, size) {}
|
||||
|
@ -3,11 +3,11 @@
|
||||
|
||||
#include "Tlv.h"
|
||||
|
||||
class FlowLabelTlv: public cfdp::Tlv {
|
||||
public:
|
||||
FlowLabelTlv(uint8_t* value, size_t size);
|
||||
private:
|
||||
class FlowLabelTlv : public cfdp::Tlv {
|
||||
public:
|
||||
FlowLabelTlv(uint8_t* value, size_t size);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_TLV_FLOWLABELTLV_H_ */
|
||||
|
@ -1,88 +1,85 @@
|
||||
#include "Lv.h"
|
||||
|
||||
cfdp::Lv::Lv(const uint8_t *value, size_t size): value(value, size, true) {
|
||||
if(size > 0) {
|
||||
zeroLen = false;
|
||||
}
|
||||
cfdp::Lv::Lv(const uint8_t* value, size_t size) : value(value, size, true) {
|
||||
if (size > 0) {
|
||||
zeroLen = false;
|
||||
}
|
||||
}
|
||||
|
||||
cfdp::Lv::Lv(): value(static_cast<uint8_t*>(nullptr), 0, true) {
|
||||
cfdp::Lv::Lv() : value(static_cast<uint8_t*>(nullptr), 0, true) {}
|
||||
|
||||
cfdp::Lv::Lv(const Lv& other)
|
||||
: value(other.value.getConstBuffer(), other.value.getSerializedSize() - 1, true) {
|
||||
if (other.value.getSerializedSize() - 1 > 0) {
|
||||
zeroLen = false;
|
||||
}
|
||||
}
|
||||
|
||||
cfdp::Lv::Lv(const Lv& other):
|
||||
value(other.value.getConstBuffer(), other.value.getSerializedSize() - 1, true) {
|
||||
if(other.value.getSerializedSize() - 1 > 0) {
|
||||
zeroLen = false;
|
||||
}
|
||||
cfdp::Lv& cfdp::Lv::operator=(const Lv& other) {
|
||||
size_t otherSize = 0;
|
||||
uint8_t* value = const_cast<uint8_t*>(other.getValue(&otherSize));
|
||||
if (value == nullptr or otherSize == 0) {
|
||||
this->zeroLen = true;
|
||||
}
|
||||
this->value.setBuffer(value, otherSize);
|
||||
return *this;
|
||||
}
|
||||
|
||||
cfdp::Lv& cfdp::Lv::operator =(const Lv& other) {
|
||||
size_t otherSize = 0;
|
||||
uint8_t* value = const_cast<uint8_t*>(other.getValue(&otherSize));
|
||||
if (value == nullptr or otherSize == 0) {
|
||||
this->zeroLen = true;
|
||||
}
|
||||
this->value.setBuffer(value, otherSize);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
ReturnValue_t cfdp::Lv::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
if(maxSize < 1) {
|
||||
return BUFFER_TOO_SHORT;
|
||||
}
|
||||
if(buffer == nullptr or size == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
if(zeroLen) {
|
||||
**buffer = 0;
|
||||
*size += 1;
|
||||
*buffer += 1;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
return value.serialize(buffer, size, maxSize, streamEndianness);
|
||||
ReturnValue_t cfdp::Lv::serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
if (maxSize < 1) {
|
||||
return BUFFER_TOO_SHORT;
|
||||
}
|
||||
if (buffer == nullptr or size == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
if (zeroLen) {
|
||||
**buffer = 0;
|
||||
*size += 1;
|
||||
*buffer += 1;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
return value.serialize(buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
|
||||
size_t cfdp::Lv::getSerializedSize() const {
|
||||
if(zeroLen) {
|
||||
return 1;
|
||||
}
|
||||
else if(value.getConstBuffer() == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
return value.getSerializedSize();
|
||||
if (zeroLen) {
|
||||
return 1;
|
||||
} else if (value.getConstBuffer() == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
return value.getSerializedSize();
|
||||
}
|
||||
|
||||
ReturnValue_t cfdp::Lv::deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) {
|
||||
if(buffer == nullptr or size == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
if(*size < 1) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
size_t lengthField = **buffer;
|
||||
if(lengthField == 0) {
|
||||
zeroLen = true;
|
||||
*buffer += 1;
|
||||
*size -= 1;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else if(*size < lengthField + 1) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
zeroLen = false;
|
||||
// Zero-copy implementation
|
||||
value.setBuffer(const_cast<uint8_t*>(*buffer + 1), lengthField);
|
||||
*buffer += 1 + lengthField;
|
||||
*size -= 1 + lengthField;
|
||||
ReturnValue_t cfdp::Lv::deSerialize(const uint8_t** buffer, size_t* size,
|
||||
Endianness streamEndianness) {
|
||||
if (buffer == nullptr or size == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
if (*size < 1) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
size_t lengthField = **buffer;
|
||||
if (lengthField == 0) {
|
||||
zeroLen = true;
|
||||
*buffer += 1;
|
||||
*size -= 1;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else if (*size < lengthField + 1) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
zeroLen = false;
|
||||
// Zero-copy implementation
|
||||
value.setBuffer(const_cast<uint8_t*>(*buffer + 1), lengthField);
|
||||
*buffer += 1 + lengthField;
|
||||
*size -= 1 + lengthField;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
const uint8_t* cfdp::Lv::getValue(size_t* size) const {
|
||||
if(size != nullptr) {
|
||||
// Length without length field
|
||||
*size = value.getSerializedSize() - 1;
|
||||
}
|
||||
return value.getConstBuffer();
|
||||
if (size != nullptr) {
|
||||
// Length without length field
|
||||
*size = value.getSerializedSize() - 1;
|
||||
}
|
||||
return value.getConstBuffer();
|
||||
}
|
||||
|
@ -10,44 +10,44 @@ namespace cfdp {
|
||||
* @details
|
||||
* Thin abstraction layer around a serial buffer adapter
|
||||
*/
|
||||
class Lv: public SerializeIF {
|
||||
public:
|
||||
Lv(const uint8_t* value, size_t size);
|
||||
Lv();
|
||||
class Lv : public SerializeIF {
|
||||
public:
|
||||
Lv(const uint8_t* value, size_t size);
|
||||
Lv();
|
||||
|
||||
// Delete copy ctor and assingment ctor for now because this class contains a reference to
|
||||
// data
|
||||
Lv (const Lv&);
|
||||
Lv& operator= (const Lv&);
|
||||
// Delete copy ctor and assingment ctor for now because this class contains a reference to
|
||||
// data
|
||||
Lv(const Lv&);
|
||||
Lv& operator=(const Lv&);
|
||||
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size,
|
||||
size_t maxSize, Endianness streamEndianness) const override;
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
/**
|
||||
* @brief Deserialize a LV field from a raw buffer
|
||||
* @param buffer Raw buffer including the size field
|
||||
* @param size
|
||||
* @param streamEndianness
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override;
|
||||
/**
|
||||
* @brief Deserialize a LV field from a raw buffer
|
||||
* @param buffer Raw buffer including the size field
|
||||
* @param size
|
||||
* @param streamEndianness
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
/**
|
||||
* Get value field and its size.
|
||||
* @param size Optionally retrieve size. Size will be the size of the actual value field
|
||||
* without the length field of the LV
|
||||
* @return
|
||||
*/
|
||||
const uint8_t* getValue(size_t* size) const;
|
||||
private:
|
||||
/**
|
||||
* Get value field and its size.
|
||||
* @param size Optionally retrieve size. Size will be the size of the actual value field
|
||||
* without the length field of the LV
|
||||
* @return
|
||||
*/
|
||||
const uint8_t* getValue(size_t* size) const;
|
||||
|
||||
bool zeroLen = true;
|
||||
SerialBufferAdapter<uint8_t> value;
|
||||
private:
|
||||
bool zeroLen = true;
|
||||
SerialBufferAdapter<uint8_t> value;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace cfdp
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_LV_H_ */
|
||||
|
@ -1,8 +1,6 @@
|
||||
#include "MessageToUserTlv.h"
|
||||
|
||||
MessageToUserTlv::MessageToUserTlv(uint8_t *value, size_t size):
|
||||
Tlv(cfdp::TlvTypes::MSG_TO_USER, value, size) {
|
||||
}
|
||||
MessageToUserTlv::MessageToUserTlv(uint8_t *value, size_t size)
|
||||
: Tlv(cfdp::TlvTypes::MSG_TO_USER, value, size) {}
|
||||
|
||||
MessageToUserTlv::MessageToUserTlv(): Tlv() {
|
||||
}
|
||||
MessageToUserTlv::MessageToUserTlv() : Tlv() {}
|
||||
|
@ -3,11 +3,12 @@
|
||||
|
||||
#include "Tlv.h"
|
||||
|
||||
class MessageToUserTlv: public cfdp::Tlv {
|
||||
public:
|
||||
MessageToUserTlv();
|
||||
MessageToUserTlv(uint8_t* value, size_t size);
|
||||
private:
|
||||
class MessageToUserTlv : public cfdp::Tlv {
|
||||
public:
|
||||
MessageToUserTlv();
|
||||
MessageToUserTlv(uint8_t* value, size_t size);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_TLV_MESSAGETOUSERTLV_H_ */
|
||||
|
@ -1,114 +1,104 @@
|
||||
#include "Tlv.h"
|
||||
|
||||
cfdp::Tlv::Tlv(TlvTypes type, const uint8_t *value, size_t size): type(type),
|
||||
value(value, size, true) {
|
||||
if(size > 0) {
|
||||
zeroLen = false;
|
||||
}
|
||||
cfdp::Tlv::Tlv(TlvTypes type, const uint8_t *value, size_t size)
|
||||
: type(type), value(value, size, true) {
|
||||
if (size > 0) {
|
||||
zeroLen = false;
|
||||
}
|
||||
}
|
||||
|
||||
cfdp::Tlv::Tlv(): value(static_cast<uint8_t*>(nullptr), 0, true) {
|
||||
}
|
||||
cfdp::Tlv::Tlv() : value(static_cast<uint8_t *>(nullptr), 0, true) {}
|
||||
|
||||
ReturnValue_t cfdp::Tlv::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
if(buffer == nullptr or size == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
if(*size + 2 > maxSize) {
|
||||
return BUFFER_TOO_SHORT;
|
||||
}
|
||||
if(type == TlvTypes::INVALID_TLV) {
|
||||
return INVALID_TLV_TYPE;
|
||||
}
|
||||
**buffer = type;
|
||||
Endianness streamEndianness) const {
|
||||
if (buffer == nullptr or size == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
if (*size + 2 > maxSize) {
|
||||
return BUFFER_TOO_SHORT;
|
||||
}
|
||||
if (type == TlvTypes::INVALID_TLV) {
|
||||
return INVALID_TLV_TYPE;
|
||||
}
|
||||
**buffer = type;
|
||||
*size += 1;
|
||||
*buffer += 1;
|
||||
|
||||
if (zeroLen) {
|
||||
**buffer = 0;
|
||||
*size += 1;
|
||||
*buffer += 1;
|
||||
|
||||
if(zeroLen) {
|
||||
**buffer = 0;
|
||||
*size += 1;
|
||||
*buffer += 1;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
if(value.getConstBuffer() == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return value.serialize(buffer, size, maxSize, streamEndianness);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
if (value.getConstBuffer() == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return value.serialize(buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
|
||||
size_t cfdp::Tlv::getSerializedSize() const {
|
||||
if(zeroLen) {
|
||||
return 2;
|
||||
}
|
||||
else if (value.getConstBuffer() == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
return value.getSerializedSize() + 1;
|
||||
if (zeroLen) {
|
||||
return 2;
|
||||
} else if (value.getConstBuffer() == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
return value.getSerializedSize() + 1;
|
||||
}
|
||||
|
||||
ReturnValue_t cfdp::Tlv::deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) {
|
||||
if(buffer == nullptr or size == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
if(*size < 2) {
|
||||
return STREAM_TOO_SHORT;
|
||||
}
|
||||
Endianness streamEndianness) {
|
||||
if (buffer == nullptr or size == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
if (*size < 2) {
|
||||
return STREAM_TOO_SHORT;
|
||||
}
|
||||
|
||||
uint8_t rawType = **buffer;
|
||||
if(not checkType(rawType)) {
|
||||
return INVALID_TLV_TYPE;
|
||||
}
|
||||
uint8_t rawType = **buffer;
|
||||
if (not checkType(rawType)) {
|
||||
return INVALID_TLV_TYPE;
|
||||
}
|
||||
|
||||
type = static_cast<TlvTypes>(rawType);
|
||||
type = static_cast<TlvTypes>(rawType);
|
||||
*buffer += 1;
|
||||
*size -= 1;
|
||||
|
||||
size_t lengthField = **buffer;
|
||||
if (lengthField == 0) {
|
||||
zeroLen = true;
|
||||
*buffer += 1;
|
||||
*size -= 1;
|
||||
|
||||
size_t lengthField = **buffer;
|
||||
if(lengthField == 0) {
|
||||
zeroLen = true;
|
||||
*buffer += 1;
|
||||
*size -= 1;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
if(lengthField + 1 > *size) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
zeroLen = false;
|
||||
// Zero-copy implementation
|
||||
value.setBuffer(const_cast<uint8_t*>(*buffer + 1), lengthField);
|
||||
*buffer += 1 + lengthField;
|
||||
*size -= 1 + lengthField;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
if (lengthField + 1 > *size) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
zeroLen = false;
|
||||
// Zero-copy implementation
|
||||
value.setBuffer(const_cast<uint8_t *>(*buffer + 1), lengthField);
|
||||
*buffer += 1 + lengthField;
|
||||
*size -= 1 + lengthField;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
const uint8_t* cfdp::Tlv::getValue() const {
|
||||
return value.getConstBuffer();
|
||||
}
|
||||
const uint8_t *cfdp::Tlv::getValue() const { return value.getConstBuffer(); }
|
||||
|
||||
cfdp::TlvTypes cfdp::Tlv::getType() const {
|
||||
return type;
|
||||
}
|
||||
cfdp::TlvTypes cfdp::Tlv::getType() const { return type; }
|
||||
|
||||
bool cfdp::Tlv::checkType(uint8_t rawType) {
|
||||
if (rawType != 0x03 and rawType <= 6) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (rawType != 0x03 and rawType <= 6) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void cfdp::Tlv::setValue(uint8_t *value, size_t len) {
|
||||
if(len > 0) {
|
||||
zeroLen = false;
|
||||
}
|
||||
this->value.setBuffer(value, len);
|
||||
if (len > 0) {
|
||||
zeroLen = false;
|
||||
}
|
||||
this->value.setBuffer(value, len);
|
||||
}
|
||||
|
||||
uint8_t cfdp::Tlv::getLengthField() const {
|
||||
return this->value.getSerializedSize() - 1;
|
||||
}
|
||||
uint8_t cfdp::Tlv::getLengthField() const { return this->value.getSerializedSize() - 1; }
|
||||
|
||||
void cfdp::Tlv::setType(TlvTypes type) {
|
||||
this->type = type;
|
||||
}
|
||||
void cfdp::Tlv::setType(TlvTypes type) { this->type = type; }
|
||||
|
@ -11,54 +11,54 @@ namespace cfdp {
|
||||
* @details
|
||||
* Thin abstraction layer around a serial buffer adapter
|
||||
*/
|
||||
class Tlv: public TlvIF {
|
||||
public:
|
||||
Tlv(TlvTypes type, const uint8_t *value, size_t size);
|
||||
Tlv();
|
||||
class Tlv : public TlvIF {
|
||||
public:
|
||||
Tlv(TlvTypes type, const uint8_t *value, size_t size);
|
||||
Tlv();
|
||||
|
||||
/**
|
||||
* Serialize a TLV into a given buffer
|
||||
* @param buffer
|
||||
* @param size
|
||||
* @param maxSize
|
||||
* @param streamEndianness
|
||||
* @return
|
||||
* - RETURN_OK on success
|
||||
* - INVALID_TLV_TYPE
|
||||
* - SerializeIF returncode on wrong serialization parameters
|
||||
*/
|
||||
virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size,
|
||||
size_t maxSize, Endianness streamEndianness) const override;
|
||||
/**
|
||||
* Serialize a TLV into a given buffer
|
||||
* @param buffer
|
||||
* @param size
|
||||
* @param maxSize
|
||||
* @param streamEndianness
|
||||
* @return
|
||||
* - RETURN_OK on success
|
||||
* - INVALID_TLV_TYPE
|
||||
* - SerializeIF returncode on wrong serialization parameters
|
||||
*/
|
||||
virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
virtual size_t getSerializedSize() const override;
|
||||
virtual size_t getSerializedSize() const override;
|
||||
|
||||
/**
|
||||
* @brief Deserialize a LV field from a raw buffer. Zero-copy implementation
|
||||
* @param buffer Raw buffer including the size field
|
||||
* @param size
|
||||
* @param streamEndianness
|
||||
* - RETURN_OK on success
|
||||
* - INVALID_TLV_TYPE
|
||||
* - SerializeIF returncode on wrong deserialization parameters
|
||||
*/
|
||||
virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override;
|
||||
/**
|
||||
* @brief Deserialize a LV field from a raw buffer. Zero-copy implementation
|
||||
* @param buffer Raw buffer including the size field
|
||||
* @param size
|
||||
* @param streamEndianness
|
||||
* - RETURN_OK on success
|
||||
* - INVALID_TLV_TYPE
|
||||
* - SerializeIF returncode on wrong deserialization parameters
|
||||
*/
|
||||
virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
void setValue(uint8_t *value, size_t len);
|
||||
|
||||
void setValue(uint8_t *value, size_t len);
|
||||
const uint8_t *getValue() const;
|
||||
void setType(TlvTypes type);
|
||||
TlvTypes getType() const override;
|
||||
uint8_t getLengthField() const override;
|
||||
|
||||
const uint8_t* getValue() const;
|
||||
void setType(TlvTypes type);
|
||||
TlvTypes getType() const override;
|
||||
uint8_t getLengthField() const override;
|
||||
private:
|
||||
bool checkType(uint8_t rawType);
|
||||
private:
|
||||
bool checkType(uint8_t rawType);
|
||||
|
||||
bool zeroLen = true;
|
||||
TlvTypes type = TlvTypes::INVALID_TLV;
|
||||
SerialBufferAdapter<uint8_t> value;
|
||||
bool zeroLen = true;
|
||||
TlvTypes type = TlvTypes::INVALID_TLV;
|
||||
SerialBufferAdapter<uint8_t> value;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace cfdp
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_TLV_H_ */
|
||||
|
@ -3,14 +3,12 @@
|
||||
|
||||
#include "../definitions.h"
|
||||
|
||||
class TlvIF: public SerializeIF {
|
||||
public:
|
||||
virtual~ TlvIF() {};
|
||||
class TlvIF : public SerializeIF {
|
||||
public:
|
||||
virtual ~TlvIF(){};
|
||||
|
||||
virtual uint8_t getLengthField() const = 0;
|
||||
virtual cfdp::TlvTypes getType() const = 0;
|
||||
virtual uint8_t getLengthField() const = 0;
|
||||
virtual cfdp::TlvTypes getType() const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_TLVIF_H_ */
|
||||
|
@ -13,241 +13,210 @@
|
||||
*
|
||||
* @ingroup container
|
||||
*/
|
||||
template<typename T, typename count_t = uint8_t>
|
||||
template <typename T, typename count_t = uint8_t>
|
||||
class ArrayList {
|
||||
template<typename U, typename count> friend class SerialArrayListAdapter;
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::ARRAY_LIST;
|
||||
static const ReturnValue_t FULL = MAKE_RETURN_CODE(0x01);
|
||||
template <typename U, typename count>
|
||||
friend class SerialArrayListAdapter;
|
||||
|
||||
/**
|
||||
* This is the allocating constructor.
|
||||
* It allocates an array of the specified size.
|
||||
* @param maxSize
|
||||
*/
|
||||
ArrayList(count_t maxSize) :
|
||||
size(0), maxSize_(maxSize), allocated(true) {
|
||||
entries = new T[maxSize];
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::ARRAY_LIST;
|
||||
static const ReturnValue_t FULL = MAKE_RETURN_CODE(0x01);
|
||||
|
||||
/**
|
||||
* This is the allocating constructor.
|
||||
* It allocates an array of the specified size.
|
||||
* @param maxSize
|
||||
*/
|
||||
ArrayList(count_t maxSize) : size(0), maxSize_(maxSize), allocated(true) {
|
||||
entries = new T[maxSize];
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the non-allocating constructor
|
||||
*
|
||||
* It expects a pointer to an array of a certain size and initializes
|
||||
* itself to it.
|
||||
*
|
||||
* @param storage the array to use as backend
|
||||
* @param maxSize size of storage
|
||||
* @param size size of data already present in storage
|
||||
*/
|
||||
ArrayList(T* storage, count_t maxSize, count_t size = 0)
|
||||
: size(size), entries(storage), maxSize_(maxSize), allocated(false) {}
|
||||
|
||||
/**
|
||||
* Copying is forbiden by declaring copy ctor and copy assignment deleted
|
||||
* It is too ambigous in this case.
|
||||
* (Allocate a new backend? Use the same? What to do in an modifying call?)
|
||||
*/
|
||||
ArrayList(const ArrayList& other) = delete;
|
||||
const ArrayList& operator=(const ArrayList& other) = delete;
|
||||
|
||||
/**
|
||||
* Number of Elements stored in this List
|
||||
*/
|
||||
count_t size;
|
||||
|
||||
/**
|
||||
* Destructor, if the allocating constructor was used, it deletes the array.
|
||||
*/
|
||||
virtual ~ArrayList() {
|
||||
if (allocated) {
|
||||
delete[] entries;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An Iterator to go trough an ArrayList
|
||||
*
|
||||
* It stores a pointer to an element and increments the
|
||||
* pointer when incremented itself.
|
||||
*/
|
||||
class Iterator {
|
||||
public:
|
||||
/**
|
||||
* Empty ctor, points to NULL
|
||||
*/
|
||||
Iterator() : value(0) {}
|
||||
|
||||
/**
|
||||
* This is the non-allocating constructor
|
||||
* Initializes the Iterator to point to an element
|
||||
*
|
||||
* It expects a pointer to an array of a certain size and initializes
|
||||
* itself to it.
|
||||
*
|
||||
* @param storage the array to use as backend
|
||||
* @param maxSize size of storage
|
||||
* @param size size of data already present in storage
|
||||
* @param initialize
|
||||
*/
|
||||
ArrayList(T *storage, count_t maxSize, count_t size = 0) :
|
||||
size(size), entries(storage), maxSize_(maxSize), allocated(false) {
|
||||
}
|
||||
Iterator(T* initialize) { value = initialize; }
|
||||
|
||||
/**
|
||||
* Copying is forbiden by declaring copy ctor and copy assignment deleted
|
||||
* It is too ambigous in this case.
|
||||
* (Allocate a new backend? Use the same? What to do in an modifying call?)
|
||||
* The current element the iterator points to
|
||||
*/
|
||||
ArrayList(const ArrayList& other) = delete;
|
||||
const ArrayList& operator=(const ArrayList& other) = delete;
|
||||
T* value;
|
||||
|
||||
/**
|
||||
* Number of Elements stored in this List
|
||||
*/
|
||||
count_t size;
|
||||
|
||||
|
||||
/**
|
||||
* Destructor, if the allocating constructor was used, it deletes the array.
|
||||
*/
|
||||
virtual ~ArrayList() {
|
||||
if (allocated) {
|
||||
delete[] entries;
|
||||
}
|
||||
Iterator& operator++() {
|
||||
value++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* An Iterator to go trough an ArrayList
|
||||
*
|
||||
* It stores a pointer to an element and increments the
|
||||
* pointer when incremented itself.
|
||||
*/
|
||||
class Iterator {
|
||||
public:
|
||||
/**
|
||||
* Empty ctor, points to NULL
|
||||
*/
|
||||
Iterator(): value(0) {}
|
||||
|
||||
/**
|
||||
* Initializes the Iterator to point to an element
|
||||
*
|
||||
* @param initialize
|
||||
*/
|
||||
Iterator(T *initialize) {
|
||||
value = initialize;
|
||||
}
|
||||
|
||||
/**
|
||||
* The current element the iterator points to
|
||||
*/
|
||||
T *value;
|
||||
|
||||
Iterator& operator++() {
|
||||
value++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator operator++(int) {
|
||||
Iterator tmp(*this);
|
||||
operator++();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Iterator& operator--() {
|
||||
value--;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator operator--(int) {
|
||||
Iterator tmp(*this);
|
||||
operator--();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
T& operator*() {
|
||||
return *value;
|
||||
}
|
||||
|
||||
const T& operator*() const {
|
||||
return *value;
|
||||
}
|
||||
|
||||
T *operator->() {
|
||||
return value;
|
||||
}
|
||||
|
||||
const T *operator->() const {
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
friend bool operator==(const ArrayList::Iterator& lhs,
|
||||
const ArrayList::Iterator& rhs) {
|
||||
return (lhs.value == rhs.value);
|
||||
Iterator operator++(int) {
|
||||
Iterator tmp(*this);
|
||||
operator++();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
friend bool operator!=(const ArrayList::Iterator& lhs,
|
||||
const ArrayList::Iterator& rhs) {
|
||||
return not (lhs.value == rhs.value);
|
||||
Iterator& operator--() {
|
||||
value--;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator pointing to the first stored elmement
|
||||
*
|
||||
* @return Iterator to the first element
|
||||
*/
|
||||
Iterator begin() const {
|
||||
return Iterator(&entries[0]);
|
||||
Iterator operator--(int) {
|
||||
Iterator tmp(*this);
|
||||
operator--();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns an Iterator pointing to the element after the last stored entry
|
||||
*
|
||||
* @return Iterator to the element after the last entry
|
||||
*/
|
||||
Iterator end() const {
|
||||
return Iterator(&entries[size]);
|
||||
T& operator*() { return *value; }
|
||||
|
||||
const T& operator*() const { return *value; }
|
||||
|
||||
T* operator->() { return value; }
|
||||
|
||||
const T* operator->() const { return value; }
|
||||
};
|
||||
|
||||
friend bool operator==(const ArrayList::Iterator& lhs, const ArrayList::Iterator& rhs) {
|
||||
return (lhs.value == rhs.value);
|
||||
}
|
||||
|
||||
friend bool operator!=(const ArrayList::Iterator& lhs, const ArrayList::Iterator& rhs) {
|
||||
return not(lhs.value == rhs.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator pointing to the first stored elmement
|
||||
*
|
||||
* @return Iterator to the first element
|
||||
*/
|
||||
Iterator begin() const { return Iterator(&entries[0]); }
|
||||
|
||||
/**
|
||||
* returns an Iterator pointing to the element after the last stored entry
|
||||
*
|
||||
* @return Iterator to the element after the last entry
|
||||
*/
|
||||
Iterator end() const { return Iterator(&entries[size]); }
|
||||
|
||||
T& operator[](count_t i) const { return entries[i]; }
|
||||
|
||||
/**
|
||||
* The first element
|
||||
*
|
||||
* @return pointer to the first stored element
|
||||
*/
|
||||
T* front() { return entries; }
|
||||
|
||||
/**
|
||||
* The last element
|
||||
*
|
||||
* does not return a valid pointer if called on an empty list.
|
||||
*
|
||||
* @return pointer to the last stored element
|
||||
*/
|
||||
T* back() {
|
||||
return &entries[size - 1];
|
||||
// Alternative solution
|
||||
// return const_cast<T*>(static_cast<const T*>(*this).back());
|
||||
}
|
||||
|
||||
const T* back() const { return &entries[size - 1]; }
|
||||
|
||||
/**
|
||||
* The maximum number of elements this List can contain
|
||||
*
|
||||
* @return maximum number of elements
|
||||
*/
|
||||
size_t maxSize() const { return this->maxSize_; }
|
||||
|
||||
/**
|
||||
* Insert a new element into the list.
|
||||
*
|
||||
* The new element is inserted after the last stored element.
|
||||
*
|
||||
* @param entry
|
||||
* @return
|
||||
* -@c FULL if the List is full
|
||||
* -@c RETURN_OK else
|
||||
*/
|
||||
ReturnValue_t insert(T entry) {
|
||||
if (size >= maxSize_) {
|
||||
return FULL;
|
||||
}
|
||||
entries[size] = entry;
|
||||
++size;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
T & operator[](count_t i) const {
|
||||
return entries[i];
|
||||
}
|
||||
/**
|
||||
* clear the List
|
||||
*
|
||||
* This does not actually clear all entries, it only sets the size to 0.
|
||||
*/
|
||||
void clear() { size = 0; }
|
||||
|
||||
/**
|
||||
* The first element
|
||||
*
|
||||
* @return pointer to the first stored element
|
||||
*/
|
||||
T *front() {
|
||||
return entries;
|
||||
}
|
||||
count_t remaining() { return (maxSize_ - size); }
|
||||
|
||||
/**
|
||||
* The last element
|
||||
*
|
||||
* does not return a valid pointer if called on an empty list.
|
||||
*
|
||||
* @return pointer to the last stored element
|
||||
*/
|
||||
T *back() {
|
||||
return &entries[size - 1];
|
||||
//Alternative solution
|
||||
//return const_cast<T*>(static_cast<const T*>(*this).back());
|
||||
}
|
||||
protected:
|
||||
/**
|
||||
* pointer to the array in which the entries are stored
|
||||
*/
|
||||
T* entries;
|
||||
/**
|
||||
* remembering the maximum size
|
||||
*/
|
||||
size_t maxSize_;
|
||||
|
||||
const T* back() const{
|
||||
return &entries[size-1];
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum number of elements this List can contain
|
||||
*
|
||||
* @return maximum number of elements
|
||||
*/
|
||||
size_t maxSize() const {
|
||||
return this->maxSize_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a new element into the list.
|
||||
*
|
||||
* The new element is inserted after the last stored element.
|
||||
*
|
||||
* @param entry
|
||||
* @return
|
||||
* -@c FULL if the List is full
|
||||
* -@c RETURN_OK else
|
||||
*/
|
||||
ReturnValue_t insert(T entry) {
|
||||
if (size >= maxSize_) {
|
||||
return FULL;
|
||||
}
|
||||
entries[size] = entry;
|
||||
++size;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* clear the List
|
||||
*
|
||||
* This does not actually clear all entries, it only sets the size to 0.
|
||||
*/
|
||||
void clear() {
|
||||
size = 0;
|
||||
}
|
||||
|
||||
count_t remaining() {
|
||||
return (maxSize_ - size);
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* pointer to the array in which the entries are stored
|
||||
*/
|
||||
T *entries;
|
||||
/**
|
||||
* remembering the maximum size
|
||||
*/
|
||||
size_t maxSize_;
|
||||
|
||||
/**
|
||||
* true if the array was allocated and needs to be deleted in the destructor.
|
||||
*/
|
||||
bool allocated;
|
||||
/**
|
||||
* true if the array was allocated and needs to be deleted in the destructor.
|
||||
*/
|
||||
bool allocated;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_CONTAINER_ARRAYLIST_H_ */
|
||||
|
@ -3,151 +3,125 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <map>
|
||||
template<typename Tp>
|
||||
template <typename Tp>
|
||||
class BinaryNode {
|
||||
public:
|
||||
BinaryNode(Tp* setValue) :
|
||||
value(setValue), left(NULL), right(NULL), parent(NULL) {
|
||||
}
|
||||
Tp *value;
|
||||
BinaryNode* left;
|
||||
BinaryNode* right;
|
||||
BinaryNode* parent;
|
||||
public:
|
||||
BinaryNode(Tp* setValue) : value(setValue), left(NULL), right(NULL), parent(NULL) {}
|
||||
Tp* value;
|
||||
BinaryNode* left;
|
||||
BinaryNode* right;
|
||||
BinaryNode* parent;
|
||||
};
|
||||
|
||||
template<typename Tp>
|
||||
template <typename Tp>
|
||||
class ExplicitNodeIterator {
|
||||
public:
|
||||
typedef ExplicitNodeIterator<Tp> _Self;
|
||||
typedef BinaryNode<Tp> _Node;
|
||||
typedef Tp value_type;
|
||||
typedef Tp* pointer;
|
||||
typedef Tp& reference;
|
||||
ExplicitNodeIterator() :
|
||||
element(NULL) {
|
||||
public:
|
||||
typedef ExplicitNodeIterator<Tp> _Self;
|
||||
typedef BinaryNode<Tp> _Node;
|
||||
typedef Tp value_type;
|
||||
typedef Tp* pointer;
|
||||
typedef Tp& reference;
|
||||
ExplicitNodeIterator() : element(NULL) {}
|
||||
ExplicitNodeIterator(_Node* node) : element(node) {}
|
||||
BinaryNode<Tp>* element;
|
||||
_Self up() { return _Self(element->parent); }
|
||||
_Self left() {
|
||||
if (element != NULL) {
|
||||
return _Self(element->left);
|
||||
} else {
|
||||
return _Self(NULL);
|
||||
}
|
||||
ExplicitNodeIterator(_Node* node) :
|
||||
element(node) {
|
||||
}
|
||||
_Self right() {
|
||||
if (element != NULL) {
|
||||
return _Self(element->right);
|
||||
} else {
|
||||
return _Self(NULL);
|
||||
}
|
||||
BinaryNode<Tp>* element;
|
||||
_Self up() {
|
||||
return _Self(element->parent);
|
||||
}
|
||||
_Self left() {
|
||||
if (element != NULL) {
|
||||
return _Self(element->left);
|
||||
} else {
|
||||
return _Self(NULL);
|
||||
}
|
||||
|
||||
}
|
||||
_Self right() {
|
||||
if (element != NULL) {
|
||||
return _Self(element->right);
|
||||
} else {
|
||||
return _Self(NULL);
|
||||
}
|
||||
|
||||
}
|
||||
bool operator==(const _Self& __x) const {
|
||||
return element == __x.element;
|
||||
}
|
||||
bool operator!=(const _Self& __x) const {
|
||||
return element != __x.element;
|
||||
}
|
||||
pointer
|
||||
operator->() const {
|
||||
if (element != NULL) {
|
||||
return element->value;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
pointer operator*() const {
|
||||
return this->operator->();
|
||||
}
|
||||
bool operator==(const _Self& __x) const { return element == __x.element; }
|
||||
bool operator!=(const _Self& __x) const { return element != __x.element; }
|
||||
pointer operator->() const {
|
||||
if (element != NULL) {
|
||||
return element->value;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
pointer operator*() const { return this->operator->(); }
|
||||
};
|
||||
|
||||
/**
|
||||
* Pretty rudimentary version of a simple binary tree (not a binary search tree!).
|
||||
*/
|
||||
template<typename Tp>
|
||||
template <typename Tp>
|
||||
class BinaryTree {
|
||||
public:
|
||||
typedef ExplicitNodeIterator<Tp> iterator;
|
||||
typedef BinaryNode<Tp> Node;
|
||||
typedef std::pair<iterator, iterator> children;
|
||||
BinaryTree() :
|
||||
rootNode(NULL) {
|
||||
public:
|
||||
typedef ExplicitNodeIterator<Tp> iterator;
|
||||
typedef BinaryNode<Tp> Node;
|
||||
typedef std::pair<iterator, iterator> children;
|
||||
BinaryTree() : rootNode(NULL) {}
|
||||
BinaryTree(Node* rootNode) : rootNode(rootNode) {}
|
||||
iterator begin() const { return iterator(rootNode); }
|
||||
static iterator end() { return iterator(NULL); }
|
||||
iterator insert(bool insertLeft, iterator parentNode, Node* newNode) {
|
||||
newNode->parent = parentNode.element;
|
||||
if (parentNode.element != NULL) {
|
||||
if (insertLeft) {
|
||||
parentNode.element->left = newNode;
|
||||
} else {
|
||||
parentNode.element->right = newNode;
|
||||
}
|
||||
} else {
|
||||
// Insert first element.
|
||||
rootNode = newNode;
|
||||
}
|
||||
BinaryTree(Node* rootNode) :
|
||||
rootNode(rootNode) {
|
||||
return iterator(newNode);
|
||||
}
|
||||
// No recursion to children. Needs to be done externally.
|
||||
children erase(iterator node) {
|
||||
if (node.element == rootNode) {
|
||||
// We're root node
|
||||
rootNode = NULL;
|
||||
} else {
|
||||
// Delete parent's reference
|
||||
if (node.up().left() == node) {
|
||||
node.up().element->left = NULL;
|
||||
} else {
|
||||
node.up().element->right = NULL;
|
||||
}
|
||||
}
|
||||
iterator begin() const {
|
||||
return iterator(rootNode);
|
||||
return children(node.element->left, node.element->right);
|
||||
}
|
||||
static uint32_t countLeft(iterator start) {
|
||||
if (start == end()) {
|
||||
return 0;
|
||||
}
|
||||
static iterator end() {
|
||||
return iterator(NULL);
|
||||
// We also count the start node itself.
|
||||
uint32_t count = 1;
|
||||
while (start.left() != end()) {
|
||||
count++;
|
||||
start = start.left();
|
||||
}
|
||||
iterator insert(bool insertLeft, iterator parentNode, Node* newNode ) {
|
||||
newNode->parent = parentNode.element;
|
||||
if (parentNode.element != NULL) {
|
||||
if (insertLeft) {
|
||||
parentNode.element->left = newNode;
|
||||
} else {
|
||||
parentNode.element->right = newNode;
|
||||
}
|
||||
} else {
|
||||
//Insert first element.
|
||||
rootNode = newNode;
|
||||
}
|
||||
return iterator(newNode);
|
||||
return count;
|
||||
}
|
||||
static uint32_t countRight(iterator start) {
|
||||
if (start == end()) {
|
||||
return 0;
|
||||
}
|
||||
//No recursion to children. Needs to be done externally.
|
||||
children erase(iterator node) {
|
||||
if (node.element == rootNode) {
|
||||
//We're root node
|
||||
rootNode = NULL;
|
||||
} else {
|
||||
//Delete parent's reference
|
||||
if (node.up().left() == node) {
|
||||
node.up().element->left = NULL;
|
||||
} else {
|
||||
node.up().element->right = NULL;
|
||||
}
|
||||
}
|
||||
return children(node.element->left, node.element->right);
|
||||
}
|
||||
static uint32_t countLeft(iterator start) {
|
||||
if (start == end()) {
|
||||
return 0;
|
||||
}
|
||||
//We also count the start node itself.
|
||||
uint32_t count = 1;
|
||||
while (start.left() != end()) {
|
||||
count++;
|
||||
start = start.left();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
static uint32_t countRight(iterator start) {
|
||||
if (start == end()) {
|
||||
return 0;
|
||||
}
|
||||
//We also count the start node itself.
|
||||
uint32_t count = 1;
|
||||
while (start.right() != end()) {
|
||||
count++;
|
||||
start = start.right();
|
||||
}
|
||||
return count;
|
||||
// We also count the start node itself.
|
||||
uint32_t count = 1;
|
||||
while (start.right() != end()) {
|
||||
count++;
|
||||
start = start.right();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
protected:
|
||||
Node* rootNode;
|
||||
protected:
|
||||
Node* rootNode;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FRAMEWORK_CONTAINER_BINARYTREE_H_ */
|
||||
|
@ -1,9 +1,10 @@
|
||||
#ifndef FSFW_CONTAINER_DYNAMICFIFO_H_
|
||||
#define FSFW_CONTAINER_DYNAMICFIFO_H_
|
||||
|
||||
#include "FIFOBase.h"
|
||||
#include <vector>
|
||||
|
||||
#include "FIFOBase.h"
|
||||
|
||||
/**
|
||||
* @brief Simple First-In-First-Out data structure. The maximum size
|
||||
* can be set in the constructor.
|
||||
@ -14,42 +15,41 @@
|
||||
* @tparam T Entry Type
|
||||
* @tparam capacity Maximum capacity
|
||||
*/
|
||||
template<typename T>
|
||||
class DynamicFIFO: public FIFOBase<T> {
|
||||
public:
|
||||
DynamicFIFO(size_t maxCapacity): FIFOBase<T>(nullptr, maxCapacity),
|
||||
fifoVector(maxCapacity) {
|
||||
// trying to pass the pointer of the uninitialized vector
|
||||
// to the FIFOBase constructor directly lead to a super evil bug.
|
||||
// So we do it like this now.
|
||||
this->setContainer(fifoVector.data());
|
||||
};
|
||||
template <typename T>
|
||||
class DynamicFIFO : public FIFOBase<T> {
|
||||
public:
|
||||
DynamicFIFO(size_t maxCapacity) : FIFOBase<T>(nullptr, maxCapacity), fifoVector(maxCapacity) {
|
||||
// trying to pass the pointer of the uninitialized vector
|
||||
// to the FIFOBase constructor directly lead to a super evil bug.
|
||||
// So we do it like this now.
|
||||
this->setContainer(fifoVector.data());
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Custom copy constructor which prevents setting the
|
||||
* underlying pointer wrong. This function allocates memory!
|
||||
* @details This is a very heavy operation so try to avoid this!
|
||||
*
|
||||
*/
|
||||
DynamicFIFO(const DynamicFIFO& other): FIFOBase<T>(other),
|
||||
fifoVector(other.maxCapacity) {
|
||||
this->fifoVector = other.fifoVector;
|
||||
this->setContainer(fifoVector.data());
|
||||
}
|
||||
/**
|
||||
* @brief Custom copy constructor which prevents setting the
|
||||
* underlying pointer wrong. This function allocates memory!
|
||||
* @details This is a very heavy operation so try to avoid this!
|
||||
*
|
||||
*/
|
||||
DynamicFIFO(const DynamicFIFO& other) : FIFOBase<T>(other), fifoVector(other.maxCapacity) {
|
||||
this->fifoVector = other.fifoVector;
|
||||
this->setContainer(fifoVector.data());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Custom assignment operator
|
||||
* @details This is a very heavy operation so try to avoid this!
|
||||
* @param other DyamicFIFO to copy from
|
||||
*/
|
||||
DynamicFIFO& operator=(const DynamicFIFO& other){
|
||||
FIFOBase<T>::operator=(other);
|
||||
this->fifoVector = other.fifoVector;
|
||||
this->setContainer(fifoVector.data());
|
||||
return *this;
|
||||
}
|
||||
private:
|
||||
std::vector<T> fifoVector;
|
||||
/**
|
||||
* @brief Custom assignment operator
|
||||
* @details This is a very heavy operation so try to avoid this!
|
||||
* @param other DyamicFIFO to copy from
|
||||
*/
|
||||
DynamicFIFO& operator=(const DynamicFIFO& other) {
|
||||
FIFOBase<T>::operator=(other);
|
||||
this->fifoVector = other.fifoVector;
|
||||
this->setContainer(fifoVector.data());
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<T> fifoVector;
|
||||
};
|
||||
|
||||
#endif /* FSFW_CONTAINER_DYNAMICFIFO_H_ */
|
||||
|
@ -1,9 +1,10 @@
|
||||
#ifndef FSFW_CONTAINER_FIFO_H_
|
||||
#define FSFW_CONTAINER_FIFO_H_
|
||||
|
||||
#include "FIFOBase.h"
|
||||
#include <array>
|
||||
|
||||
#include "FIFOBase.h"
|
||||
|
||||
/**
|
||||
* @brief Simple First-In-First-Out data structure with size fixed at
|
||||
* compile time
|
||||
@ -13,35 +14,33 @@
|
||||
* @tparam T Entry Type
|
||||
* @tparam capacity Maximum capacity
|
||||
*/
|
||||
template<typename T, size_t capacity>
|
||||
class FIFO: public FIFOBase<T> {
|
||||
public:
|
||||
FIFO(): FIFOBase<T>(nullptr, capacity) {
|
||||
this->setContainer(fifoArray.data());
|
||||
};
|
||||
template <typename T, size_t capacity>
|
||||
class FIFO : public FIFOBase<T> {
|
||||
public:
|
||||
FIFO() : FIFOBase<T>(nullptr, capacity) { this->setContainer(fifoArray.data()); };
|
||||
|
||||
/**
|
||||
* @brief Custom copy constructor to set pointer correctly.
|
||||
* @param other
|
||||
*/
|
||||
FIFO(const FIFO& other): FIFOBase<T>(other) {
|
||||
this->fifoArray = other.fifoArray;
|
||||
this->setContainer(fifoArray.data());
|
||||
}
|
||||
/**
|
||||
* @brief Custom copy constructor to set pointer correctly.
|
||||
* @param other
|
||||
*/
|
||||
FIFO(const FIFO& other) : FIFOBase<T>(other) {
|
||||
this->fifoArray = other.fifoArray;
|
||||
this->setContainer(fifoArray.data());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Custom assignment operator
|
||||
* @param other
|
||||
*/
|
||||
FIFO& operator=(const FIFO& other){
|
||||
FIFOBase<T>::operator=(other);
|
||||
this->fifoArray = other.fifoArray;
|
||||
this->setContainer(fifoArray.data());
|
||||
return *this;
|
||||
}
|
||||
/**
|
||||
* @brief Custom assignment operator
|
||||
* @param other
|
||||
*/
|
||||
FIFO& operator=(const FIFO& other) {
|
||||
FIFOBase<T>::operator=(other);
|
||||
this->fifoArray = other.fifoArray;
|
||||
this->setContainer(fifoArray.data());
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<T, capacity> fifoArray;
|
||||
private:
|
||||
std::array<T, capacity> fifoArray;
|
||||
};
|
||||
|
||||
#endif /* FSFW_CONTAINER_FIFO_H_ */
|
||||
|
@ -1,77 +1,78 @@
|
||||
#ifndef FSFW_CONTAINER_FIFOBASE_H_
|
||||
#define FSFW_CONTAINER_FIFOBASE_H_
|
||||
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
template <typename T>
|
||||
class FIFOBase {
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::FIFO_CLASS;
|
||||
static const ReturnValue_t FULL = MAKE_RETURN_CODE(1);
|
||||
static const ReturnValue_t EMPTY = MAKE_RETURN_CODE(2);
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::FIFO_CLASS;
|
||||
static const ReturnValue_t FULL = MAKE_RETURN_CODE(1);
|
||||
static const ReturnValue_t EMPTY = MAKE_RETURN_CODE(2);
|
||||
|
||||
/** Default ctor, takes pointer to first entry of underlying container
|
||||
* and maximum capacity */
|
||||
FIFOBase(T* values, const size_t maxCapacity);
|
||||
/** Default ctor, takes pointer to first entry of underlying container
|
||||
* and maximum capacity */
|
||||
FIFOBase(T* values, const size_t maxCapacity);
|
||||
|
||||
/**
|
||||
* Insert value into FIFO
|
||||
* @param value
|
||||
* @return RETURN_OK on success, FULL if full
|
||||
*/
|
||||
ReturnValue_t insert(T value);
|
||||
/**
|
||||
* Retrieve item from FIFO. This removes the item from the FIFO.
|
||||
* @param value Must point to a valid T
|
||||
* @return RETURN_OK on success, EMPTY if empty and FAILED if nullptr check failed
|
||||
*/
|
||||
ReturnValue_t retrieve(T *value);
|
||||
/**
|
||||
* Retrieve item from FIFO without removing it from FIFO.
|
||||
* @param value Must point to a valid T
|
||||
* @return RETURN_OK on success, EMPTY if empty and FAILED if nullptr check failed
|
||||
*/
|
||||
ReturnValue_t peek(T * value);
|
||||
/**
|
||||
* Remove item from FIFO.
|
||||
* @return RETURN_OK on success, EMPTY if empty
|
||||
*/
|
||||
ReturnValue_t pop();
|
||||
/**
|
||||
* Insert value into FIFO
|
||||
* @param value
|
||||
* @return RETURN_OK on success, FULL if full
|
||||
*/
|
||||
ReturnValue_t insert(T value);
|
||||
/**
|
||||
* Retrieve item from FIFO. This removes the item from the FIFO.
|
||||
* @param value Must point to a valid T
|
||||
* @return RETURN_OK on success, EMPTY if empty and FAILED if nullptr check failed
|
||||
*/
|
||||
ReturnValue_t retrieve(T* value);
|
||||
/**
|
||||
* Retrieve item from FIFO without removing it from FIFO.
|
||||
* @param value Must point to a valid T
|
||||
* @return RETURN_OK on success, EMPTY if empty and FAILED if nullptr check failed
|
||||
*/
|
||||
ReturnValue_t peek(T* value);
|
||||
/**
|
||||
* Remove item from FIFO.
|
||||
* @return RETURN_OK on success, EMPTY if empty
|
||||
*/
|
||||
ReturnValue_t pop();
|
||||
|
||||
/***
|
||||
* Check if FIFO is empty
|
||||
* @return True if empty, False if not
|
||||
*/
|
||||
bool empty();
|
||||
/***
|
||||
* Check if FIFO is Full
|
||||
* @return True if full, False if not
|
||||
*/
|
||||
bool full();
|
||||
/***
|
||||
* Current used size (elements) used
|
||||
* @return size_t in elements
|
||||
*/
|
||||
size_t size();
|
||||
/***
|
||||
* Get maximal capacity of fifo
|
||||
* @return size_t with max capacity of this fifo
|
||||
*/
|
||||
size_t getMaxCapacity() const;
|
||||
/***
|
||||
* Check if FIFO is empty
|
||||
* @return True if empty, False if not
|
||||
*/
|
||||
bool empty();
|
||||
/***
|
||||
* Check if FIFO is Full
|
||||
* @return True if full, False if not
|
||||
*/
|
||||
bool full();
|
||||
/***
|
||||
* Current used size (elements) used
|
||||
* @return size_t in elements
|
||||
*/
|
||||
size_t size();
|
||||
/***
|
||||
* Get maximal capacity of fifo
|
||||
* @return size_t with max capacity of this fifo
|
||||
*/
|
||||
size_t getMaxCapacity() const;
|
||||
|
||||
protected:
|
||||
void setContainer(T* data);
|
||||
size_t maxCapacity = 0;
|
||||
protected:
|
||||
void setContainer(T* data);
|
||||
size_t maxCapacity = 0;
|
||||
|
||||
T* values;
|
||||
T* values;
|
||||
|
||||
size_t readIndex = 0;
|
||||
size_t writeIndex = 0;
|
||||
size_t currentSize = 0;
|
||||
size_t readIndex = 0;
|
||||
size_t writeIndex = 0;
|
||||
size_t currentSize = 0;
|
||||
|
||||
size_t next(size_t current);
|
||||
size_t next(size_t current);
|
||||
};
|
||||
|
||||
#include "FIFOBase.tpp"
|
||||
|
@ -1,40 +1,38 @@
|
||||
#ifndef FIXEDARRAYLIST_H_
|
||||
#define FIXEDARRAYLIST_H_
|
||||
|
||||
#include "ArrayList.h"
|
||||
#include <cmath>
|
||||
|
||||
#include "ArrayList.h"
|
||||
/**
|
||||
* \ingroup container
|
||||
*/
|
||||
template<typename T, size_t MAX_SIZE, typename count_t = uint8_t>
|
||||
class FixedArrayList: public ArrayList<T, count_t> {
|
||||
template <typename T, size_t MAX_SIZE, typename count_t = uint8_t>
|
||||
class FixedArrayList : public ArrayList<T, count_t> {
|
||||
#if !defined(_MSC_VER)
|
||||
static_assert(MAX_SIZE <= (std::pow(2,sizeof(count_t)*8)-1), "count_t is not large enough to hold MAX_SIZE");
|
||||
static_assert(MAX_SIZE <= (std::pow(2, sizeof(count_t) * 8) - 1),
|
||||
"count_t is not large enough to hold MAX_SIZE");
|
||||
#endif
|
||||
private:
|
||||
T data[MAX_SIZE];
|
||||
public:
|
||||
FixedArrayList() :
|
||||
ArrayList<T, count_t>(data, MAX_SIZE) {
|
||||
}
|
||||
private:
|
||||
T data[MAX_SIZE];
|
||||
|
||||
FixedArrayList(const FixedArrayList& other) :
|
||||
ArrayList<T, count_t>(data, MAX_SIZE) {
|
||||
memcpy(this->data, other.data, sizeof(this->data));
|
||||
this->entries = data;
|
||||
this->size = other.size;
|
||||
}
|
||||
public:
|
||||
FixedArrayList() : ArrayList<T, count_t>(data, MAX_SIZE) {}
|
||||
|
||||
FixedArrayList& operator=(FixedArrayList other) {
|
||||
memcpy(this->data, other.data, sizeof(this->data));
|
||||
this->entries = data;
|
||||
this->size = other.size;
|
||||
return *this;
|
||||
}
|
||||
FixedArrayList(const FixedArrayList& other) : ArrayList<T, count_t>(data, MAX_SIZE) {
|
||||
memcpy(this->data, other.data, sizeof(this->data));
|
||||
this->entries = data;
|
||||
this->size = other.size;
|
||||
}
|
||||
|
||||
virtual ~FixedArrayList() {
|
||||
}
|
||||
FixedArrayList& operator=(FixedArrayList other) {
|
||||
memcpy(this->data, other.data, sizeof(this->data));
|
||||
this->entries = data;
|
||||
this->size = other.size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual ~FixedArrayList() {}
|
||||
};
|
||||
|
||||
#endif /* FIXEDARRAYLIST_H_ */
|
||||
|
@ -1,10 +1,11 @@
|
||||
#ifndef FSFW_CONTAINER_FIXEDMAP_H_
|
||||
#define FSFW_CONTAINER_FIXEDMAP_H_
|
||||
|
||||
#include "ArrayList.h"
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
#include "ArrayList.h"
|
||||
|
||||
/**
|
||||
* @brief Map implementation for maps with a pre-defined size.
|
||||
@ -16,215 +17,191 @@
|
||||
* @warning A User is not allowed to change the key, otherwise the map is corrupted.
|
||||
* @ingroup container
|
||||
*/
|
||||
template<typename key_t, typename T>
|
||||
class FixedMap: public SerializeIF {
|
||||
static_assert (std::is_trivially_copyable<T>::value or
|
||||
std::is_base_of<SerializeIF, T>::value,
|
||||
"Types used in FixedMap must either be trivial copy-able or a "
|
||||
"derived class from SerializeIF to be serialize-able");
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MAP;
|
||||
static const ReturnValue_t KEY_ALREADY_EXISTS = MAKE_RETURN_CODE(0x01);
|
||||
static const ReturnValue_t MAP_FULL = MAKE_RETURN_CODE(0x02);
|
||||
static const ReturnValue_t KEY_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x03);
|
||||
template <typename key_t, typename T>
|
||||
class FixedMap : public SerializeIF {
|
||||
static_assert(std::is_trivially_copyable<T>::value or std::is_base_of<SerializeIF, T>::value,
|
||||
"Types used in FixedMap must either be trivial copy-able or a "
|
||||
"derived class from SerializeIF to be serialize-able");
|
||||
|
||||
private:
|
||||
static const key_t EMPTY_SLOT = -1;
|
||||
ArrayList<std::pair<key_t, T>, uint32_t> theMap;
|
||||
uint32_t _size;
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MAP;
|
||||
static const ReturnValue_t KEY_ALREADY_EXISTS = MAKE_RETURN_CODE(0x01);
|
||||
static const ReturnValue_t MAP_FULL = MAKE_RETURN_CODE(0x02);
|
||||
static const ReturnValue_t KEY_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x03);
|
||||
|
||||
uint32_t findIndex(key_t key) const {
|
||||
if (_size == 0) {
|
||||
return 1;
|
||||
}
|
||||
uint32_t i = 0;
|
||||
for (i = 0; i < _size; ++i) {
|
||||
if (theMap[i].first == key) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
private:
|
||||
static const key_t EMPTY_SLOT = -1;
|
||||
ArrayList<std::pair<key_t, T>, uint32_t> theMap;
|
||||
uint32_t _size;
|
||||
|
||||
uint32_t findIndex(key_t key) const {
|
||||
if (_size == 0) {
|
||||
return 1;
|
||||
}
|
||||
uint32_t i = 0;
|
||||
for (i = 0; i < _size; ++i) {
|
||||
if (theMap[i].first == key) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
public:
|
||||
FixedMap(uint32_t maxSize) :
|
||||
theMap(maxSize), _size(0) {
|
||||
return i;
|
||||
}
|
||||
|
||||
public:
|
||||
FixedMap(uint32_t maxSize) : theMap(maxSize), _size(0) {}
|
||||
|
||||
class Iterator : public ArrayList<std::pair<key_t, T>, uint32_t>::Iterator {
|
||||
public:
|
||||
Iterator() : ArrayList<std::pair<key_t, T>, uint32_t>::Iterator() {}
|
||||
|
||||
Iterator(std::pair<key_t, T>* pair)
|
||||
: ArrayList<std::pair<key_t, T>, uint32_t>::Iterator(pair) {}
|
||||
};
|
||||
|
||||
friend bool operator==(const typename FixedMap::Iterator& lhs,
|
||||
const typename FixedMap::Iterator& rhs) {
|
||||
return (lhs.value == rhs.value);
|
||||
}
|
||||
|
||||
friend bool operator!=(const typename FixedMap::Iterator& lhs,
|
||||
const typename FixedMap::Iterator& rhs) {
|
||||
return not(lhs.value == rhs.value);
|
||||
}
|
||||
|
||||
Iterator begin() const { return Iterator(&theMap[0]); }
|
||||
|
||||
Iterator end() const { return Iterator(&theMap[_size]); }
|
||||
|
||||
uint32_t size() const { return _size; }
|
||||
|
||||
ReturnValue_t insert(key_t key, T value, Iterator* storedValue = nullptr) {
|
||||
if (exists(key) == HasReturnvaluesIF::RETURN_OK) {
|
||||
return KEY_ALREADY_EXISTS;
|
||||
}
|
||||
if (_size == theMap.maxSize()) {
|
||||
return MAP_FULL;
|
||||
}
|
||||
theMap[_size].first = key;
|
||||
theMap[_size].second = value;
|
||||
if (storedValue != nullptr) {
|
||||
*storedValue = Iterator(&theMap[_size]);
|
||||
}
|
||||
++_size;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t insert(std::pair<key_t, T> pair) { return insert(pair.first, pair.second); }
|
||||
|
||||
ReturnValue_t exists(key_t key) const {
|
||||
ReturnValue_t result = KEY_DOES_NOT_EXIST;
|
||||
if (findIndex(key) < _size) {
|
||||
result = HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t erase(Iterator* iter) {
|
||||
uint32_t i;
|
||||
if ((i = findIndex((*iter).value->first)) >= _size) {
|
||||
return KEY_DOES_NOT_EXIST;
|
||||
}
|
||||
theMap[i] = theMap[_size - 1];
|
||||
--_size;
|
||||
--((*iter).value);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t erase(key_t key) {
|
||||
uint32_t i;
|
||||
if ((i = findIndex(key)) >= _size) {
|
||||
return KEY_DOES_NOT_EXIST;
|
||||
}
|
||||
theMap[i] = theMap[_size - 1];
|
||||
--_size;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
T* findValue(key_t key) const { return &theMap[findIndex(key)].second; }
|
||||
|
||||
Iterator find(key_t key) const {
|
||||
ReturnValue_t result = exists(key);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return end();
|
||||
}
|
||||
return Iterator(&theMap[findIndex(key)]);
|
||||
}
|
||||
|
||||
ReturnValue_t find(key_t key, T** value) const {
|
||||
ReturnValue_t result = exists(key);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
*value = &theMap[findIndex(key)].second;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
bool empty() {
|
||||
if (_size == 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool full() {
|
||||
if (_size >= theMap.maxSize()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void clear() { _size = 0; }
|
||||
|
||||
uint32_t maxSize() const { return theMap.maxSize(); }
|
||||
|
||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result =
|
||||
SerializeAdapter::serialize(&this->_size, buffer, size, maxSize, streamEndianness);
|
||||
uint32_t i = 0;
|
||||
while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) {
|
||||
result =
|
||||
SerializeAdapter::serialize(&theMap[i].first, buffer, size, maxSize, streamEndianness);
|
||||
result =
|
||||
SerializeAdapter::serialize(&theMap[i].second, buffer, size, maxSize, streamEndianness);
|
||||
++i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual size_t getSerializedSize() const {
|
||||
uint32_t printSize = sizeof(_size);
|
||||
uint32_t i = 0;
|
||||
|
||||
for (i = 0; i < _size; ++i) {
|
||||
printSize += SerializeAdapter::getSerializedSize(&theMap[i].first);
|
||||
printSize += SerializeAdapter::getSerializedSize(&theMap[i].second);
|
||||
}
|
||||
|
||||
class Iterator: public ArrayList<std::pair<key_t, T>, uint32_t>::Iterator {
|
||||
public:
|
||||
Iterator() :
|
||||
ArrayList<std::pair<key_t, T>, uint32_t>::Iterator() {
|
||||
}
|
||||
return printSize;
|
||||
}
|
||||
|
||||
Iterator(std::pair<key_t, T> *pair) :
|
||||
ArrayList<std::pair<key_t, T>, uint32_t>::Iterator(pair) {
|
||||
}
|
||||
};
|
||||
|
||||
friend bool operator==(const typename FixedMap::Iterator& lhs,
|
||||
const typename FixedMap::Iterator& rhs) {
|
||||
return (lhs.value == rhs.value);
|
||||
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
Endianness streamEndianness) {
|
||||
ReturnValue_t result =
|
||||
SerializeAdapter::deSerialize(&this->_size, buffer, size, streamEndianness);
|
||||
if (this->_size > theMap.maxSize()) {
|
||||
return SerializeIF::TOO_MANY_ELEMENTS;
|
||||
}
|
||||
|
||||
friend bool operator!=(const typename FixedMap::Iterator& lhs,
|
||||
const typename FixedMap::Iterator& rhs) {
|
||||
return not (lhs.value == rhs.value);
|
||||
uint32_t i = 0;
|
||||
while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) {
|
||||
result = SerializeAdapter::deSerialize(&theMap[i].first, buffer, size, streamEndianness);
|
||||
result = SerializeAdapter::deSerialize(&theMap[i].second, buffer, size, streamEndianness);
|
||||
++i;
|
||||
}
|
||||
|
||||
Iterator begin() const {
|
||||
return Iterator(&theMap[0]);
|
||||
}
|
||||
|
||||
Iterator end() const {
|
||||
return Iterator(&theMap[_size]);
|
||||
}
|
||||
|
||||
uint32_t size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
ReturnValue_t insert(key_t key, T value, Iterator *storedValue = nullptr) {
|
||||
if (exists(key) == HasReturnvaluesIF::RETURN_OK) {
|
||||
return KEY_ALREADY_EXISTS;
|
||||
}
|
||||
if (_size == theMap.maxSize()) {
|
||||
return MAP_FULL;
|
||||
}
|
||||
theMap[_size].first = key;
|
||||
theMap[_size].second = value;
|
||||
if (storedValue != nullptr) {
|
||||
*storedValue = Iterator(&theMap[_size]);
|
||||
}
|
||||
++_size;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t insert(std::pair<key_t, T> pair) {
|
||||
return insert(pair.first, pair.second);
|
||||
}
|
||||
|
||||
ReturnValue_t exists(key_t key) const {
|
||||
ReturnValue_t result = KEY_DOES_NOT_EXIST;
|
||||
if (findIndex(key) < _size) {
|
||||
result = HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t erase(Iterator *iter) {
|
||||
uint32_t i;
|
||||
if ((i = findIndex((*iter).value->first)) >= _size) {
|
||||
return KEY_DOES_NOT_EXIST;
|
||||
}
|
||||
theMap[i] = theMap[_size - 1];
|
||||
--_size;
|
||||
--((*iter).value);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t erase(key_t key) {
|
||||
uint32_t i;
|
||||
if ((i = findIndex(key)) >= _size) {
|
||||
return KEY_DOES_NOT_EXIST;
|
||||
}
|
||||
theMap[i] = theMap[_size - 1];
|
||||
--_size;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
T *findValue(key_t key) const {
|
||||
return &theMap[findIndex(key)].second;
|
||||
}
|
||||
|
||||
Iterator find(key_t key) const {
|
||||
ReturnValue_t result = exists(key);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return end();
|
||||
}
|
||||
return Iterator(&theMap[findIndex(key)]);
|
||||
}
|
||||
|
||||
ReturnValue_t find(key_t key, T **value) const {
|
||||
ReturnValue_t result = exists(key);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
*value = &theMap[findIndex(key)].second;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
bool empty() {
|
||||
if(_size == 0) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool full() {
|
||||
if(_size >= theMap.maxSize()) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void clear() {
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
uint32_t maxSize() const {
|
||||
return theMap.maxSize();
|
||||
}
|
||||
|
||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
|
||||
size_t maxSize, Endianness streamEndianness) const {
|
||||
ReturnValue_t result = SerializeAdapter::serialize(&this->_size,
|
||||
buffer, size, maxSize, streamEndianness);
|
||||
uint32_t i = 0;
|
||||
while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) {
|
||||
result = SerializeAdapter::serialize(&theMap[i].first, buffer,
|
||||
size, maxSize, streamEndianness);
|
||||
result = SerializeAdapter::serialize(&theMap[i].second, buffer, size,
|
||||
maxSize, streamEndianness);
|
||||
++i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual size_t getSerializedSize() const {
|
||||
uint32_t printSize = sizeof(_size);
|
||||
uint32_t i = 0;
|
||||
|
||||
for (i = 0; i < _size; ++i) {
|
||||
printSize += SerializeAdapter::getSerializedSize(
|
||||
&theMap[i].first);
|
||||
printSize += SerializeAdapter::getSerializedSize(&theMap[i].second);
|
||||
}
|
||||
|
||||
return printSize;
|
||||
}
|
||||
|
||||
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
Endianness streamEndianness) {
|
||||
ReturnValue_t result = SerializeAdapter::deSerialize(&this->_size,
|
||||
buffer, size, streamEndianness);
|
||||
if (this->_size > theMap.maxSize()) {
|
||||
return SerializeIF::TOO_MANY_ELEMENTS;
|
||||
}
|
||||
uint32_t i = 0;
|
||||
while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) {
|
||||
result = SerializeAdapter::deSerialize(&theMap[i].first, buffer,
|
||||
size, streamEndianness);
|
||||
result = SerializeAdapter::deSerialize(&theMap[i].second, buffer, size,
|
||||
streamEndianness);
|
||||
++i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* FSFW_CONTAINER_FIXEDMAP_H_ */
|
||||
|
@ -1,10 +1,11 @@
|
||||
#ifndef FSFW_CONTAINER_FIXEDORDEREDMULTIMAP_H_
|
||||
#define FSFW_CONTAINER_FIXEDORDEREDMULTIMAP_H_
|
||||
|
||||
#include "ArrayList.h"
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
|
||||
#include "ArrayList.h"
|
||||
|
||||
/**
|
||||
* @brief An associative container which allows multiple entries of the same key.
|
||||
* @details
|
||||
@ -31,175 +32,160 @@
|
||||
*
|
||||
* \ingroup container
|
||||
*/
|
||||
template<typename key_t, typename T, typename KEY_COMPARE = std::less<key_t>>
|
||||
template <typename key_t, typename T, typename KEY_COMPARE = std::less<key_t>>
|
||||
class FixedOrderedMultimap {
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MULTIMAP;
|
||||
static const ReturnValue_t MAP_FULL = MAKE_RETURN_CODE(0x01);
|
||||
static const ReturnValue_t KEY_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x02);
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MULTIMAP;
|
||||
static const ReturnValue_t MAP_FULL = MAKE_RETURN_CODE(0x01);
|
||||
static const ReturnValue_t KEY_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x02);
|
||||
|
||||
/***
|
||||
* Constructor which needs a size_t for the maximum allowed size
|
||||
*
|
||||
* Can not be resized during runtime
|
||||
*
|
||||
* Allocates memory at construction
|
||||
* @param maxSize size_t of Maximum allowed size
|
||||
*/
|
||||
FixedOrderedMultimap(size_t maxSize):theMap(maxSize), _size(0){
|
||||
/***
|
||||
* Constructor which needs a size_t for the maximum allowed size
|
||||
*
|
||||
* Can not be resized during runtime
|
||||
*
|
||||
* Allocates memory at construction
|
||||
* @param maxSize size_t of Maximum allowed size
|
||||
*/
|
||||
FixedOrderedMultimap(size_t maxSize) : theMap(maxSize), _size(0) {}
|
||||
|
||||
/***
|
||||
* Virtual destructor frees Memory by deleting its member
|
||||
*/
|
||||
virtual ~FixedOrderedMultimap() {}
|
||||
|
||||
/***
|
||||
* Special iterator for FixedOrderedMultimap
|
||||
*/
|
||||
class Iterator : public ArrayList<std::pair<key_t, T>, size_t>::Iterator {
|
||||
public:
|
||||
Iterator() : ArrayList<std::pair<key_t, T>, size_t>::Iterator() {}
|
||||
|
||||
Iterator(std::pair<key_t, T>* pair) : ArrayList<std::pair<key_t, T>, size_t>::Iterator(pair) {}
|
||||
};
|
||||
|
||||
/***
|
||||
* Returns an iterator pointing to the first element
|
||||
* @return Iterator pointing to first element
|
||||
*/
|
||||
Iterator begin() const { return Iterator(&theMap[0]); }
|
||||
|
||||
/**
|
||||
* Returns an iterator pointing to one element past the end
|
||||
* @return Iterator pointing to one element past the end
|
||||
*/
|
||||
Iterator end() const { return Iterator(&theMap[_size]); }
|
||||
|
||||
/***
|
||||
* Returns the current size of the map (not maximum size!)
|
||||
* @return Current size
|
||||
*/
|
||||
size_t size() const { return _size; }
|
||||
|
||||
/**
|
||||
* Clears the map, does not deallocate any memory
|
||||
*/
|
||||
void clear() { _size = 0; }
|
||||
|
||||
/**
|
||||
* Returns the maximum size of the map
|
||||
* @return Maximum size of the map
|
||||
*/
|
||||
size_t maxSize() const { return theMap.maxSize(); }
|
||||
|
||||
/***
|
||||
* Used to insert a key and value separately.
|
||||
*
|
||||
* @param[in] key Key of the new element
|
||||
* @param[in] value Value of the new element
|
||||
* @param[in/out] (optional) storedValue On success this points to the new value, otherwise a
|
||||
* nullptr
|
||||
* @return RETURN_OK if insert was successful, MAP_FULL if no space is available
|
||||
*/
|
||||
ReturnValue_t insert(key_t key, T value, Iterator* storedValue = nullptr);
|
||||
|
||||
/***
|
||||
* Used to insert new pair instead of single values
|
||||
*
|
||||
* @param pair Pair to be inserted
|
||||
* @return RETURN_OK if insert was successful, MAP_FULL if no space is available
|
||||
*/
|
||||
ReturnValue_t insert(std::pair<key_t, T> pair);
|
||||
|
||||
/***
|
||||
* Can be used to check if a certain key is in the map
|
||||
* @param key Key to be checked
|
||||
* @return RETURN_OK if the key exists KEY_DOES_NOT_EXIST otherwise
|
||||
*/
|
||||
ReturnValue_t exists(key_t key) const;
|
||||
|
||||
/***
|
||||
* Used to delete the element in the iterator
|
||||
*
|
||||
* The iterator will point to the element before or begin(),
|
||||
* but never to one element in front of the map.
|
||||
*
|
||||
* @warning The iterator needs to be valid and dereferenceable
|
||||
* @param[in/out] iter Pointer to iterator to the element that needs to be ereased
|
||||
* @return RETURN_OK if erased, KEY_DOES_NOT_EXIST if the there is no element like this
|
||||
*/
|
||||
ReturnValue_t erase(Iterator* iter);
|
||||
|
||||
/***
|
||||
* Used to erase by key
|
||||
* @param key Key to be erased
|
||||
* @return RETURN_OK if erased, KEY_DOES_NOT_EXIST if the there is no element like this
|
||||
*/
|
||||
ReturnValue_t erase(key_t key);
|
||||
|
||||
/***
|
||||
* Find returns the first appearance of the key
|
||||
*
|
||||
* If the key does not exist, it points to end()
|
||||
*
|
||||
* @param key Key to search for
|
||||
* @return Iterator pointing to the first entry of key
|
||||
*/
|
||||
Iterator find(key_t key) const {
|
||||
ReturnValue_t result = exists(key);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return end();
|
||||
}
|
||||
return Iterator(&theMap[findFirstIndex(key)]);
|
||||
};
|
||||
|
||||
/***
|
||||
* Virtual destructor frees Memory by deleting its member
|
||||
*/
|
||||
virtual ~FixedOrderedMultimap() {
|
||||
}
|
||||
/***
|
||||
* Finds first entry of the given key and returns a
|
||||
* pointer to the value
|
||||
*
|
||||
* @param key Key to search for
|
||||
* @param value Found value
|
||||
* @return RETURN_OK if it points to the value,
|
||||
* KEY_DOES_NOT_EXIST if the key is not in the map
|
||||
*/
|
||||
ReturnValue_t find(key_t key, T** value) const;
|
||||
|
||||
/***
|
||||
* Special iterator for FixedOrderedMultimap
|
||||
*/
|
||||
class Iterator: public ArrayList<std::pair<key_t, T>, size_t>::Iterator {
|
||||
public:
|
||||
Iterator() :
|
||||
ArrayList<std::pair<key_t, T>, size_t>::Iterator() {
|
||||
}
|
||||
friend bool operator==(const typename FixedOrderedMultimap::Iterator& lhs,
|
||||
const typename FixedOrderedMultimap::Iterator& rhs) {
|
||||
return (lhs.value == rhs.value);
|
||||
}
|
||||
|
||||
Iterator(std::pair<key_t, T> *pair) :
|
||||
ArrayList<std::pair<key_t, T>, size_t>::Iterator(pair) {
|
||||
}
|
||||
};
|
||||
friend bool operator!=(const typename FixedOrderedMultimap::Iterator& lhs,
|
||||
const typename FixedOrderedMultimap::Iterator& rhs) {
|
||||
return not(lhs.value == rhs.value);
|
||||
}
|
||||
|
||||
/***
|
||||
* Returns an iterator pointing to the first element
|
||||
* @return Iterator pointing to first element
|
||||
*/
|
||||
Iterator begin() const {
|
||||
return Iterator(&theMap[0]);
|
||||
}
|
||||
private:
|
||||
typedef KEY_COMPARE compare;
|
||||
compare myComp;
|
||||
ArrayList<std::pair<key_t, T>, size_t> theMap;
|
||||
size_t _size;
|
||||
|
||||
/**
|
||||
* Returns an iterator pointing to one element past the end
|
||||
* @return Iterator pointing to one element past the end
|
||||
*/
|
||||
Iterator end() const {
|
||||
return Iterator(&theMap[_size]);
|
||||
}
|
||||
size_t findFirstIndex(key_t key, size_t startAt = 0) const;
|
||||
|
||||
/***
|
||||
* Returns the current size of the map (not maximum size!)
|
||||
* @return Current size
|
||||
*/
|
||||
size_t size() const{
|
||||
return _size;
|
||||
}
|
||||
size_t findNicePlace(key_t key) const;
|
||||
|
||||
/**
|
||||
* Clears the map, does not deallocate any memory
|
||||
*/
|
||||
void clear(){
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum size of the map
|
||||
* @return Maximum size of the map
|
||||
*/
|
||||
size_t maxSize() const{
|
||||
return theMap.maxSize();
|
||||
}
|
||||
|
||||
/***
|
||||
* Used to insert a key and value separately.
|
||||
*
|
||||
* @param[in] key Key of the new element
|
||||
* @param[in] value Value of the new element
|
||||
* @param[in/out] (optional) storedValue On success this points to the new value, otherwise a nullptr
|
||||
* @return RETURN_OK if insert was successful, MAP_FULL if no space is available
|
||||
*/
|
||||
ReturnValue_t insert(key_t key, T value, Iterator *storedValue = nullptr);
|
||||
|
||||
/***
|
||||
* Used to insert new pair instead of single values
|
||||
*
|
||||
* @param pair Pair to be inserted
|
||||
* @return RETURN_OK if insert was successful, MAP_FULL if no space is available
|
||||
*/
|
||||
ReturnValue_t insert(std::pair<key_t, T> pair);
|
||||
|
||||
/***
|
||||
* Can be used to check if a certain key is in the map
|
||||
* @param key Key to be checked
|
||||
* @return RETURN_OK if the key exists KEY_DOES_NOT_EXIST otherwise
|
||||
*/
|
||||
ReturnValue_t exists(key_t key) const;
|
||||
|
||||
/***
|
||||
* Used to delete the element in the iterator
|
||||
*
|
||||
* The iterator will point to the element before or begin(),
|
||||
* but never to one element in front of the map.
|
||||
*
|
||||
* @warning The iterator needs to be valid and dereferenceable
|
||||
* @param[in/out] iter Pointer to iterator to the element that needs to be ereased
|
||||
* @return RETURN_OK if erased, KEY_DOES_NOT_EXIST if the there is no element like this
|
||||
*/
|
||||
ReturnValue_t erase(Iterator *iter);
|
||||
|
||||
/***
|
||||
* Used to erase by key
|
||||
* @param key Key to be erased
|
||||
* @return RETURN_OK if erased, KEY_DOES_NOT_EXIST if the there is no element like this
|
||||
*/
|
||||
ReturnValue_t erase(key_t key);
|
||||
|
||||
/***
|
||||
* Find returns the first appearance of the key
|
||||
*
|
||||
* If the key does not exist, it points to end()
|
||||
*
|
||||
* @param key Key to search for
|
||||
* @return Iterator pointing to the first entry of key
|
||||
*/
|
||||
Iterator find(key_t key) const{
|
||||
ReturnValue_t result = exists(key);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return end();
|
||||
}
|
||||
return Iterator(&theMap[findFirstIndex(key)]);
|
||||
};
|
||||
|
||||
/***
|
||||
* Finds first entry of the given key and returns a
|
||||
* pointer to the value
|
||||
*
|
||||
* @param key Key to search for
|
||||
* @param value Found value
|
||||
* @return RETURN_OK if it points to the value,
|
||||
* KEY_DOES_NOT_EXIST if the key is not in the map
|
||||
*/
|
||||
ReturnValue_t find(key_t key, T **value) const;
|
||||
|
||||
friend bool operator==(const typename FixedOrderedMultimap::Iterator& lhs,
|
||||
const typename FixedOrderedMultimap::Iterator& rhs) {
|
||||
return (lhs.value == rhs.value);
|
||||
}
|
||||
|
||||
friend bool operator!=(const typename FixedOrderedMultimap::Iterator& lhs,
|
||||
const typename FixedOrderedMultimap::Iterator& rhs) {
|
||||
return not (lhs.value == rhs.value);
|
||||
}
|
||||
|
||||
private:
|
||||
typedef KEY_COMPARE compare;
|
||||
compare myComp;
|
||||
ArrayList<std::pair<key_t, T>, size_t> theMap;
|
||||
size_t _size;
|
||||
|
||||
size_t findFirstIndex(key_t key, size_t startAt = 0) const;
|
||||
|
||||
size_t findNicePlace(key_t key) const;
|
||||
|
||||
void removeFromPosition(size_t position);
|
||||
void removeFromPosition(size_t position);
|
||||
};
|
||||
|
||||
#include "FixedOrderedMultimap.tpp"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user