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"
|
"--exclude-unreachable-branches"
|
||||||
)
|
)
|
||||||
set(COVERAGE_EXCLUDES
|
set(COVERAGE_EXCLUDES
|
||||||
"/c/msys64/mingw64/*"
|
"/c/msys64/mingw64/*" "*/fsfw_hal/*"
|
||||||
)
|
)
|
||||||
elseif(UNIX)
|
elseif(UNIX)
|
||||||
set(COVERAGE_EXCLUDES
|
set(COVERAGE_EXCLUDES
|
||||||
"/usr/include/*" "/usr/bin/*" "Catch2/*"
|
"/usr/include/*" "/usr/bin/*" "Catch2/*"
|
||||||
"/usr/local/include/*" "*/fsfw_tests/*"
|
"/usr/local/include/*" "*/fsfw_tests/*"
|
||||||
"*/catch2-src/*"
|
"*/catch2-src/*" "*/fsfw_hal/*"
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ You can use the following commands inside the `fsfw` folder to set up the build
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
mkdir build-Unittest && cd build-Unittest
|
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.
|
You can also use `-DFSFW_OSAL=linux` on Linux systems.
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
namespace addresses {
|
namespace addresses {
|
||||||
/* Logical addresses have uint32_t datatype */
|
/* Logical addresses have uint32_t datatype */
|
||||||
enum logicalAddresses: address_t {
|
enum LogAddr: address_t {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# Core
|
# Core
|
||||||
|
|
||||||
add_subdirectory(action)
|
add_subdirectory(action)
|
||||||
|
add_subdirectory(cfdp)
|
||||||
add_subdirectory(container)
|
add_subdirectory(container)
|
||||||
add_subdirectory(controller)
|
add_subdirectory(controller)
|
||||||
add_subdirectory(datapool)
|
add_subdirectory(datapool)
|
||||||
|
@ -46,6 +46,10 @@
|
|||||||
#define FSFW_USE_PUS_C_TELECOMMANDS 1
|
#define FSFW_USE_PUS_C_TELECOMMANDS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef FSFW_TCP_RECV_WIRETAPPING_ENABLED
|
||||||
|
#define FSFW_TCP_RECV_WIRETAPPING_ENABLED 0
|
||||||
|
#endif
|
||||||
|
|
||||||
// FSFW HAL defines
|
// FSFW HAL defines
|
||||||
|
|
||||||
// Can be used for low-level debugging of the SPI bus
|
// 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"
|
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extendes the basic ControllerBase with the common components
|
* @brief Extends the basic ControllerBase with commonly used components
|
||||||
* HasActionsIF for commandability and HasLocalDataPoolIF to keep
|
|
||||||
* a pool of local data pool variables.
|
|
||||||
* @details
|
* @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.
|
* to be implemented by child class.
|
||||||
*/
|
*/
|
||||||
class ExtendedControllerBase: public ControllerBase,
|
class ExtendedControllerBase: public ControllerBase,
|
||||||
|
@ -78,15 +78,16 @@ class StorageManagerIF;
|
|||||||
*
|
*
|
||||||
* @ingroup devices
|
* @ingroup devices
|
||||||
*/
|
*/
|
||||||
class DeviceHandlerBase: public DeviceHandlerIF,
|
class DeviceHandlerBase:
|
||||||
public HasReturnvaluesIF,
|
public DeviceHandlerIF,
|
||||||
public ExecutableObjectIF,
|
public HasReturnvaluesIF,
|
||||||
public SystemObject,
|
public ExecutableObjectIF,
|
||||||
public HasModesIF,
|
public SystemObject,
|
||||||
public HasHealthIF,
|
public HasModesIF,
|
||||||
public HasActionsIF,
|
public HasHealthIF,
|
||||||
public ReceivesParameterMessagesIF,
|
public HasActionsIF,
|
||||||
public HasLocalDataPoolIF {
|
public ReceivesParameterMessagesIF,
|
||||||
|
public HasLocalDataPoolIF {
|
||||||
friend void (Factory::setStaticFrameworkObjectIds)();
|
friend void (Factory::setStaticFrameworkObjectIds)();
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -9,6 +9,7 @@ enum FsfwMessageTypes {
|
|||||||
HEALTH_COMMAND,
|
HEALTH_COMMAND,
|
||||||
MODE_SEQUENCE,
|
MODE_SEQUENCE,
|
||||||
ACTION,
|
ACTION,
|
||||||
|
CFDP,
|
||||||
TM_STORE,
|
TM_STORE,
|
||||||
DEVICE_HANDLER_COMMAND,
|
DEVICE_HANDLER_COMMAND,
|
||||||
MONITORING,
|
MONITORING,
|
||||||
|
@ -19,6 +19,9 @@ enum framework_objects: object_id_t {
|
|||||||
PUS_SERVICE_200_MODE_MGMT = 0x53000200,
|
PUS_SERVICE_200_MODE_MGMT = 0x53000200,
|
||||||
PUS_SERVICE_201_HEALTH = 0x53000201,
|
PUS_SERVICE_201_HEALTH = 0x53000201,
|
||||||
|
|
||||||
|
/* CFDP Distributer */
|
||||||
|
CFDP_PACKET_DISTRIBUTOR = 0x53001000,
|
||||||
|
|
||||||
//Generic IDs for IPC, modes, health, events
|
//Generic IDs for IPC, modes, health, events
|
||||||
HEALTH_TABLE = 0x53010000,
|
HEALTH_TABLE = 0x53010000,
|
||||||
// MODE_STORE = 0x53010100,
|
// MODE_STORE = 0x53010100,
|
||||||
|
@ -60,6 +60,7 @@ enum: uint8_t {
|
|||||||
HAS_ACTIONS_IF, //HF
|
HAS_ACTIONS_IF, //HF
|
||||||
DEVICE_COMMUNICATION_IF, //DC
|
DEVICE_COMMUNICATION_IF, //DC
|
||||||
BSP, //BSP
|
BSP, //BSP
|
||||||
|
CFDP, //CFDP
|
||||||
TIME_STAMPER_IF, //TSI
|
TIME_STAMPER_IF, //TSI
|
||||||
SGP4PROPAGATOR_CLASS, //SGP4
|
SGP4PROPAGATOR_CLASS, //SGP4
|
||||||
MUTEX_IF, //MUX
|
MUTEX_IF, //MUX
|
||||||
|
@ -105,7 +105,7 @@ uint8_t * SerialBufferAdapter<count_t>::getBuffer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename count_t>
|
template<typename count_t>
|
||||||
const uint8_t * SerialBufferAdapter<count_t>::getConstBuffer() {
|
const uint8_t * SerialBufferAdapter<count_t>::getConstBuffer() const {
|
||||||
if(constBuffer == nullptr) {
|
if(constBuffer == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "SerialBufferAdapter::getConstBuffer:"
|
sif::error << "SerialBufferAdapter::getConstBuffer:"
|
||||||
|
@ -66,7 +66,7 @@ public:
|
|||||||
Endianness streamEndianness) override;
|
Endianness streamEndianness) override;
|
||||||
|
|
||||||
uint8_t * getBuffer();
|
uint8_t * getBuffer();
|
||||||
const uint8_t * getConstBuffer();
|
const uint8_t * getConstBuffer() const;
|
||||||
void setBuffer(uint8_t* buffer, count_t bufferLength);
|
void setBuffer(uint8_t* buffer, count_t bufferLength);
|
||||||
private:
|
private:
|
||||||
bool serializeLength = false;
|
bool serializeLength = false;
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
#define CCSDS_DISTRIBUTOR_DEBUGGING 0
|
#define CCSDS_DISTRIBUTOR_DEBUGGING 0
|
||||||
|
|
||||||
CCSDSDistributor::CCSDSDistributor(uint16_t setDefaultApid,
|
CCSDSDistributor::CCSDSDistributor(uint16_t setDefaultApid,
|
||||||
object_id_t setObjectId):
|
object_id_t setObjectId):
|
||||||
TcDistributor(setObjectId), defaultApid( setDefaultApid ) {
|
TcDistributor(setObjectId), defaultApid( setDefaultApid ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CCSDSDistributor::~CCSDSDistributor() {}
|
CCSDSDistributor::~CCSDSDistributor() {}
|
||||||
@ -16,97 +16,97 @@ CCSDSDistributor::~CCSDSDistributor() {}
|
|||||||
TcDistributor::TcMqMapIter CCSDSDistributor::selectDestination() {
|
TcDistributor::TcMqMapIter CCSDSDistributor::selectDestination() {
|
||||||
#if CCSDS_DISTRIBUTOR_DEBUGGING == 1
|
#if CCSDS_DISTRIBUTOR_DEBUGGING == 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "CCSDSDistributor::selectDestination received: " <<
|
sif::debug << "CCSDSDistributor::selectDestination received: " <<
|
||||||
this->currentMessage.getStorageId().poolIndex << ", " <<
|
this->currentMessage.getStorageId().poolIndex << ", " <<
|
||||||
this->currentMessage.getStorageId().packetIndex << std::endl;
|
this->currentMessage.getStorageId().packetIndex << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printDebug("CCSDSDistributor::selectDestination received: %d, %d\n",
|
sif::printDebug("CCSDSDistributor::selectDestination received: %d, %d\n",
|
||||||
currentMessage.getStorageId().poolIndex, currentMessage.getStorageId().packetIndex);
|
currentMessage.getStorageId().poolIndex, currentMessage.getStorageId().packetIndex);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
const uint8_t* packet = nullptr;
|
const uint8_t* packet = nullptr;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
ReturnValue_t result = this->tcStore->getData(currentMessage.getStorageId(),
|
ReturnValue_t result = this->tcStore->getData(currentMessage.getStorageId(),
|
||||||
&packet, &size );
|
&packet, &size );
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "CCSDSDistributor::selectDestination: Getting data from"
|
sif::error << "CCSDSDistributor::selectDestination: Getting data from"
|
||||||
" store failed!" << std::endl;
|
" store failed!" << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printError("CCSDSDistributor::selectDestination: Getting data from"
|
sif::printError("CCSDSDistributor::selectDestination: Getting data from"
|
||||||
" store failed!\n");
|
" store failed!\n");
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
SpacePacketBase currentPacket(packet);
|
SpacePacketBase currentPacket(packet);
|
||||||
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1 && CCSDS_DISTRIBUTOR_DEBUGGING == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1 && CCSDS_DISTRIBUTOR_DEBUGGING == 1
|
||||||
sif::info << "CCSDSDistributor::selectDestination has packet with APID " << std::hex <<
|
sif::info << "CCSDSDistributor::selectDestination has packet with APID " << std::hex <<
|
||||||
currentPacket.getAPID() << std::dec << std::endl;
|
currentPacket.getAPID() << std::dec << std::endl;
|
||||||
#endif
|
#endif
|
||||||
TcMqMapIter position = this->queueMap.find(currentPacket.getAPID());
|
TcMqMapIter position = this->queueMap.find(currentPacket.getAPID());
|
||||||
if ( position != this->queueMap.end() ) {
|
if ( position != this->queueMap.end() ) {
|
||||||
return position;
|
return position;
|
||||||
} else {
|
} else {
|
||||||
//The APID was not found. Forward packet to main SW-APID anyway to
|
//The APID was not found. Forward packet to main SW-APID anyway to
|
||||||
// create acceptance failure report.
|
// create acceptance failure report.
|
||||||
return this->queueMap.find( this->defaultApid );
|
return this->queueMap.find( this->defaultApid );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t CCSDSDistributor::getRequestQueue() {
|
MessageQueueId_t CCSDSDistributor::getRequestQueue() {
|
||||||
return tcQueue->getId();
|
return tcQueue->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CCSDSDistributor::registerApplication(
|
ReturnValue_t CCSDSDistributor::registerApplication(
|
||||||
AcceptsTelecommandsIF* application) {
|
AcceptsTelecommandsIF* application) {
|
||||||
ReturnValue_t returnValue = RETURN_OK;
|
ReturnValue_t returnValue = RETURN_OK;
|
||||||
auto insertPair = this->queueMap.emplace(application->getIdentifier(),
|
auto insertPair = this->queueMap.emplace(application->getIdentifier(),
|
||||||
application->getRequestQueue());
|
application->getRequestQueue());
|
||||||
if(not insertPair.second) {
|
if(not insertPair.second) {
|
||||||
returnValue = RETURN_FAILED;
|
returnValue = RETURN_FAILED;
|
||||||
}
|
}
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CCSDSDistributor::registerApplication(uint16_t apid,
|
ReturnValue_t CCSDSDistributor::registerApplication(uint16_t apid,
|
||||||
MessageQueueId_t id) {
|
MessageQueueId_t id) {
|
||||||
ReturnValue_t returnValue = RETURN_OK;
|
ReturnValue_t returnValue = RETURN_OK;
|
||||||
auto insertPair = this->queueMap.emplace(apid, id);
|
auto insertPair = this->queueMap.emplace(apid, id);
|
||||||
if(not insertPair.second) {
|
if(not insertPair.second) {
|
||||||
returnValue = RETURN_FAILED;
|
returnValue = RETURN_FAILED;
|
||||||
}
|
}
|
||||||
return returnValue;
|
return returnValue;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t CCSDSDistributor::getIdentifier() {
|
uint16_t CCSDSDistributor::getIdentifier() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CCSDSDistributor::initialize() {
|
ReturnValue_t CCSDSDistributor::initialize() {
|
||||||
ReturnValue_t status = this->TcDistributor::initialize();
|
ReturnValue_t status = this->TcDistributor::initialize();
|
||||||
this->tcStore = ObjectManager::instance()->get<StorageManagerIF>( objects::TC_STORE );
|
this->tcStore = ObjectManager::instance()->get<StorageManagerIF>( objects::TC_STORE );
|
||||||
if (this->tcStore == nullptr) {
|
if (this->tcStore == nullptr) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "CCSDSDistributor::initialize: Could not initialize"
|
sif::error << "CCSDSDistributor::initialize: Could not initialize"
|
||||||
" TC store!" << std::endl;
|
" TC store!" << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printError("CCSDSDistributor::initialize: Could not initialize"
|
sif::printError("CCSDSDistributor::initialize: Could not initialize"
|
||||||
" TC store!\n");
|
" TC store!\n");
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
status = RETURN_FAILED;
|
status = RETURN_FAILED;
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CCSDSDistributor::callbackAfterSending(
|
ReturnValue_t CCSDSDistributor::callbackAfterSending(
|
||||||
ReturnValue_t queueStatus) {
|
ReturnValue_t queueStatus) {
|
||||||
if (queueStatus != RETURN_OK) {
|
if (queueStatus != RETURN_OK) {
|
||||||
tcStore->deleteData(currentMessage.getStorageId());
|
tcStore->deleteData(currentMessage.getStorageId());
|
||||||
}
|
}
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
@ -15,56 +15,57 @@
|
|||||||
* The Secondary Header (with Service/Subservice) is ignored.
|
* The Secondary Header (with Service/Subservice) is ignored.
|
||||||
* @ingroup tc_distribution
|
* @ingroup tc_distribution
|
||||||
*/
|
*/
|
||||||
class CCSDSDistributor : public TcDistributor,
|
class CCSDSDistributor:
|
||||||
public CCSDSDistributorIF,
|
public TcDistributor,
|
||||||
public AcceptsTelecommandsIF {
|
public CCSDSDistributorIF,
|
||||||
|
public AcceptsTelecommandsIF {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief The constructor sets the default APID and calls the
|
* @brief The constructor sets the default APID and calls the
|
||||||
* TcDistributor ctor with a certain object id.
|
* TcDistributor ctor with a certain object id.
|
||||||
* @details
|
* @details
|
||||||
* @c tcStore is set in the @c initialize method.
|
* @c tcStore is set in the @c initialize method.
|
||||||
* @param setDefaultApid The default APID, where packets with unknown
|
* @param setDefaultApid The default APID, where packets with unknown
|
||||||
* destination are sent to.
|
* destination are sent to.
|
||||||
*/
|
*/
|
||||||
CCSDSDistributor(uint16_t setDefaultApid, object_id_t setObjectId);
|
CCSDSDistributor(uint16_t setDefaultApid, object_id_t setObjectId);
|
||||||
/**
|
/**
|
||||||
* The destructor is empty.
|
* The destructor is empty.
|
||||||
*/
|
*/
|
||||||
virtual ~CCSDSDistributor();
|
virtual ~CCSDSDistributor();
|
||||||
|
|
||||||
MessageQueueId_t getRequestQueue() override;
|
MessageQueueId_t getRequestQueue() override;
|
||||||
ReturnValue_t registerApplication( uint16_t apid,
|
ReturnValue_t registerApplication( uint16_t apid,
|
||||||
MessageQueueId_t id) override;
|
MessageQueueId_t id) override;
|
||||||
ReturnValue_t registerApplication(
|
ReturnValue_t registerApplication(
|
||||||
AcceptsTelecommandsIF* application) override;
|
AcceptsTelecommandsIF* application) override;
|
||||||
uint16_t getIdentifier() override;
|
uint16_t getIdentifier() override;
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* This implementation checks if an application with fitting APID has
|
* This implementation checks if an application with fitting APID has
|
||||||
* registered and forwards the packet to the according message queue.
|
* registered and forwards the packet to the according message queue.
|
||||||
* If the packet is not found, it returns the queue to @c defaultApid,
|
* If the packet is not found, it returns the queue to @c defaultApid,
|
||||||
* where a Acceptance Failure message should be generated.
|
* where a Acceptance Failure message should be generated.
|
||||||
* @return Iterator to map entry of found APID or iterator to default APID.
|
* @return Iterator to map entry of found APID or iterator to default APID.
|
||||||
*/
|
*/
|
||||||
TcMqMapIter selectDestination() override;
|
TcMqMapIter selectDestination() override;
|
||||||
/**
|
/**
|
||||||
* The callback here handles the generation of acceptance
|
* The callback here handles the generation of acceptance
|
||||||
* success/failure messages.
|
* success/failure messages.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t callbackAfterSending( ReturnValue_t queueStatus ) override;
|
ReturnValue_t callbackAfterSending( ReturnValue_t queueStatus ) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default APID, where packets with unknown APID are sent to.
|
* The default APID, where packets with unknown APID are sent to.
|
||||||
*/
|
*/
|
||||||
uint16_t defaultApid;
|
uint16_t defaultApid;
|
||||||
/**
|
/**
|
||||||
* A reference to the TC storage must be maintained, as this class handles
|
* A reference to the TC storage must be maintained, as this class handles
|
||||||
* pure Space Packets and there exists no SpacePacketStored class.
|
* pure Space Packets and there exists no SpacePacketStored class.
|
||||||
*/
|
*/
|
||||||
StorageManagerIF* tcStore = nullptr;
|
StorageManagerIF* tcStore = nullptr;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -13,31 +13,30 @@
|
|||||||
*/
|
*/
|
||||||
class CCSDSDistributorIF {
|
class CCSDSDistributorIF {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* With this call, a class implementing the CCSDSApplicationIF can register
|
* With this call, a class implementing the CCSDSApplicationIF can register
|
||||||
* at the distributor.
|
* at the distributor.
|
||||||
* @param application A pointer to the Application to register.
|
* @param application A pointer to the Application to register.
|
||||||
* @return - @c RETURN_OK on success,
|
* @return - @c RETURN_OK on success,
|
||||||
* - @c RETURN_FAILED on failure.
|
* - @c RETURN_FAILED on failure.
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t registerApplication(
|
virtual ReturnValue_t registerApplication(
|
||||||
AcceptsTelecommandsIF* application) = 0;
|
AcceptsTelecommandsIF* application) = 0;
|
||||||
/**
|
/**
|
||||||
* With this call, other Applications can register to the CCSDS distributor.
|
* With this call, other Applications can register to the CCSDS distributor.
|
||||||
* This is done by passing an APID and a MessageQueueId to the method.
|
* This is done by passing an APID and a MessageQueueId to the method.
|
||||||
* @param apid The APID to register.
|
* @param apid The APID to register.
|
||||||
* @param id The MessageQueueId of the message queue to send the
|
* @param id The MessageQueueId of the message queue to send the
|
||||||
* TC Packets to.
|
* TC Packets to.
|
||||||
* @return - @c RETURN_OK on success,
|
* @return - @c RETURN_OK on success,
|
||||||
* - @c RETURN_FAILED on failure.
|
* - @c RETURN_FAILED on failure.
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t registerApplication( uint16_t apid,
|
virtual ReturnValue_t registerApplication( uint16_t apid,
|
||||||
MessageQueueId_t id) = 0;
|
MessageQueueId_t id) = 0;
|
||||||
/**
|
/**
|
||||||
* The empty virtual destructor.
|
* 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);
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user