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)) {
|
||||