Merge pull request 'Added CFDP packet stack' (#528) from KSat/fsfw:mueller/cfdp-pdus into development
Reviewed-on: fsfw/fsfw#528
This commit is contained in:
commit
70b593df65
@ -192,13 +192,13 @@ if(FSFW_BUILD_UNITTESTS)
|
||||
"--exclude-unreachable-branches"
|
||||
)
|
||||
set(COVERAGE_EXCLUDES
|
||||
"/c/msys64/mingw64/*"
|
||||
"/c/msys64/mingw64/*" "*/fsfw_hal/*"
|
||||
)
|
||||
elseif(UNIX)
|
||||
set(COVERAGE_EXCLUDES
|
||||
"/usr/include/*" "/usr/bin/*" "Catch2/*"
|
||||
"/usr/local/include/*" "*/fsfw_tests/*"
|
||||
"*/catch2-src/*"
|
||||
"*/catch2-src/*" "*/fsfw_hal/*"
|
||||
)
|
||||
endif()
|
||||
|
||||
|
@ -91,7 +91,7 @@ You can use the following commands inside the `fsfw` folder to set up the build
|
||||
|
||||
```sh
|
||||
mkdir build-Unittest && cd build-Unittest
|
||||
cmake -DFSFW_BUILD_UNITTESTS=ON -DFSFW_OSAL=host ..
|
||||
cmake -DFSFW_BUILD_UNITTESTS=ON -DFSFW_OSAL=host -DCMAKE_BUILD_TYPE=Debug ..
|
||||
```
|
||||
|
||||
You can also use `-DFSFW_OSAL=linux` on Linux systems.
|
||||
|
@ -10,7 +10,7 @@
|
||||
*/
|
||||
namespace addresses {
|
||||
/* Logical addresses have uint32_t datatype */
|
||||
enum logicalAddresses: address_t {
|
||||
enum LogAddr: address_t {
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
# Core
|
||||
|
||||
add_subdirectory(action)
|
||||
add_subdirectory(cfdp)
|
||||
add_subdirectory(container)
|
||||
add_subdirectory(controller)
|
||||
add_subdirectory(datapool)
|
||||
|
@ -46,6 +46,10 @@
|
||||
#define FSFW_USE_PUS_C_TELECOMMANDS 1
|
||||
#endif
|
||||
|
||||
#ifndef FSFW_TCP_RECV_WIRETAPPING_ENABLED
|
||||
#define FSFW_TCP_RECV_WIRETAPPING_ENABLED 0
|
||||
#endif
|
||||
|
||||
// FSFW HAL defines
|
||||
|
||||
// Can be used for low-level debugging of the SPI bus
|
||||
|
60
src/fsfw/cfdp/CFDPHandler.cpp
Normal file
60
src/fsfw/cfdp/CFDPHandler.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
#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/ipc/QueueFactory.h"
|
||||
#include "fsfw/objectmanager/ObjectManager.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() {}
|
||||
|
||||
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 CFDPHandler::handleRequest(store_address_t storeId) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "CFDPHandler::handleRequest" << std::endl;
|
||||
#else
|
||||
sif::printDebug("CFDPHandler::handleRequest\n");
|
||||
#endif /* !FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||
#endif
|
||||
|
||||
//TODO read out packet from store using storeId
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
uint16_t CFDPHandler::getIdentifier() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
MessageQueueId_t CFDPHandler::getRequestQueue() {
|
||||
return this->requestQueue->getId();
|
||||
}
|
62
src/fsfw/cfdp/CFDPHandler.h
Normal file
62
src/fsfw/cfdp/CFDPHandler.h
Normal file
@ -0,0 +1,62 @@
|
||||
#ifndef FSFW_CFDP_CFDPHANDLER_H_
|
||||
#define FSFW_CFDP_CFDPHANDLER_H_
|
||||
|
||||
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
||||
#include "fsfw/objectmanager/SystemObject.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||
#include "fsfw/tcdistribution/CFDPDistributor.h"
|
||||
|
||||
#include "fsfw/ipc/MessageQueueIF.h"
|
||||
|
||||
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();
|
||||
|
||||
virtual ReturnValue_t handleRequest(store_address_t storeId);
|
||||
|
||||
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;
|
||||
|
||||
CFDPDistributor* distributor = nullptr;
|
||||
|
||||
/**
|
||||
* 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_ */
|
21
src/fsfw/cfdp/CFDPMessage.cpp
Normal file
21
src/fsfw/cfdp/CFDPMessage.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
#include "CFDPMessage.h"
|
||||
|
||||
CFDPMessage::CFDPMessage() {
|
||||
}
|
||||
|
||||
CFDPMessage::~CFDPMessage() {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void CFDPMessage::clear(CommandMessage *message) {
|
||||
}
|
23
src/fsfw/cfdp/CFDPMessage.h
Normal file
23
src/fsfw/cfdp/CFDPMessage.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef FSFW_CFDP_CFDPMESSAGE_H_
|
||||
#define FSFW_CFDP_CFDPMESSAGE_H_
|
||||
|
||||
#include "fsfw/ipc/CommandMessage.h"
|
||||
#include "fsfw/objectmanager/ObjectManagerIF.h"
|
||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||
|
||||
class CFDPMessage {
|
||||
private:
|
||||
CFDPMessage();
|
||||
public:
|
||||
static const uint8_t MESSAGE_ID = messagetypes::CFDP;
|
||||
|
||||
virtual ~CFDPMessage();
|
||||
static void setCommand(CommandMessage* message,
|
||||
store_address_t cfdpPacket);
|
||||
|
||||
static store_address_t getStoreId(const CommandMessage* message);
|
||||
|
||||
static void clear(CommandMessage* message);
|
||||
};
|
||||
|
||||
#endif /* FSFW_CFDP_CFDPMESSAGE_H_ */
|
7
src/fsfw/cfdp/CMakeLists.txt
Normal file
7
src/fsfw/cfdp/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE
|
||||
CFDPHandler.cpp
|
||||
CFDPMessage.cpp
|
||||
)
|
||||
|
||||
add_subdirectory(pdu)
|
||||
add_subdirectory(tlv)
|
83
src/fsfw/cfdp/FileSize.h
Normal file
83
src/fsfw/cfdp/FileSize.h
Normal file
@ -0,0 +1,83 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_FILESIZE_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_FILESIZE_H_
|
||||
|
||||
#include "fsfw/serialize/SerializeAdapter.h"
|
||||
#include "fsfw/serialize/SerializeIF.h"
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
struct FileSize: public SerializeIF {
|
||||
public:
|
||||
FileSize(): largeFile(false) {};
|
||||
|
||||
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(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);
|
||||
}
|
||||
|
||||
size_t getSerializedSize() const override {
|
||||
if (largeFile) {
|
||||
return 8;
|
||||
} else {
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_FILESIZE_H_ */
|
153
src/fsfw/cfdp/definitions.h
Normal file
153
src/fsfw/cfdp/definitions.h
Normal file
@ -0,0 +1,153 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_DEFINITIONS_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_DEFINITIONS_H_
|
||||
|
||||
#include <fsfw/serialize/SerializeIF.h>
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include "fsfw/returnvalues/FwClassIds.h"
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
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);
|
||||
static constexpr ReturnValue_t INVALID_DIRECTIVE_FIELDS =
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 2);
|
||||
static constexpr ReturnValue_t INVALID_PDU_DATAFIELD_LEN =
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 3);
|
||||
static constexpr ReturnValue_t INVALID_ACK_DIRECTIVE_FIELDS =
|
||||
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);
|
||||
static constexpr ReturnValue_t NAK_CANT_PARSE_OPTIONS =
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 6);
|
||||
static constexpr ReturnValue_t FINISHED_CANT_PARSE_FS_RESPONSES =
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 6);
|
||||
static constexpr ReturnValue_t FILESTORE_REQUIRES_SECOND_FILE =
|
||||
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);
|
||||
|
||||
//! 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
|
||||
};
|
||||
|
||||
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 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 AckTransactionStatus {
|
||||
UNDEFINED = 0b00,
|
||||
ACTIVE = 0b01,
|
||||
TERMINATED = 0b10,
|
||||
UNRECOGNIZED = 0b11
|
||||
};
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
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 RecordContinuationState {
|
||||
NO_START_NO_END = 0b00,
|
||||
CONTAINS_START_NO_END = 0b01,
|
||||
CONTAINS_END_NO_START = 0b10,
|
||||
CONTAINS_START_AND_END = 0b11
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_DEFINITIONS_H_ */
|
52
src/fsfw/cfdp/pdu/AckInfo.cpp
Normal file
52
src/fsfw/cfdp/pdu/AckInfo.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
#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::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;
|
||||
}
|
||||
}
|
||||
|
||||
cfdp::FileDirectives AckInfo::getAckedDirective() const {
|
||||
return ackedDirective;
|
||||
}
|
||||
|
||||
void AckInfo::setAckedDirective(cfdp::FileDirectives ackedDirective) {
|
||||
this->ackedDirective = ackedDirective;
|
||||
}
|
||||
|
||||
uint8_t AckInfo::getDirectiveSubtypeCode() const {
|
||||
return directiveSubtypeCode;
|
||||
}
|
||||
|
||||
void AckInfo::setDirectiveSubtypeCode(uint8_t directiveSubtypeCode) {
|
||||
this->directiveSubtypeCode = directiveSubtypeCode;
|
||||
}
|
||||
|
||||
cfdp::AckTransactionStatus AckInfo::getTransactionStatus() const {
|
||||
return transactionStatus;
|
||||
}
|
||||
|
||||
AckInfo::AckInfo() {
|
||||
}
|
||||
|
||||
void AckInfo::setTransactionStatus(cfdp::AckTransactionStatus transactionStatus) {
|
||||
this->transactionStatus = transactionStatus;
|
||||
}
|
33
src/fsfw/cfdp/pdu/AckInfo.h
Normal file
33
src/fsfw/cfdp/pdu/AckInfo.h
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_ACKINFO_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_ACKINFO_H_
|
||||
|
||||
#include "../definitions.h"
|
||||
|
||||
class AckInfo {
|
||||
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::FileDirectives getAckedDirective() const;
|
||||
void setAckedDirective(cfdp::FileDirectives ackedDirective);
|
||||
|
||||
uint8_t getDirectiveSubtypeCode() const;
|
||||
void setDirectiveSubtypeCode(uint8_t directiveSubtypeCode);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_ACKINFO_H_ */
|
38
src/fsfw/cfdp/pdu/AckPduDeserializer.cpp
Normal file
38
src/fsfw/cfdp/pdu/AckPduDeserializer.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
#include "AckPduDeserializer.h"
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool AckPduDeserializer::checkAndSetCodes(uint8_t firstByte, uint8_t secondByte) {
|
||||
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;
|
||||
}
|
26
src/fsfw/cfdp/pdu/AckPduDeserializer.h
Normal file
26
src/fsfw/cfdp/pdu/AckPduDeserializer.h
Normal file
@ -0,0 +1,26 @@
|
||||
#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"
|
||||
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_ACKPDUDESERIALIZER_H_ */
|
38
src/fsfw/cfdp/pdu/AckPduSerializer.cpp
Normal file
38
src/fsfw/cfdp/pdu/AckPduSerializer.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
#include "AckPduSerializer.h"
|
||||
|
||||
AckPduSerializer::AckPduSerializer(AckInfo& ackInfo, PduConfig &pduConf):
|
||||
FileDirectiveSerializer(pduConf, cfdp::FileDirectives::ACK, 2),
|
||||
ackInfo(ackInfo) {
|
||||
}
|
||||
|
||||
size_t AckPduSerializer::getSerializedSize() const {
|
||||
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;
|
||||
}
|
30
src/fsfw/cfdp/pdu/AckPduSerializer.h
Normal file
30
src/fsfw/cfdp/pdu/AckPduSerializer.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_ACKPDUSERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_ACKPDUSERIALIZER_H_
|
||||
|
||||
#include "AckInfo.h"
|
||||
#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);
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
private:
|
||||
AckInfo& ackInfo;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_ACKPDUSERIALIZER_H_ */
|
32
src/fsfw/cfdp/pdu/CMakeLists.txt
Normal file
32
src/fsfw/cfdp/pdu/CMakeLists.txt
Normal file
@ -0,0 +1,32 @@
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE
|
||||
PduConfig.cpp
|
||||
VarLenField.cpp
|
||||
HeaderSerializer.cpp
|
||||
HeaderDeserializer.cpp
|
||||
FileDirectiveDeserializer.cpp
|
||||
FileDirectiveSerializer.cpp
|
||||
|
||||
AckInfo.cpp
|
||||
AckPduSerializer.cpp
|
||||
AckPduDeserializer.cpp
|
||||
EofInfo.cpp
|
||||
EofPduSerializer.cpp
|
||||
EofPduDeserializer.cpp
|
||||
NakInfo.cpp
|
||||
NakPduSerializer.cpp
|
||||
NakPduDeserializer.cpp
|
||||
FinishedInfo.cpp
|
||||
FinishedPduSerializer.cpp
|
||||
FinishedPduDeserializer.cpp
|
||||
MetadataInfo.cpp
|
||||
MetadataPduSerializer.cpp
|
||||
MetadataPduDeserializer.cpp
|
||||
KeepAlivePduSerializer.cpp
|
||||
KeepAlivePduDeserializer.cpp
|
||||
PromptPduSerializer.cpp
|
||||
PromptPduDeserializer.cpp
|
||||
|
||||
FileDataSerializer.cpp
|
||||
FileDataDeserializer.cpp
|
||||
FileDataInfo.cpp
|
||||
)
|
58
src/fsfw/cfdp/pdu/EofInfo.cpp
Normal file
58
src/fsfw/cfdp/pdu/EofInfo.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
#include "EofInfo.h"
|
||||
|
||||
EofInfo::EofInfo(cfdp::ConditionCode conditionCode, uint32_t checksum, cfdp::FileSize fileSize,
|
||||
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) {
|
||||
}
|
||||
|
||||
uint32_t EofInfo::getChecksum() const {
|
||||
return checksum;
|
||||
}
|
||||
|
||||
cfdp::ConditionCode EofInfo::getConditionCode() const {
|
||||
return conditionCode;
|
||||
}
|
||||
|
||||
EntityIdTlv* EofInfo::getFaultLoc() const {
|
||||
return faultLoc;
|
||||
}
|
||||
|
||||
cfdp::FileSize& EofInfo::getFileSize() {
|
||||
return fileSize;
|
||||
}
|
||||
|
||||
void EofInfo::setChecksum(uint32_t checksum) {
|
||||
this->checksum = checksum;
|
||||
}
|
||||
|
||||
void EofInfo::setConditionCode(cfdp::ConditionCode conditionCode) {
|
||||
this->conditionCode = conditionCode;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ReturnValue_t EofInfo::setFileSize(size_t fileSize, bool isLarge) {
|
||||
return this->fileSize.setFileSize(fileSize, isLarge);
|
||||
}
|
33
src/fsfw/cfdp/pdu/EofInfo.h
Normal file
33
src/fsfw/cfdp/pdu/EofInfo.h
Normal file
@ -0,0 +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"
|
||||
|
||||
struct EofInfo {
|
||||
public:
|
||||
EofInfo(EntityIdTlv* faultLoc = nullptr);
|
||||
EofInfo(cfdp::ConditionCode conditionCode, uint32_t checksum, cfdp::FileSize fileSize,
|
||||
EntityIdTlv* faultLoc = nullptr);
|
||||
|
||||
size_t getSerializedSize(bool fssLarge = false);
|
||||
|
||||
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:
|
||||
|
||||
cfdp::ConditionCode conditionCode;
|
||||
uint32_t checksum;
|
||||
cfdp::FileSize fileSize;
|
||||
EntityIdTlv* faultLoc = nullptr;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_EOFINFO_H_ */
|
68
src/fsfw/cfdp/pdu/EofPduDeserializer.cpp
Normal file
68
src/fsfw/cfdp/pdu/EofPduDeserializer.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
#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) {
|
||||
}
|
||||
|
||||
ReturnValue_t EofPduDeserializer::parseData() {
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
#else
|
||||
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 result;
|
||||
}
|
18
src/fsfw/cfdp/pdu/EofPduDeserializer.h
Normal file
18
src/fsfw/cfdp/pdu/EofPduDeserializer.h
Normal file
@ -0,0 +1,18 @@
|
||||
#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"
|
||||
|
||||
class EofPduDeserializer: public FileDirectiveDeserializer {
|
||||
public:
|
||||
EofPduDeserializer(const uint8_t* pduBuf, size_t maxSize, EofInfo& eofInfo);
|
||||
|
||||
virtual ReturnValue_t parseData() override;
|
||||
private:
|
||||
EofInfo& info;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_EOFPDUDESERIALIZER_H_ */
|
46
src/fsfw/cfdp/pdu/EofPduSerializer.cpp
Normal file
46
src/fsfw/cfdp/pdu/EofPduSerializer.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
#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()));
|
||||
}
|
||||
|
||||
size_t EofPduSerializer::getSerializedSize() const {
|
||||
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);
|
||||
}
|
||||
return result;
|
||||
}
|
22
src/fsfw/cfdp/pdu/EofPduSerializer.h
Normal file
22
src/fsfw/cfdp/pdu/EofPduSerializer.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_EOFPDUSERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_EOFPDUSERIALIZER_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);
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
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_ */
|
52
src/fsfw/cfdp/pdu/FileDataDeserializer.cpp
Normal file
52
src/fsfw/cfdp/pdu/FileDataDeserializer.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
#include "FileDataDeserializer.h"
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
SerializeIF::Endianness FileDataDeserializer::getEndianness() const {
|
||||
return endianness;
|
||||
}
|
||||
|
||||
void FileDataDeserializer::setEndianness(SerializeIF::Endianness endianness) {
|
||||
this->endianness = endianness;
|
||||
}
|
22
src/fsfw/cfdp/pdu/FileDataDeserializer.h
Normal file
22
src/fsfw/cfdp/pdu/FileDataDeserializer.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_FILEDATADESERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_FILEDATADESERIALIZER_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);
|
||||
|
||||
ReturnValue_t parseData();
|
||||
SerializeIF::Endianness getEndianness() const;
|
||||
void setEndianness(SerializeIF::Endianness endianness = SerializeIF::Endianness::NETWORK);
|
||||
|
||||
private:
|
||||
|
||||
SerializeIF::Endianness endianness = SerializeIF::Endianness::NETWORK;
|
||||
FileDataInfo& info;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_FILEDATADESERIALIZER_H_ */
|
104
src/fsfw/cfdp/pdu/FileDataInfo.cpp
Normal file
104
src/fsfw/cfdp/pdu/FileDataInfo.cpp
Normal file
@ -0,0 +1,104 @@
|
||||
#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): offset(offset) {
|
||||
}
|
||||
|
||||
void FileDataInfo::setSegmentMetadataFlag(bool enable) {
|
||||
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;
|
||||
}
|
||||
|
||||
cfdp::SegmentMetadataFlag FileDataInfo::getSegmentMetadataFlag() const {
|
||||
return this->segmentMetadataFlag;
|
||||
}
|
||||
|
||||
bool FileDataInfo::hasSegmentMetadata() const {
|
||||
if(segmentMetadataFlag == cfdp::SegmentMetadataFlag::PRESENT) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
cfdp::RecordContinuationState FileDataInfo::getRecordContinuationState() const {
|
||||
return this->recContState;
|
||||
}
|
||||
|
||||
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* 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;
|
||||
}
|
||||
|
||||
cfdp::FileSize& FileDataInfo::getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
void FileDataInfo::setRecordContinuationState(cfdp::RecordContinuationState recContState) {
|
||||
this->recContState = recContState;
|
||||
}
|
||||
|
||||
void FileDataInfo::setSegmentMetadataLen(size_t len) {
|
||||
this->segmentMetadataLen = len;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
cfdp::SegmentationControl FileDataInfo::getSegmentationControl() const {
|
||||
return segCtrl;
|
||||
}
|
||||
|
||||
void FileDataInfo::setSegmentationControl(cfdp::SegmentationControl segCtrl) {
|
||||
this->segCtrl = segCtrl;
|
||||
}
|
45
src/fsfw/cfdp/pdu/FileDataInfo.h
Normal file
45
src/fsfw/cfdp/pdu/FileDataInfo.h
Normal file
@ -0,0 +1,45 @@
|
||||
#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>
|
||||
|
||||
class FileDataInfo {
|
||||
public:
|
||||
FileDataInfo(cfdp::FileSize& offset);
|
||||
FileDataInfo(cfdp::FileSize& offset, const uint8_t* fileData, size_t fileSize);
|
||||
|
||||
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::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);
|
||||
|
||||
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_ */
|
54
src/fsfw/cfdp/pdu/FileDataSerializer.cpp
Normal file
54
src/fsfw/cfdp/pdu/FileDataSerializer.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
#include "FileDataSerializer.h"
|
||||
#include <cstring>
|
||||
|
||||
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()));
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
23
src/fsfw/cfdp/pdu/FileDataSerializer.h
Normal file
23
src/fsfw/cfdp/pdu/FileDataSerializer.h
Normal file
@ -0,0 +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 "HeaderSerializer.h"
|
||||
|
||||
class FileDataSerializer: public HeaderSerializer {
|
||||
public:
|
||||
FileDataSerializer(PduConfig& conf, FileDataInfo& info);
|
||||
|
||||
void update();
|
||||
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
private:
|
||||
FileDataInfo& info;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_FILEDATADESERIALIZER_H_ */
|
55
src/fsfw/cfdp/pdu/FileDirectiveDeserializer.cpp
Normal file
55
src/fsfw/cfdp/pdu/FileDirectiveDeserializer.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
#include "FileDirectiveDeserializer.h"
|
||||
|
||||
FileDirectiveDeserializer::FileDirectiveDeserializer(const uint8_t *pduBuf, size_t maxSize):
|
||||
HeaderDeserializer(pduBuf, maxSize) {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
size_t FileDirectiveDeserializer::getHeaderSize() const {
|
||||
// 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;
|
||||
}
|
||||
|
||||
void FileDirectiveDeserializer::setFileDirective(cfdp::FileDirectives fileDirective) {
|
||||
this->fileDirective = fileDirective;
|
||||
}
|
||||
|
||||
void FileDirectiveDeserializer::setEndianness(SerializeIF::Endianness endianness) {
|
||||
this->endianness = endianness;
|
||||
}
|
||||
|
||||
SerializeIF::Endianness FileDirectiveDeserializer::getEndianness() const {
|
||||
return endianness;
|
||||
}
|
41
src/fsfw/cfdp/pdu/FileDirectiveDeserializer.h
Normal file
41
src/fsfw/cfdp/pdu/FileDirectiveDeserializer.h
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_FILEDIRECTIVEDESERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_FILEDIRECTIVEDESERIALIZER_H_
|
||||
|
||||
#include "../definitions.h"
|
||||
#include "fsfw/cfdp/pdu/HeaderDeserializer.h"
|
||||
|
||||
/**
|
||||
* @brief This class is used to deserialize a PDU file directive header from raw memory.
|
||||
* @details
|
||||
* Base class for other file directives.
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
void setEndianness(SerializeIF::Endianness endianness);
|
||||
SerializeIF::Endianness getEndianness() const;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_FILEDIRECTIVEDESERIALIZER_H_ */
|
39
src/fsfw/cfdp/pdu/FileDirectiveSerializer.cpp
Normal file
39
src/fsfw/cfdp/pdu/FileDirectiveSerializer.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
#include "FileDirectiveSerializer.h"
|
||||
|
||||
|
||||
FileDirectiveSerializer::FileDirectiveSerializer(PduConfig &pduConf,
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
28
src/fsfw/cfdp/pdu/FileDirectiveSerializer.h
Normal file
28
src/fsfw/cfdp/pdu/FileDirectiveSerializer.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_FILEDIRECTIVESERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_FILEDIRECTIVESERIALIZER_H_
|
||||
|
||||
#include "fsfw/cfdp/pdu/HeaderSerializer.h"
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_FILEDIRECTIVESERIALIZER_H_ */
|
111
src/fsfw/cfdp/pdu/FinishedInfo.cpp
Normal file
111
src/fsfw/cfdp/pdu/FinishedInfo.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
#include "FinishedInfo.h"
|
||||
|
||||
FinishedInfo::FinishedInfo() {
|
||||
}
|
||||
|
||||
|
||||
FinishedInfo::FinishedInfo(cfdp::ConditionCode conditionCode,
|
||||
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();
|
||||
}
|
||||
}
|
||||
if(this->faultLocation != nullptr) {
|
||||
size += faultLocation->getSerializedSize();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
bool FinishedInfo::hasFsResponses() const {
|
||||
if(fsResponses != nullptr and fsResponsesLen > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool FinishedInfo::canHoldFsResponses() const {
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
cfdp::ConditionCode FinishedInfo::getConditionCode() const {
|
||||
return conditionCode;
|
||||
}
|
||||
|
||||
void FinishedInfo::setConditionCode(cfdp::ConditionCode conditionCode) {
|
||||
this->conditionCode = conditionCode;
|
||||
}
|
||||
|
||||
cfdp::FinishedDeliveryCode FinishedInfo::getDeliveryCode() const {
|
||||
return deliveryCode;
|
||||
}
|
||||
|
||||
void FinishedInfo::setDeliveryCode(cfdp::FinishedDeliveryCode deliveryCode) {
|
||||
this->deliveryCode = deliveryCode;
|
||||
}
|
||||
|
||||
cfdp::FinishedFileStatus FinishedInfo::getFileStatus() const {
|
||||
return fileStatus;
|
||||
}
|
||||
|
||||
void FinishedInfo::setFilestoreResponsesArrayLen(size_t fsResponsesLen) {
|
||||
this->fsResponsesLen = fsResponsesLen;
|
||||
}
|
||||
|
||||
size_t FinishedInfo::getFsResponsesLen() const {
|
||||
return fsResponsesLen;
|
||||
}
|
||||
|
||||
void FinishedInfo::setFileStatus(cfdp::FinishedFileStatus fileStatus) {
|
||||
this->fileStatus = fileStatus;
|
||||
}
|
45
src/fsfw/cfdp/pdu/FinishedInfo.h
Normal file
45
src/fsfw/cfdp/pdu/FinishedInfo.h
Normal file
@ -0,0 +1,45 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_FINISHINFO_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_FINISHINFO_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);
|
||||
|
||||
size_t getSerializedSize() 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 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;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_FINISHINFO_H_ */
|
90
src/fsfw/cfdp/pdu/FinishedPduDeserializer.cpp
Normal file
90
src/fsfw/cfdp/pdu/FinishedPduDeserializer.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
#include "FinishedPduDeserializer.h"
|
||||
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
finishedInfo.setFilestoreResponsesArrayLen(fsResponsesIdx);
|
||||
return result;
|
||||
}
|
21
src/fsfw/cfdp/pdu/FinishedPduDeserializer.h
Normal file
21
src/fsfw/cfdp/pdu/FinishedPduDeserializer.h
Normal file
@ -0,0 +1,21 @@
|
||||
#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"
|
||||
|
||||
class FinishPduDeserializer: public FileDirectiveDeserializer {
|
||||
public:
|
||||
FinishPduDeserializer(const uint8_t *pduBuf, size_t maxSize, FinishedInfo& info);
|
||||
|
||||
ReturnValue_t parseData() override;
|
||||
|
||||
FinishedInfo& getInfo();
|
||||
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_ */
|
47
src/fsfw/cfdp/pdu/FinishedPduSerializer.cpp
Normal file
47
src/fsfw/cfdp/pdu/FinishedPduSerializer.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include "FinishedPduSerializer.h"
|
||||
|
||||
FinishPduSerializer::FinishPduSerializer(PduConfig &conf, FinishedInfo &finishInfo):
|
||||
FileDirectiveSerializer(conf, cfdp::FileDirectives::FINISH, 0), finishInfo(finishInfo) {
|
||||
updateDirectiveFieldLen();
|
||||
}
|
||||
|
||||
size_t FinishPduSerializer::getSerializedSize() const {
|
||||
return FinishPduSerializer::getWholePduSize();
|
||||
}
|
||||
|
||||
void FinishPduSerializer::updateDirectiveFieldLen() {
|
||||
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);
|
||||
}
|
||||
return result;
|
||||
}
|
22
src/fsfw/cfdp/pdu/FinishedPduSerializer.h
Normal file
22
src/fsfw/cfdp/pdu/FinishedPduSerializer.h
Normal file
@ -0,0 +1,22 @@
|
||||
#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"
|
||||
|
||||
class FinishPduSerializer: public FileDirectiveSerializer {
|
||||
public:
|
||||
FinishPduSerializer(PduConfig& pduConf, FinishedInfo& finishInfo);
|
||||
|
||||
void updateDirectiveFieldLen();
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
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_ */
|
136
src/fsfw/cfdp/pdu/HeaderDeserializer.cpp
Normal file
136
src/fsfw/cfdp/pdu/HeaderDeserializer.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
#include <fsfw/serialize/SerializeAdapter.h>
|
||||
#include "HeaderDeserializer.h"
|
||||
#include <cstring>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
size_t HeaderDeserializer::getPduDataFieldLen() const {
|
||||
uint16_t pduFiedlLen = (fixedHeader->pduDataFieldLenH << 8) | fixedHeader->pduDataFieldLenL;
|
||||
return pduFiedlLen;
|
||||
}
|
||||
|
||||
size_t HeaderDeserializer::getWholePduSize() const {
|
||||
return getPduDataFieldLen() + getHeaderSize();
|
||||
}
|
||||
|
||||
cfdp::PduType HeaderDeserializer::getPduType() const {
|
||||
return static_cast<cfdp::PduType>((fixedHeader->firstByte >> 4) & 0x01);
|
||||
}
|
||||
|
||||
cfdp::Direction HeaderDeserializer::getDirection() const {
|
||||
return static_cast<cfdp::Direction>((fixedHeader->firstByte >> 3) & 0x01);
|
||||
}
|
||||
|
||||
cfdp::TransmissionModes HeaderDeserializer::getTransmissionMode() const {
|
||||
return static_cast<cfdp::TransmissionModes>((fixedHeader->firstByte >> 2) & 0x01);
|
||||
}
|
||||
|
||||
bool HeaderDeserializer::getCrcFlag() const {
|
||||
return (fixedHeader->firstByte >> 1) & 0x01;
|
||||
}
|
||||
|
||||
bool HeaderDeserializer::getLargeFileFlag() const {
|
||||
return fixedHeader->firstByte & 0x01;
|
||||
}
|
||||
|
||||
cfdp::SegmentationControl HeaderDeserializer::getSegmentationControl() const {
|
||||
return static_cast<cfdp::SegmentationControl>((fixedHeader->fourthByte >> 7) & 0x01);
|
||||
}
|
||||
|
||||
cfdp::WidthInBytes HeaderDeserializer::getLenEntityIds() const {
|
||||
return static_cast<cfdp::WidthInBytes>((fixedHeader->fourthByte >> 4) & 0x07);
|
||||
}
|
||||
|
||||
cfdp::WidthInBytes HeaderDeserializer::getLenSeqNum() const {
|
||||
return static_cast<cfdp::WidthInBytes>(fixedHeader->fourthByte & 0x07);
|
||||
}
|
||||
|
||||
cfdp::SegmentMetadataFlag HeaderDeserializer::getSegmentMetadataFlag() const {
|
||||
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);
|
||||
}
|
||||
|
||||
void HeaderDeserializer::getDestId(cfdp::EntityId &destId) const {
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t HeaderDeserializer::getMaxSize() const {
|
||||
return maxSize;
|
||||
}
|
||||
|
||||
bool HeaderDeserializer::hasSegmentMetadataFlag() const {
|
||||
if(this->getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::PRESENT) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
93
src/fsfw/cfdp/pdu/HeaderDeserializer.h
Normal file
93
src/fsfw/cfdp/pdu/HeaderDeserializer.h
Normal file
@ -0,0 +1,93 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_HEADERDESERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_HEADERDESERIALIZER_H_
|
||||
|
||||
#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;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This class is used to deserialize a PDU header from raw memory.
|
||||
* @details
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
size_t getMaxSize() const;
|
||||
protected:
|
||||
PduHeaderFixedStruct* fixedHeader = nullptr;
|
||||
const uint8_t* rawPtr = nullptr;
|
||||
size_t maxSize = 0;
|
||||
|
||||
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_ */
|
135
src/fsfw/cfdp/pdu/HeaderSerializer.cpp
Normal file
135
src/fsfw/cfdp/pdu/HeaderSerializer.cpp
Normal file
@ -0,0 +1,135 @@
|
||||
#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) {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
size_t HeaderSerializer::getSerializedSize() const {
|
||||
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;
|
||||
}
|
||||
|
||||
size_t HeaderSerializer::getWholePduSize() const {
|
||||
// Return size of header plus the PDU data field length
|
||||
return pduDataFieldLen + HeaderSerializer::getSerializedSize();
|
||||
}
|
||||
|
||||
size_t HeaderSerializer::getPduDataFieldLen() const {
|
||||
return pduDataFieldLen;
|
||||
}
|
||||
|
||||
void HeaderSerializer::setPduDataFieldLen(size_t pduDataFieldLen) {
|
||||
this->pduDataFieldLen = pduDataFieldLen;
|
||||
}
|
||||
|
||||
void HeaderSerializer::setPduType(cfdp::PduType pduType) {
|
||||
this->pduType = pduType;
|
||||
}
|
||||
|
||||
void HeaderSerializer::setSegmentMetadataFlag(cfdp::SegmentMetadataFlag segmentMetadataFlag) {
|
||||
this->segmentMetadataFlag = segmentMetadataFlag;
|
||||
}
|
||||
|
||||
cfdp::PduType HeaderSerializer::getPduType() const {
|
||||
return pduType;
|
||||
}
|
||||
|
||||
cfdp::Direction HeaderSerializer::getDirection() const {
|
||||
return pduConf.direction;
|
||||
}
|
||||
|
||||
cfdp::TransmissionModes HeaderSerializer::getTransmissionMode() const {
|
||||
return pduConf.mode;
|
||||
}
|
||||
|
||||
bool HeaderSerializer::getCrcFlag() const {
|
||||
return pduConf.crcFlag;
|
||||
}
|
||||
|
||||
bool HeaderSerializer::getLargeFileFlag() const {
|
||||
return pduConf.largeFile;
|
||||
}
|
||||
|
||||
cfdp::SegmentationControl HeaderSerializer::getSegmentationControl() const {
|
||||
return segmentationCtrl;
|
||||
}
|
||||
|
||||
cfdp::WidthInBytes HeaderSerializer::getLenEntityIds() const {
|
||||
return pduConf.sourceId.getWidth();
|
||||
}
|
||||
|
||||
cfdp::WidthInBytes HeaderSerializer::getLenSeqNum() const {
|
||||
return pduConf.seqNum.getWidth();
|
||||
}
|
||||
|
||||
cfdp::SegmentMetadataFlag HeaderSerializer::getSegmentMetadataFlag() const {
|
||||
return segmentMetadataFlag;
|
||||
}
|
||||
|
||||
void HeaderSerializer::getSourceId(cfdp::EntityId &sourceId) const {
|
||||
sourceId = pduConf.sourceId;
|
||||
}
|
||||
|
||||
void HeaderSerializer::getDestId(cfdp::EntityId &destId) const {
|
||||
destId = pduConf.destId;
|
||||
}
|
||||
|
||||
void HeaderSerializer::setSegmentationControl(cfdp::SegmentationControl segmentationControl) {
|
||||
this->segmentationCtrl = segmentationControl;
|
||||
}
|
||||
|
||||
void HeaderSerializer::getTransactionSeqNum(cfdp::TransactionSeqNum &seqNum) const {
|
||||
seqNum = pduConf.seqNum;
|
||||
}
|
||||
|
||||
bool HeaderSerializer::hasSegmentMetadataFlag() const {
|
||||
if(this->segmentMetadataFlag == cfdp::SegmentMetadataFlag::PRESENT) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
64
src/fsfw/cfdp/pdu/HeaderSerializer.h
Normal file
64
src/fsfw/cfdp/pdu/HeaderSerializer.h
Normal file
@ -0,0 +1,64 @@
|
||||
#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"
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
PduConfig& pduConf;
|
||||
};
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_HEADERSERIALIZER_H_ */
|
20
src/fsfw/cfdp/pdu/KeepAlivePduDeserializer.cpp
Normal file
20
src/fsfw/cfdp/pdu/KeepAlivePduDeserializer.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
#include "KeepAlivePduDeserializer.h"
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
cfdp::FileSize& KeepAlivePduDeserializer::getProgress() {
|
||||
return progress;
|
||||
}
|
18
src/fsfw/cfdp/pdu/KeepAlivePduDeserializer.h
Normal file
18
src/fsfw/cfdp/pdu/KeepAlivePduDeserializer.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_KEEPALIVEPDUDESERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_KEEPALIVEPDUDESERIALIZER_H_
|
||||
|
||||
#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);
|
||||
|
||||
ReturnValue_t parseData() override;
|
||||
|
||||
cfdp::FileSize& getProgress();
|
||||
private:
|
||||
cfdp::FileSize& progress;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_KEEPALIVEPDUDESERIALIZER_H_ */
|
26
src/fsfw/cfdp/pdu/KeepAlivePduSerializer.cpp
Normal file
26
src/fsfw/cfdp/pdu/KeepAlivePduSerializer.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
#include "KeepAlivePduSerializer.h"
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
void KeepAlivePduSerializer::updateDirectiveFieldLen() {
|
||||
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);
|
||||
}
|
21
src/fsfw/cfdp/pdu/KeepAlivePduSerializer.h
Normal file
21
src/fsfw/cfdp/pdu/KeepAlivePduSerializer.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_KEEPALIVEPDUSERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_KEEPALIVEPDUSERIALIZER_H_
|
||||
|
||||
#include "fsfw/cfdp/FileSize.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveSerializer.h"
|
||||
|
||||
class KeepAlivePduSerializer: public FileDirectiveSerializer {
|
||||
public:
|
||||
KeepAlivePduSerializer(PduConfig& conf, cfdp::FileSize& progress);
|
||||
|
||||
void updateDirectiveFieldLen();
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_KEEPALIVEPDUSERIALIZER_H_ */
|
115
src/fsfw/cfdp/pdu/MetadataInfo.cpp
Normal file
115
src/fsfw/cfdp/pdu/MetadataInfo.cpp
Normal file
@ -0,0 +1,115 @@
|
||||
#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) {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
cfdp::ChecksumType MetadataInfo::getChecksumType() const {
|
||||
return checksumType;
|
||||
}
|
||||
|
||||
void MetadataInfo::setChecksumType(cfdp::ChecksumType checksumType) {
|
||||
this->checksumType = checksumType;
|
||||
}
|
||||
|
||||
bool MetadataInfo::isClosureRequested() const {
|
||||
return closureRequested;
|
||||
}
|
||||
|
||||
void MetadataInfo::setClosureRequested(bool closureRequested) {
|
||||
this->closureRequested = closureRequested;
|
||||
}
|
||||
|
||||
cfdp::Lv& MetadataInfo::getDestFileName() {
|
||||
return destFileName;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool MetadataInfo::hasOptions() const {
|
||||
if (optionsArray != nullptr and optionsLen > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MetadataInfo::canHoldOptions() const {
|
||||
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;
|
||||
}
|
||||
size += sourceFileName.getSerializedSize();
|
||||
size += destFileName.getSerializedSize();
|
||||
if(hasOptions()) {
|
||||
for(size_t idx = 0; idx < optionsLen; idx++) {
|
||||
size += optionsArray[idx]->getSerializedSize();
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
void MetadataInfo::setDestFileName(cfdp::Lv &destFileName) {
|
||||
this->destFileName = destFileName;
|
||||
}
|
||||
|
||||
void MetadataInfo::setSourceFileName(cfdp::Lv &sourceFileName) {
|
||||
this->sourceFileName = sourceFileName;
|
||||
}
|
||||
|
||||
size_t MetadataInfo::getMaxOptionsLen() const {
|
||||
return maxOptionsLen;
|
||||
}
|
||||
|
||||
void MetadataInfo::setMaxOptionsLen(size_t maxOptionsLen) {
|
||||
this->maxOptionsLen = maxOptionsLen;
|
||||
}
|
||||
|
||||
size_t MetadataInfo::getOptionsLen() const {
|
||||
return optionsLen;
|
||||
}
|
||||
|
||||
void MetadataInfo::setOptionsLen(size_t optionsLen) {
|
||||
this->optionsLen = optionsLen;
|
||||
}
|
||||
|
||||
cfdp::Lv& MetadataInfo::getSourceFileName() {
|
||||
return sourceFileName;
|
||||
}
|
49
src/fsfw/cfdp/pdu/MetadataInfo.h
Normal file
49
src/fsfw/cfdp/pdu/MetadataInfo.h
Normal file
@ -0,0 +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"
|
||||
|
||||
class MetadataInfo {
|
||||
public:
|
||||
MetadataInfo(bool closureRequested, cfdp::ChecksumType checksumType, cfdp::FileSize& fileSize,
|
||||
cfdp::Lv& sourceFileName, cfdp::Lv& destFileName);
|
||||
|
||||
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 setDestFileName(cfdp::Lv& destFileName);
|
||||
void setSourceFileName(cfdp::Lv& sourceFileName);
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_METADATAINFO_H_ */
|
58
src/fsfw/cfdp/pdu/MetadataPduDeserializer.cpp
Normal file
58
src/fsfw/cfdp/pdu/MetadataPduDeserializer.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
#include "MetadataPduDeserializer.h"
|
||||
|
||||
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);
|
||||
}
|
||||
return result;
|
||||
}
|
18
src/fsfw/cfdp/pdu/MetadataPduDeserializer.h
Normal file
18
src/fsfw/cfdp/pdu/MetadataPduDeserializer.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_METADATAPDUDESERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_METADATAPDUDESERIALIZER_H_
|
||||
|
||||
#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);
|
||||
|
||||
ReturnValue_t parseData() override;
|
||||
private:
|
||||
MetadataInfo& info;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_METADATAPDUDESERIALIZER_H_ */
|
54
src/fsfw/cfdp/pdu/MetadataPduSerializer.cpp
Normal file
54
src/fsfw/cfdp/pdu/MetadataPduSerializer.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
#include "MetadataPduSerializer.h"
|
||||
|
||||
MetadataPduSerializer::MetadataPduSerializer(PduConfig &conf, MetadataInfo &info):
|
||||
FileDirectiveSerializer(conf, cfdp::FileDirectives::METADATA, 5), info(info) {
|
||||
updateDirectiveFieldLen();
|
||||
}
|
||||
|
||||
void MetadataPduSerializer::updateDirectiveFieldLen() {
|
||||
setDirectiveDataFieldLen(info.getSerializedSize(getLargeFileFlag()));
|
||||
}
|
||||
|
||||
size_t MetadataPduSerializer::getSerializedSize() const {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
23
src/fsfw/cfdp/pdu/MetadataPduSerializer.h
Normal file
23
src/fsfw/cfdp/pdu/MetadataPduSerializer.h
Normal file
@ -0,0 +1,23 @@
|
||||
#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"
|
||||
|
||||
class MetadataPduSerializer: public FileDirectiveSerializer {
|
||||
public:
|
||||
MetadataPduSerializer(PduConfig &conf, MetadataInfo& info);
|
||||
|
||||
void updateDirectiveFieldLen();
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
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_ */
|
83
src/fsfw/cfdp/pdu/NakInfo.cpp
Normal file
83
src/fsfw/cfdp/pdu/NakInfo.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
#include "NakInfo.h"
|
||||
|
||||
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;
|
||||
}
|
||||
if(hasSegmentRequests()) {
|
||||
if(fssLarge) {
|
||||
size += segmentRequestsLen * 16;
|
||||
} else {
|
||||
size += segmentRequestsLen * 8;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
bool NakInfo::hasSegmentRequests() const {
|
||||
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;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
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::getStartOfScope() {
|
||||
return startOfScope;
|
||||
}
|
||||
|
||||
cfdp::FileSize& NakInfo::getEndOfScope() {
|
||||
return endOfScope;
|
||||
}
|
||||
|
||||
size_t NakInfo::getSegmentRequestsLen() const {
|
||||
return segmentRequestsLen;
|
||||
}
|
||||
|
||||
size_t NakInfo::getSegmentRequestsMaxLen() const {
|
||||
return maxSegmentRequestsLen;
|
||||
}
|
||||
|
||||
void NakInfo::setSegmentRequestLen(size_t readLen) {
|
||||
this->segmentRequestsLen = readLen;
|
||||
}
|
||||
|
||||
void NakInfo::setMaxSegmentRequestLen(size_t maxSize) {
|
||||
this->maxSegmentRequestsLen = maxSize;
|
||||
}
|
40
src/fsfw/cfdp/pdu/NakInfo.h
Normal file
40
src/fsfw/cfdp/pdu/NakInfo.h
Normal file
@ -0,0 +1,40 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_NAKINFO_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_NAKINFO_H_
|
||||
|
||||
#include "fsfw/cfdp/FileSize.h"
|
||||
#include <utility>
|
||||
|
||||
class NakInfo {
|
||||
public:
|
||||
using SegmentRequest = std::pair<cfdp::FileSize, cfdp::FileSize>;
|
||||
|
||||
NakInfo(cfdp::FileSize startOfScope, cfdp::FileSize endOfScope);
|
||||
|
||||
void setSegmentRequests(SegmentRequest* segmentRequests, size_t* segmentRequestLen,
|
||||
size_t* maxSegmentRequestLen);
|
||||
|
||||
size_t getSerializedSize(bool fssLarge = false);
|
||||
|
||||
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;
|
||||
|
||||
//! 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;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_NAKINFO_H_ */
|
58
src/fsfw/cfdp/pdu/NakPduDeserializer.cpp
Normal file
58
src/fsfw/cfdp/pdu/NakPduDeserializer.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
#include "NakPduDeserializer.h"
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
22
src/fsfw/cfdp/pdu/NakPduDeserializer.h
Normal file
22
src/fsfw/cfdp/pdu/NakPduDeserializer.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_NAKPDUDESERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_NAKPDUDESERIALIZER_H_
|
||||
|
||||
#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);
|
||||
|
||||
/**
|
||||
* 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_ */
|
49
src/fsfw/cfdp/pdu/NakPduSerializer.cpp
Normal file
49
src/fsfw/cfdp/pdu/NakPduSerializer.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
#include "NakPduSerializer.h"
|
||||
|
||||
NakPduSerializer::NakPduSerializer(PduConfig& pduConf, NakInfo& nakInfo):
|
||||
FileDirectiveSerializer(pduConf, cfdp::FileDirectives::NAK, 0), nakInfo(nakInfo) {
|
||||
updateDirectiveFieldLen();
|
||||
}
|
||||
|
||||
void NakPduSerializer::updateDirectiveFieldLen() {
|
||||
this->setDirectiveDataFieldLen(nakInfo.getSerializedSize(getLargeFileFlag()));
|
||||
}
|
||||
|
||||
size_t NakPduSerializer::getSerializedSize() const {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
41
src/fsfw/cfdp/pdu/NakPduSerializer.h
Normal file
41
src/fsfw/cfdp/pdu/NakPduSerializer.h
Normal file
@ -0,0 +1,41 @@
|
||||
#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:
|
||||
|
||||
/**
|
||||
*
|
||||
* @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;
|
||||
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_NAKPDUSERIALIZER_H_ */
|
8
src/fsfw/cfdp/pdu/PduConfig.cpp
Normal file
8
src/fsfw/cfdp/pdu/PduConfig.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
#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) {
|
||||
}
|
36
src/fsfw/cfdp/pdu/PduConfig.h
Normal file
36
src/fsfw/cfdp/pdu/PduConfig.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_PDUCONFIG_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_PDUCONFIG_H_
|
||||
|
||||
#include "VarLenField.h"
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
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) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_PDUCONFIG_H_ */
|
37
src/fsfw/cfdp/pdu/PduHeaderIF.h
Normal file
37
src/fsfw/cfdp/pdu/PduHeaderIF.h
Normal file
@ -0,0 +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>
|
||||
|
||||
/**
|
||||
* @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() {};
|
||||
|
||||
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_ */
|
22
src/fsfw/cfdp/pdu/PromptPduDeserializer.cpp
Normal file
22
src/fsfw/cfdp/pdu/PromptPduDeserializer.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
#include "PromptPduDeserializer.h"
|
||||
|
||||
PromptPduDeserializer::PromptPduDeserializer(const uint8_t *pduBuf, size_t maxSize):
|
||||
FileDirectiveDeserializer(pduBuf, maxSize) {
|
||||
}
|
||||
|
||||
cfdp::PromptResponseRequired PromptPduDeserializer::getPromptResponseRequired() const {
|
||||
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;
|
||||
}
|
18
src/fsfw/cfdp/pdu/PromptPduDeserializer.h
Normal file
18
src/fsfw/cfdp/pdu/PromptPduDeserializer.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_PROMPTPDUDESERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_PROMPTPDUDESERIALIZER_H_
|
||||
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveDeserializer.h"
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_PROMPTPDUDESERIALIZER_H_ */
|
27
src/fsfw/cfdp/pdu/PromptPduSerializer.cpp
Normal file
27
src/fsfw/cfdp/pdu/PromptPduSerializer.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include "PromptPduSerializer.h"
|
||||
|
||||
PromptPduSerializer::PromptPduSerializer(PduConfig &conf,
|
||||
cfdp::PromptResponseRequired responseRequired):
|
||||
FileDirectiveSerializer(conf, cfdp::FileDirectives::PROMPT, 1),
|
||||
responseRequired(responseRequired) {
|
||||
}
|
||||
|
||||
size_t PromptPduSerializer::getSerializedSize() const {
|
||||
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;
|
||||
return result;
|
||||
}
|
18
src/fsfw/cfdp/pdu/PromptPduSerializer.h
Normal file
18
src/fsfw/cfdp/pdu/PromptPduSerializer.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_PROMPTPDUSERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_PROMPTPDUSERIALIZER_H_
|
||||
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveSerializer.h"
|
||||
|
||||
class PromptPduSerializer: public FileDirectiveSerializer {
|
||||
public:
|
||||
PromptPduSerializer(PduConfig& conf, cfdp::PromptResponseRequired responseRequired);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_PROMPTPDUSERIALIZER_H_ */
|
127
src/fsfw/cfdp/pdu/VarLenField.cpp
Normal file
127
src/fsfw/cfdp/pdu/VarLenField.cpp
Normal file
@ -0,0 +1,127 @@
|
||||
#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) {
|
||||
#if FSFW_DISABLE_PRINTOUT == 0
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "cfdp::VarLenField: Setting value failed" << std::endl;
|
||||
#else
|
||||
sif::printWarning("cfdp::VarLenField: Setting value failed\n");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
cfdp::VarLenField::VarLenField(): width(cfdp::WidthInBytes::ONE_BYTE) {
|
||||
value.oneByte = 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
this->width = widthInBytes;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
size_t cfdp::VarLenField::getValue() const {
|
||||
switch(width) {
|
||||
case(cfdp::WidthInBytes::ONE_BYTE): {
|
||||
return value.oneByte;
|
||||
}
|
||||
case(cfdp::WidthInBytes::TWO_BYTES): {
|
||||
return value.twoBytes;
|
||||
}
|
||||
case(cfdp::WidthInBytes::FOUR_BYTES): {
|
||||
return value.fourBytes;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
default: {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
default: {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
45
src/fsfw/cfdp/pdu/VarLenField.h
Normal file
45
src/fsfw/cfdp/pdu/VarLenField.h
Normal file
@ -0,0 +1,45 @@
|
||||
#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>
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
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);
|
||||
|
||||
ReturnValue_t setValue(cfdp::WidthInBytes, size_t value);
|
||||
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
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 width;
|
||||
LengthFieldLen value;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_VARLENFIELD_H_ */
|
10
src/fsfw/cfdp/tlv/CMakeLists.txt
Normal file
10
src/fsfw/cfdp/tlv/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE
|
||||
EntityIdTlv.cpp
|
||||
FilestoreRequestTlv.cpp
|
||||
FilestoreResponseTlv.cpp
|
||||
Lv.cpp
|
||||
Tlv.cpp
|
||||
FlowLabelTlv.cpp
|
||||
MessageToUserTlv.cpp
|
||||
FaultHandlerOverrideTlv.cpp
|
||||
)
|
68
src/fsfw/cfdp/tlv/EntityIdTlv.cpp
Normal file
68
src/fsfw/cfdp/tlv/EntityIdTlv.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
#include "EntityIdTlv.h"
|
||||
#include <array>
|
||||
|
||||
EntityIdTlv::EntityIdTlv(cfdp::EntityId& entityId): entityId(entityId) {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
uint8_t EntityIdTlv::getLengthField() const {
|
||||
return 1 + entityId.getSerializedSize();
|
||||
}
|
||||
|
||||
cfdp::TlvTypes EntityIdTlv::getType() const {
|
||||
return cfdp::TlvTypes::ENTITY_ID;
|
||||
}
|
||||
|
||||
cfdp::EntityId& EntityIdTlv::getEntityId() {
|
||||
return entityId;
|
||||
}
|
39
src/fsfw/cfdp/tlv/EntityIdTlv.h
Normal file
39
src/fsfw/cfdp/tlv/EntityIdTlv.h
Normal file
@ -0,0 +1,39 @@
|
||||
#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"
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
uint8_t getLengthField() const override;
|
||||
cfdp::TlvTypes getType() const override;
|
||||
|
||||
cfdp::EntityId& getEntityId();
|
||||
private:
|
||||
cfdp::EntityId& entityId;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_ENTITYIDTLV_H_ */
|
64
src/fsfw/cfdp/tlv/FaultHandlerOverrideTlv.cpp
Normal file
64
src/fsfw/cfdp/tlv/FaultHandlerOverrideTlv.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
#include "FaultHandlerOverrideTlv.h"
|
||||
|
||||
FaultHandlerOverrideTlv::FaultHandlerOverrideTlv(cfdp::ConditionCode conditionCode,
|
||||
cfdp::FaultHandlerCode handlerCode):
|
||||
conditionCode(conditionCode), handlerCode(handlerCode) {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
cfdp::TlvTypes FaultHandlerOverrideTlv::getType() const {
|
||||
return cfdp::TlvTypes::FAULT_HANDLER;
|
||||
}
|
39
src/fsfw/cfdp/tlv/FaultHandlerOverrideTlv.h
Normal file
39
src/fsfw/cfdp/tlv/FaultHandlerOverrideTlv.h
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_TLV_FAULTHANDLEROVERRIDETLV_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_TLV_FAULTHANDLEROVERRIDETLV_H_
|
||||
|
||||
#include "TlvIF.h"
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
enum FaultHandlerCode {
|
||||
RESERVED = 0b0000,
|
||||
NOTICE_OF_CANCELLATION = 0b0001,
|
||||
NOTICE_OF_SUSPENSION = 0b0010,
|
||||
IGNORE_ERROR = 0b0011,
|
||||
ABANDON_TRANSACTION = 0b0100
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
class FaultHandlerOverrideTlv: public TlvIF {
|
||||
public:
|
||||
|
||||
FaultHandlerOverrideTlv();
|
||||
FaultHandlerOverrideTlv(cfdp::ConditionCode conditionCode, cfdp::FaultHandlerCode handlerCode);
|
||||
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size,
|
||||
size_t maxSize, Endianness streamEndianness) 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;
|
||||
|
||||
private:
|
||||
cfdp::ConditionCode conditionCode = cfdp::ConditionCode::NO_CONDITION_FIELD;
|
||||
cfdp::FaultHandlerCode handlerCode = cfdp::FaultHandlerCode::RESERVED;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_TLV_FAULTHANDLEROVERRIDETLV_H_ */
|
83
src/fsfw/cfdp/tlv/FilestoreRequestTlv.cpp
Normal file
83
src/fsfw/cfdp/tlv/FilestoreRequestTlv.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
#include "fsfw/cfdp/tlv/FilestoreRequestTlv.h"
|
||||
#include "fsfw/FSFW.h"
|
||||
|
||||
FilestoreRequestTlv::FilestoreRequestTlv(cfdp::FilestoreActionCode actionCode,
|
||||
cfdp::Lv& firstFileName): FilestoreTlvBase(actionCode, firstFileName) {
|
||||
}
|
||||
|
||||
FilestoreRequestTlv::FilestoreRequestTlv(cfdp::Lv &firstFileName):
|
||||
FilestoreTlvBase(cfdp::FilestoreActionCode::INVALID, firstFileName) {
|
||||
}
|
||||
|
||||
void FilestoreRequestTlv::setSecondFileName(cfdp::Lv *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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
uint8_t FilestoreRequestTlv::getLengthField() const {
|
||||
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);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
cfdp::TlvTypes FilestoreRequestTlv::getType() const {
|
||||
return cfdp::TlvTypes::FILESTORE_REQUEST;
|
||||
}
|
45
src/fsfw/cfdp/tlv/FilestoreRequestTlv.h
Normal file
45
src/fsfw/cfdp/tlv/FilestoreRequestTlv.h
Normal file
@ -0,0 +1,45 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_FILESTOREREQUESTTLV_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_FILESTOREREQUESTTLV_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);
|
||||
|
||||
FilestoreRequestTlv(cfdp::Lv& firstFileName);
|
||||
|
||||
void setSecondFileName(cfdp::Lv* secondFileName);
|
||||
|
||||
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);
|
||||
|
||||
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::Lv* secondFileName = nullptr;
|
||||
|
||||
ReturnValue_t deSerializeFromValue(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_FILESTOREREQUESTTLV_H_ */
|
124
src/fsfw/cfdp/tlv/FilestoreResponseTlv.cpp
Normal file
124
src/fsfw/cfdp/tlv/FilestoreResponseTlv.cpp
Normal file
@ -0,0 +1,124 @@
|
||||
#include "FilestoreResponseTlv.h"
|
||||
|
||||
FilestoreResponseTlv::FilestoreResponseTlv(cfdp::FilestoreActionCode actionCode, uint8_t statusCode,
|
||||
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) {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void FilestoreResponseTlv::setSecondFileName(cfdp::Lv *secondFileName) {
|
||||
this->secondFileName = secondFileName;
|
||||
}
|
||||
|
||||
void FilestoreResponseTlv::setFilestoreMessage(cfdp::Lv *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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
*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);
|
||||
}
|
||||
|
||||
ReturnValue_t FilestoreResponseTlv::deSerialize(const cfdp::Tlv &tlv, Endianness endianness) {
|
||||
const uint8_t* ptr = tlv.getValue();
|
||||
size_t remSz = tlv.getSerializedSize();
|
||||
|
||||
return deSerializeFromValue(&ptr, &remSz, endianness);
|
||||
}
|
||||
|
||||
uint8_t FilestoreResponseTlv::getStatusCode() const {
|
||||
return statusCode;
|
||||
}
|
||||
|
||||
|
||||
cfdp::TlvTypes FilestoreResponseTlv::getType() const {
|
||||
return cfdp::TlvTypes::FILESTORE_RESPONSE;
|
||||
}
|
50
src/fsfw/cfdp/tlv/FilestoreResponseTlv.h
Normal file
50
src/fsfw/cfdp/tlv/FilestoreResponseTlv.h
Normal file
@ -0,0 +1,50 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_FILESTORERESPONSETLV_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_FILESTORERESPONSETLV_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:
|
||||
|
||||
FilestoreResponseTlv(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);
|
||||
|
||||
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);
|
||||
|
||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
uint8_t getLengthField() const override;
|
||||
cfdp::TlvTypes getType() const override;
|
||||
|
||||
private:
|
||||
uint8_t statusCode;
|
||||
cfdp::Lv* secondFileName = nullptr;
|
||||
cfdp::Lv* filestoreMsg = nullptr;
|
||||
|
||||
ReturnValue_t deSerializeFromValue(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_FILESTORERESPONSETLV_H_ */
|
176
src/fsfw/cfdp/tlv/FilestoreTlvBase.h
Normal file
176
src/fsfw/cfdp/tlv/FilestoreTlvBase.h
Normal file
@ -0,0 +1,176 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_FILESTOREREQUESTBASE_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_FILESTOREREQUESTBASE_H_
|
||||
|
||||
#include <fsfw/cfdp/definitions.h>
|
||||
#include <fsfw/cfdp/tlv/Lv.h>
|
||||
#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
|
||||
};
|
||||
|
||||
// FSR = Filestore Response
|
||||
static constexpr uint8_t FSR_SUCCESS = 0b0000;
|
||||
static constexpr uint8_t FSR_NOT_PERFORMED = 0b1111;
|
||||
|
||||
static constexpr uint8_t FSR_CREATE_NOT_ALLOWED = 0b0001;
|
||||
|
||||
static constexpr uint8_t FSR_DEL_FILE_NOT_EXISTS = 0b0001;
|
||||
static constexpr uint8_t FSR_DEL_NOT_ALLOWED = 0b0010;
|
||||
|
||||
static constexpr uint8_t FSR_RENAME_OLD_FILE_NOT_EXISTS = 0b0001;
|
||||
static constexpr uint8_t FSR_RENAME_NEW_FILE_ALREADY_EXISTS = 0b0010;
|
||||
static constexpr uint8_t FSR_RENAME_NOT_ALLOWED = 0b0011;
|
||||
|
||||
static constexpr uint8_t FSR_APPEND_FILE_1_NOT_EXISTS = 0b0001;
|
||||
static constexpr uint8_t FSR_APPEND_FILE_2_NOT_EXISTS = 0b0010;
|
||||
static constexpr uint8_t FSR_APPEND_NOT_ALLOWED = 0b0011;
|
||||
|
||||
static constexpr uint8_t FSR_REPLACE_FILE_1_NOT_EXISTS = 0b0001;
|
||||
static constexpr uint8_t FSR_REPLACE_FILE_2_NOT_EXISTS = 0b0010;
|
||||
static constexpr uint8_t FSR_REPLACE_REPLACE_NOT_ALLOWED = 0b0011;
|
||||
|
||||
static constexpr uint8_t FSR_CREATE_DIR_NOT_POSSIBLE = 0b0001;
|
||||
|
||||
static constexpr uint8_t FSR_DELDIR_NOT_EXISTS = 0b0001;
|
||||
static constexpr uint8_t FSR_DELDIR_NOT_ALLOWED = 0b0010;
|
||||
|
||||
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:
|
||||
|
||||
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 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;
|
||||
#else
|
||||
sif::printWarning("FilestoreRequestTlv::deSerialize: Second file name required"
|
||||
" but TLV pointer not set\n");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
FilestoreActionCode getActionCode() const {
|
||||
return actionCode;
|
||||
}
|
||||
|
||||
void setActionCode(FilestoreActionCode actionCode) {
|
||||
this->actionCode = actionCode;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
size_t getSerializedSize() const override {
|
||||
return getLengthField() + 2;
|
||||
}
|
||||
protected:
|
||||
FilestoreActionCode actionCode = FilestoreActionCode::INVALID;
|
||||
cfdp::Lv& firstFileName;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_FILESTOREREQUESTBASE_H_ */
|
5
src/fsfw/cfdp/tlv/FlowLabelTlv.cpp
Normal file
5
src/fsfw/cfdp/tlv/FlowLabelTlv.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "FlowLabelTlv.h"
|
||||
|
||||
FlowLabelTlv::FlowLabelTlv(uint8_t* value, size_t size):
|
||||
Tlv(cfdp::TlvTypes::FLOW_LABEL, value, size) {
|
||||
}
|
13
src/fsfw/cfdp/tlv/FlowLabelTlv.h
Normal file
13
src/fsfw/cfdp/tlv/FlowLabelTlv.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_TLV_FLOWLABELTLV_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_TLV_FLOWLABELTLV_H_
|
||||
|
||||
#include "Tlv.h"
|
||||
|
||||
class FlowLabelTlv: public cfdp::Tlv {
|
||||
public:
|
||||
FlowLabelTlv(uint8_t* value, size_t size);
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_TLV_FLOWLABELTLV_H_ */
|
88
src/fsfw/cfdp/tlv/Lv.cpp
Normal file
88
src/fsfw/cfdp/tlv/Lv.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
#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(): 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& 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);
|
||||
}
|
||||
|
||||
size_t cfdp::Lv::getSerializedSize() const {
|
||||
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;
|
||||
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();
|
||||
}
|
53
src/fsfw/cfdp/tlv/Lv.h
Normal file
53
src/fsfw/cfdp/tlv/Lv.h
Normal file
@ -0,0 +1,53 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_LV_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_LV_H_
|
||||
|
||||
#include "fsfw/serialize/SerialBufferAdapter.h"
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
/**
|
||||
* @brief Length-Value field implementation
|
||||
* @details
|
||||
* Thin abstraction layer around a serial buffer adapter
|
||||
*/
|
||||
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&);
|
||||
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size,
|
||||
size_t maxSize, Endianness streamEndianness) 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;
|
||||
|
||||
/**
|
||||
* 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:
|
||||
|
||||
bool zeroLen = true;
|
||||
SerialBufferAdapter<uint8_t> value;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_LV_H_ */
|
8
src/fsfw/cfdp/tlv/MessageToUserTlv.cpp
Normal file
8
src/fsfw/cfdp/tlv/MessageToUserTlv.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
#include "MessageToUserTlv.h"
|
||||
|
||||
MessageToUserTlv::MessageToUserTlv(uint8_t *value, size_t size):
|
||||
Tlv(cfdp::TlvTypes::MSG_TO_USER, value, size) {
|
||||
}
|
||||
|
||||
MessageToUserTlv::MessageToUserTlv(): Tlv() {
|
||||
}
|
13
src/fsfw/cfdp/tlv/MessageToUserTlv.h
Normal file
13
src/fsfw/cfdp/tlv/MessageToUserTlv.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_TLV_MESSAGETOUSERTLV_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_TLV_MESSAGETOUSERTLV_H_
|
||||
|
||||
#include "Tlv.h"
|
||||
|
||||
class MessageToUserTlv: public cfdp::Tlv {
|
||||
public:
|
||||
MessageToUserTlv();
|
||||
MessageToUserTlv(uint8_t* value, size_t size);
|
||||
private:
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_TLV_MESSAGETOUSERTLV_H_ */
|
114
src/fsfw/cfdp/tlv/Tlv.cpp
Normal file
114
src/fsfw/cfdp/tlv/Tlv.cpp
Normal file
@ -0,0 +1,114 @@
|
||||
#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(): 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;
|
||||
*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);
|
||||
}
|
||||
|
||||
size_t cfdp::Tlv::getSerializedSize() const {
|
||||
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;
|
||||
}
|
||||
|
||||
uint8_t rawType = **buffer;
|
||||
if(not checkType(rawType)) {
|
||||
return INVALID_TLV_TYPE;
|
||||
}
|
||||
|
||||
type = static_cast<TlvTypes>(rawType);
|
||||
*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;
|
||||
}
|
||||
|
||||
const uint8_t* cfdp::Tlv::getValue() const {
|
||||
return value.getConstBuffer();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void cfdp::Tlv::setValue(uint8_t *value, size_t len) {
|
||||
if(len > 0) {
|
||||
zeroLen = false;
|
||||
}
|
||||
this->value.setBuffer(value, len);
|
||||
}
|
||||
|
||||
uint8_t cfdp::Tlv::getLengthField() const {
|
||||
return this->value.getSerializedSize() - 1;
|
||||
}
|
||||
|
||||
void cfdp::Tlv::setType(TlvTypes type) {
|
||||
this->type = type;
|
||||
}
|
64
src/fsfw/cfdp/tlv/Tlv.h
Normal file
64
src/fsfw/cfdp/tlv/Tlv.h
Normal file
@ -0,0 +1,64 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_TLV_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_TLV_H_
|
||||
|
||||
#include "TlvIF.h"
|
||||
#include "fsfw/serialize/SerialBufferAdapter.h"
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
/**
|
||||
* @brief Type-Length-Value field implementation
|
||||
* @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();
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
const uint8_t* getValue() const;
|
||||
void setType(TlvTypes type);
|
||||
TlvTypes getType() const override;
|
||||
uint8_t getLengthField() const override;
|
||||
private:
|
||||
bool checkType(uint8_t rawType);
|
||||
|
||||
bool zeroLen = true;
|
||||
TlvTypes type = TlvTypes::INVALID_TLV;
|
||||
SerialBufferAdapter<uint8_t> value;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_TLV_H_ */
|
16
src/fsfw/cfdp/tlv/TlvIF.h
Normal file
16
src/fsfw/cfdp/tlv/TlvIF.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_TLVIF_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_TLVIF_H_
|
||||
|
||||
#include "../definitions.h"
|
||||
|
||||
class TlvIF: public SerializeIF {
|
||||
public:
|
||||
virtual~ TlvIF() {};
|
||||
|
||||
virtual uint8_t getLengthField() const = 0;
|
||||
virtual cfdp::TlvTypes getType() const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_TLVIF_H_ */
|
@ -8,11 +8,10 @@
|
||||
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
|
||||
|
||||
/**
|
||||
* @brief Extendes the basic ControllerBase with the common components
|
||||
* HasActionsIF for commandability and HasLocalDataPoolIF to keep
|
||||
* a pool of local data pool variables.
|
||||
* @brief Extends the basic ControllerBase with commonly used components
|
||||
* @details
|
||||
* Default implementations required for the interfaces will be empty and have
|
||||
* HasActionsIF for commandability and HasLocalDataPoolIF to keep a pool of local data pool
|
||||
* variables. Default implementations required for the interfaces will be empty and have
|
||||
* to be implemented by child class.
|
||||
*/
|
||||
class ExtendedControllerBase: public ControllerBase,
|
||||
|
@ -78,15 +78,16 @@ class StorageManagerIF;
|
||||
*
|
||||
* @ingroup devices
|
||||
*/
|
||||
class DeviceHandlerBase: public DeviceHandlerIF,
|
||||
public HasReturnvaluesIF,
|
||||
public ExecutableObjectIF,
|
||||
public SystemObject,
|
||||
public HasModesIF,
|
||||
public HasHealthIF,
|
||||
public HasActionsIF,
|
||||
public ReceivesParameterMessagesIF,
|
||||
public HasLocalDataPoolIF {
|
||||
class DeviceHandlerBase:
|
||||
public DeviceHandlerIF,
|
||||
public HasReturnvaluesIF,
|
||||
public ExecutableObjectIF,
|
||||
public SystemObject,
|
||||
public HasModesIF,
|
||||
public HasHealthIF,
|
||||
public HasActionsIF,
|
||||
public ReceivesParameterMessagesIF,
|
||||
public HasLocalDataPoolIF {
|
||||
friend void (Factory::setStaticFrameworkObjectIds)();
|
||||
public:
|
||||
/**
|
||||
|
@ -9,6 +9,7 @@ enum FsfwMessageTypes {
|
||||
HEALTH_COMMAND,
|
||||
MODE_SEQUENCE,
|
||||
ACTION,
|
||||
CFDP,
|
||||
TM_STORE,
|
||||
DEVICE_HANDLER_COMMAND,
|
||||
MONITORING,
|
||||
|
@ -19,6 +19,9 @@ enum framework_objects: object_id_t {
|
||||
PUS_SERVICE_200_MODE_MGMT = 0x53000200,
|
||||
PUS_SERVICE_201_HEALTH = 0x53000201,
|
||||
|
||||
/* CFDP Distributer */
|
||||
CFDP_PACKET_DISTRIBUTOR = 0x53001000,
|
||||
|
||||
//Generic IDs for IPC, modes, health, events
|
||||
HEALTH_TABLE = 0x53010000,
|
||||
// MODE_STORE = 0x53010100,
|
||||
|
@ -60,6 +60,7 @@ enum: uint8_t {
|
||||
HAS_ACTIONS_IF, //HF
|
||||
DEVICE_COMMUNICATION_IF, //DC
|
||||
BSP, //BSP
|
||||
CFDP, //CFDP
|
||||
TIME_STAMPER_IF, //TSI
|
||||
SGP4PROPAGATOR_CLASS, //SGP4
|
||||
MUTEX_IF, //MUX
|
||||
|
@ -105,7 +105,7 @@ uint8_t * SerialBufferAdapter<count_t>::getBuffer() {
|
||||
}
|
||||
|
||||
template<typename count_t>
|
||||
const uint8_t * SerialBufferAdapter<count_t>::getConstBuffer() {
|
||||
const uint8_t * SerialBufferAdapter<count_t>::getConstBuffer() const {
|
||||
if(constBuffer == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "SerialBufferAdapter::getConstBuffer:"
|
||||
|
@ -66,7 +66,7 @@ public:
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
uint8_t * getBuffer();
|
||||
const uint8_t * getConstBuffer();
|
||||
const uint8_t * getConstBuffer() const;
|
||||
void setBuffer(uint8_t* buffer, count_t bufferLength);
|
||||
private:
|
||||
bool serializeLength = false;
|
||||
|
@ -15,7 +15,8 @@
|
||||
* The Secondary Header (with Service/Subservice) is ignored.
|
||||
* @ingroup tc_distribution
|
||||
*/
|
||||
class CCSDSDistributor : public TcDistributor,
|
||||
class CCSDSDistributor:
|
||||
public TcDistributor,
|
||||
public CCSDSDistributorIF,
|
||||
public AcceptsTelecommandsIF {
|
||||
public:
|
||||
|
@ -36,8 +36,7 @@ public:
|
||||
/**
|
||||
* The empty virtual destructor.
|
||||
*/
|
||||
virtual ~CCSDSDistributorIF() {
|
||||
}
|
||||
virtual ~CCSDSDistributorIF() {}
|
||||
};
|
||||
|
||||
|
||||
|
147
src/fsfw/tcdistribution/CFDPDistributor.cpp
Normal file
147
src/fsfw/tcdistribution/CFDPDistributor.cpp
Normal file
@ -0,0 +1,147 @@
|
||||
#include "fsfw/tcdistribution/CCSDSDistributorIF.h"
|
||||
#include "fsfw/tcdistribution/CFDPDistributor.h"
|
||||
|
||||
#include "fsfw/tmtcpacket/cfdp/CFDPPacketStored.h"
|
||||
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
|
||||
#ifndef FSFW_CFDP_DISTRIBUTOR_DEBUGGING
|
||||
#define FSFW_CFDP_DISTRIBUTOR_DEBUGGING 1
|
||||
#endif
|
||||
|
||||
CFDPDistributor::CFDPDistributor(uint16_t setApid, object_id_t setObjectId,
|
||||
object_id_t setPacketSource):
|
||||
TcDistributor(setObjectId), apid(setApid), checker(setApid),
|
||||
tcStatus(RETURN_FAILED), packetSource(setPacketSource) {
|
||||
}
|
||||
|
||||
CFDPDistributor::~CFDPDistributor() {}
|
||||
|
||||
CFDPDistributor::TcMqMapIter CFDPDistributor::selectDestination() {
|
||||
#if FSFW_CFDP_DISTRIBUTOR_DEBUGGING == 1
|
||||
store_address_t storeId = this->currentMessage.getStorageId();
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "CFDPDistributor::handlePacket received: " << storeId.poolIndex << ", " <<
|
||||
storeId.packetIndex << std::endl;
|
||||
#else
|
||||
sif::printDebug("CFDPDistributor::handlePacket received: %d, %d\n", storeId.poolIndex,
|
||||
storeId.packetIndex);
|
||||
#endif
|
||||
#endif
|
||||
TcMqMapIter queueMapIt = this->queueMap.end();
|
||||
if(this->currentPacket == nullptr) {
|
||||
return queueMapIt;
|
||||
}
|
||||
this->currentPacket->setStoreAddress(this->currentMessage.getStorageId());
|
||||
if (currentPacket->getWholeData() != nullptr) {
|
||||
tcStatus = checker.checkPacket(currentPacket);
|
||||
if(tcStatus != HasReturnvaluesIF::RETURN_OK) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "CFDPDistributor::handlePacket: Packet format invalid, code " <<
|
||||
static_cast<int>(tcStatus) << std::endl;
|
||||
#else
|
||||
sif::printDebug("CFDPDistributor::handlePacket: Packet format invalid, code %d\n",
|
||||
static_cast<int>(tcStatus));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
queueMapIt = this->queueMap.find(0);
|
||||
}
|
||||
else {
|
||||
tcStatus = PACKET_LOST;
|
||||
}
|
||||
|
||||
if (queueMapIt == this->queueMap.end()) {
|
||||
tcStatus = DESTINATION_NOT_FOUND;
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "CFDPDistributor::handlePacket: Destination not found" << std::endl;
|
||||
#else
|
||||
sif::printDebug("CFDPDistributor::handlePacket: Destination not found\n");
|
||||
#endif /* !FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||
#endif
|
||||
}
|
||||
|
||||
if (tcStatus != RETURN_OK) {
|
||||
return this->queueMap.end();
|
||||
}
|
||||
else {
|
||||
return queueMapIt;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
ReturnValue_t CFDPDistributor::registerHandler(AcceptsTelecommandsIF* handler) {
|
||||
uint16_t handlerId = handler->getIdentifier(); //should be 0, because CFDPHandler does not set a set a service-ID
|
||||
#if FSFW_CFDP_DISTRIBUTOR_DEBUGGING == 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::info << "CFDPDistributor::registerHandler: Handler ID: " << static_cast<int>(handlerId) << std::endl;
|
||||
#else
|
||||
sif::printInfo("CFDPDistributor::registerHandler: Handler ID: %d\n", static_cast<int>(handlerId));
|
||||
#endif
|
||||
#endif
|
||||
MessageQueueId_t queue = handler->getRequestQueue();
|
||||
auto returnPair = queueMap.emplace(handlerId, queue);
|
||||
if (not returnPair.second) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "CFDPDistributor::registerHandler: Service ID already"
|
||||
" exists in map" << std::endl;
|
||||
#else
|
||||
sif::printError("CFDPDistributor::registerHandler: Service ID already exists in map\n");
|
||||
#endif
|
||||
#endif
|
||||
return SERVICE_ID_ALREADY_EXISTS;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
MessageQueueId_t CFDPDistributor::getRequestQueue() {
|
||||
return tcQueue->getId();
|
||||
}
|
||||
|
||||
//ReturnValue_t CFDPDistributor::callbackAfterSending(ReturnValue_t queueStatus) {
|
||||
// if (queueStatus != RETURN_OK) {
|
||||
// tcStatus = queueStatus;
|
||||
// }
|
||||
// if (tcStatus != RETURN_OK) {
|
||||
// this->verifyChannel.sendFailureReport(tc_verification::ACCEPTANCE_FAILURE,
|
||||
// currentPacket, tcStatus);
|
||||
// // A failed packet is deleted immediately after reporting,
|
||||
// // otherwise it will block memory.
|
||||
// currentPacket->deletePacket();
|
||||
// return RETURN_FAILED;
|
||||
// } else {
|
||||
// this->verifyChannel.sendSuccessReport(tc_verification::ACCEPTANCE_SUCCESS,
|
||||
// currentPacket);
|
||||
// return RETURN_OK;
|
||||
// }
|
||||
//}
|
||||
|
||||
uint16_t CFDPDistributor::getIdentifier() {
|
||||
return this->apid;
|
||||
}
|
||||
|
||||
ReturnValue_t CFDPDistributor::initialize() {
|
||||
currentPacket = new CFDPPacketStored();
|
||||
if(currentPacket == nullptr) {
|
||||
// Should not happen, memory allocation failed!
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
|
||||
CCSDSDistributorIF* ccsdsDistributor = ObjectManager::instance()->get<CCSDSDistributorIF>(
|
||||
packetSource);
|
||||
if (ccsdsDistributor == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "CFDPDistributor::initialize: Packet source invalid" << std::endl;
|
||||
sif::error << " Make sure it exists and implements CCSDSDistributorIF!" << std::endl;
|
||||
#else
|
||||
sif::printError("CFDPDistributor::initialize: Packet source invalid\n");
|
||||
sif::printError("Make sure it exists and implements CCSDSDistributorIF\n");
|
||||
#endif
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
return ccsdsDistributor->registerApplication(this);
|
||||
}
|
72
src/fsfw/tcdistribution/CFDPDistributor.h
Normal file
72
src/fsfw/tcdistribution/CFDPDistributor.h
Normal file
@ -0,0 +1,72 @@
|
||||
#ifndef FSFW_TCDISTRIBUTION_CFDPDISTRIBUTOR_H_
|
||||
#define FSFW_TCDISTRIBUTION_CFDPDISTRIBUTOR_H_
|
||||
|
||||
#include <fsfw/tcdistribution/TcPacketCheckCFDP.h>
|
||||
#include "CFDPDistributorIF.h"
|
||||
#include "TcDistributor.h"
|
||||
#include "../tmtcpacket/cfdp/CFDPPacketStored.h"
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
#include "../tmtcservices/AcceptsTelecommandsIF.h"
|
||||
#include "../tmtcservices/VerificationReporter.h"
|
||||
|
||||
/**
|
||||
* This class accepts CFDP Telecommands and forwards them to Application
|
||||
* services.
|
||||
* @ingroup tc_distribution
|
||||
*/
|
||||
class CFDPDistributor:
|
||||
public TcDistributor,
|
||||
public CFDPDistributorIF,
|
||||
public AcceptsTelecommandsIF {
|
||||
public:
|
||||
/**
|
||||
* The ctor passes @c set_apid to the checker class and calls the
|
||||
* TcDistribution ctor with a certain object id.
|
||||
* @param setApid The APID of this receiving Application.
|
||||
* @param setObjectId Object ID of the distributor itself
|
||||
* @param setPacketSource Object ID of the source of TC packets.
|
||||
* Must implement CCSDSDistributorIF.
|
||||
*/
|
||||
CFDPDistributor(uint16_t setApid, object_id_t setObjectId,
|
||||
object_id_t setPacketSource);
|
||||
/**
|
||||
* The destructor is empty.
|
||||
*/
|
||||
virtual ~CFDPDistributor();
|
||||
ReturnValue_t registerHandler(AcceptsTelecommandsIF* handler) override;
|
||||
MessageQueueId_t getRequestQueue() override;
|
||||
ReturnValue_t initialize() override;
|
||||
uint16_t getIdentifier() override;
|
||||
|
||||
protected:
|
||||
uint16_t apid;
|
||||
/**
|
||||
* The currently handled packet is stored here.
|
||||
*/
|
||||
CFDPPacketStored* currentPacket = nullptr;
|
||||
TcPacketCheckCFDP checker;
|
||||
/**
|
||||
* With this variable, the current check status is stored to generate
|
||||
* acceptance messages later.
|
||||
*/
|
||||
ReturnValue_t tcStatus;
|
||||
|
||||
const object_id_t packetSource;
|
||||
|
||||
/**
|
||||
* This method reads the packet service, checks if such a service is
|
||||
* registered and forwards the packet to the destination.
|
||||
* It also initiates the formal packet check and sending of verification
|
||||
* messages.
|
||||
* @return Iterator to map entry of found service id
|
||||
* or iterator to @c map.end().
|
||||
*/
|
||||
TcMqMapIter selectDestination() override;
|
||||
/**
|
||||
* The callback here handles the generation of acceptance
|
||||
* success/failure messages.
|
||||
*/
|
||||
//ReturnValue_t callbackAfterSending(ReturnValue_t queueStatus) override;
|
||||
};
|
||||
|
||||
#endif /* FSFW_TCDISTRIBUTION_CFDPDISTRIBUTOR_H_ */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user