Compare commits
1 Commits
develop
...
fixed-arra
Author | SHA1 | Date | |
---|---|---|---|
5c29635029 |
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,5 +1,5 @@
|
||||||
# PyCharm and CLion
|
# PyCharm and CLion
|
||||||
.idea/*
|
/.idea/*
|
||||||
!/.idea/runConfigurations
|
!/.idea/runConfigurations
|
||||||
!/.idea/cmake.xml
|
!/.idea/cmake.xml
|
||||||
!/.idea/codeStyles
|
!/.idea/codeStyles
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="CMakeSharedSettings">
|
|
||||||
<configurations>
|
|
||||||
<configuration PROFILE_NAME="Debug Test" ENABLED="true" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DFSFW_OSAL=host -DFSFW_BUILD_TESTS=ON" NO_GENERATOR="true" />
|
|
||||||
</configurations>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
18
CHANGELOG.md
18
CHANGELOG.md
|
@ -10,9 +10,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
## Fixes
|
## Fixes
|
||||||
|
|
||||||
- FreshDeviceHandlerBase did not initialize the fdirInstance
|
|
||||||
- The `PusTmCreator` API only accepted 255 bytes of source data. It can now accept source
|
|
||||||
data with a size limited only by the size of `size_t`.
|
|
||||||
- Important bugfix in CFDP PDU header format: The entity length field and the transaction sequence
|
- Important bugfix in CFDP PDU header format: The entity length field and the transaction sequence
|
||||||
number fields stored the actual length of the field instead of the length minus 1 like specified
|
number fields stored the actual length of the field instead of the length minus 1 like specified
|
||||||
in the CFDP standard.
|
in the CFDP standard.
|
||||||
|
@ -29,13 +26,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
- add CFDP subsystem ID
|
- add CFDP subsystem ID
|
||||||
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/742
|
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/742
|
||||||
- `PusTmZcWriter` now exposes API to set message counter field.
|
- `PusTmZcWriter` now exposes API to set message counter field.
|
||||||
- Relative timeshift in the PUS time service.
|
|
||||||
|
|
||||||
## Changed
|
## Changed
|
||||||
|
|
||||||
- The PUS time service now dumps the time before setting a new time and after having set the
|
|
||||||
time.
|
|
||||||
- HK generation is now countdown based.
|
|
||||||
- Bump ETL version to 20.35.14
|
- Bump ETL version to 20.35.14
|
||||||
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/748
|
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/748
|
||||||
- Renamed `PCDU_2` subsystem ID to `POWER_SWITCH_IF`.
|
- Renamed `PCDU_2` subsystem ID to `POWER_SWITCH_IF`.
|
||||||
|
@ -45,16 +37,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
- Assert that `FixedArrayList` is larger than 0 at compile time.
|
- Assert that `FixedArrayList` is larger than 0 at compile time.
|
||||||
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/740
|
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/740
|
||||||
- Health functions are virtual now.
|
- Health functions are virtual now.
|
||||||
- PUS Service Base request queue depth and maximum number of handled packets per cycle is now
|
|
||||||
configurable.
|
|
||||||
|
|
||||||
## Added
|
|
||||||
|
|
||||||
- `EventManager`: Add function to print all listeners.
|
|
||||||
|
|
||||||
## Changed
|
|
||||||
|
|
||||||
- `EventManager`: Queue depth is configurable now
|
|
||||||
|
|
||||||
# [v6.0.0] 2023-02-10
|
# [v6.0.0] 2023-02-10
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ set(FSFW_ETL_LIB_MAJOR_VERSION
|
||||||
20
|
20
|
||||||
CACHE STRING "ETL library major version requirement")
|
CACHE STRING "ETL library major version requirement")
|
||||||
set(FSFW_ETL_LIB_VERSION
|
set(FSFW_ETL_LIB_VERSION
|
||||||
${FSFW_ETL_LIB_MAJOR_VERSION}.36.0
|
${FSFW_ETL_LIB_MAJOR_VERSION}.35.14
|
||||||
CACHE STRING "ETL library exact version requirement")
|
CACHE STRING "ETL library exact version requirement")
|
||||||
set(FSFW_ETL_LINK_TARGET etl::etl)
|
set(FSFW_ETL_LINK_TARGET etl::etl)
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ set(FSFW_CATCH2_LIB_MAJOR_VERSION
|
||||||
3
|
3
|
||||||
CACHE STRING "Catch2 library major version requirement")
|
CACHE STRING "Catch2 library major version requirement")
|
||||||
set(FSFW_CATCH2_LIB_VERSION
|
set(FSFW_CATCH2_LIB_VERSION
|
||||||
v${FSFW_CATCH2_LIB_MAJOR_VERSION}.3.2
|
v${FSFW_CATCH2_LIB_MAJOR_VERSION}.1.0
|
||||||
CACHE STRING "Catch2 library exact version requirement")
|
CACHE STRING "Catch2 library exact version requirement")
|
||||||
|
|
||||||
# Keep this off by default for now. See PR:
|
# Keep this off by default for now. See PR:
|
||||||
|
|
4
automation/Jenkinsfile
vendored
4
automation/Jenkinsfile
vendored
|
@ -97,7 +97,7 @@ pipeline {
|
||||||
sh 'rsync -r --delete docs/sphinx/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/development'
|
sh 'rsync -r --delete docs/sphinx/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/development'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dir(BUILDDIR_LINUX) {
|
dir(BUILDDIR) {
|
||||||
sshagent(credentials: ['documentation-buildfix']) {
|
sshagent(credentials: ['documentation-buildfix']) {
|
||||||
sh 'rsync -r --delete fsfw-tests_coverage/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/coverage/development'
|
sh 'rsync -r --delete fsfw-tests_coverage/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/coverage/development'
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@ pipeline {
|
||||||
sh 'rsync -r --delete docs/sphinx/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/master'
|
sh 'rsync -r --delete docs/sphinx/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/master'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dir(BUILDDIR_LINUX) {
|
dir(BUILDDIR) {
|
||||||
sshagent(credentials: ['documentation-buildfix']) {
|
sshagent(credentials: ['documentation-buildfix']) {
|
||||||
sh 'rsync -r --delete fsfw-tests_coverage/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/coverage/master'
|
sh 'rsync -r --delete fsfw-tests_coverage/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/coverage/master'
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ add_subdirectory(timemanager)
|
||||||
add_subdirectory(tmtcpacket)
|
add_subdirectory(tmtcpacket)
|
||||||
add_subdirectory(tmtcservices)
|
add_subdirectory(tmtcservices)
|
||||||
add_subdirectory(filesystem)
|
add_subdirectory(filesystem)
|
||||||
add_subdirectory(util)
|
|
||||||
|
|
||||||
# Optional
|
# Optional
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,8 @@ CfdpMessage::CfdpMessage() = default;
|
||||||
|
|
||||||
CfdpMessage::~CfdpMessage() = default;
|
CfdpMessage::~CfdpMessage() = default;
|
||||||
|
|
||||||
void CfdpMessage::setPutRequest(CommandMessage *message, store_address_t putRequest) {
|
void CfdpMessage::setCommand(CommandMessage *message, store_address_t cfdpPacket) {
|
||||||
message->setCommand(PUT_REQUEST);
|
message->setParameter(cfdpPacket.raw);
|
||||||
message->setParameter(putRequest.raw);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
store_address_t CfdpMessage::getStoreId(const CommandMessage *message) {
|
store_address_t CfdpMessage::getStoreId(const CommandMessage *message) {
|
||||||
|
|
|
@ -11,11 +11,9 @@ class CfdpMessage {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const uint8_t MESSAGE_ID = messagetypes::CFDP;
|
static const uint8_t MESSAGE_ID = messagetypes::CFDP;
|
||||||
static const Command_t PUT_REQUEST = MAKE_COMMAND_ID(1);
|
|
||||||
static const Command_t CANCEL_REQUEST = MAKE_COMMAND_ID(1);
|
|
||||||
|
|
||||||
virtual ~CfdpMessage();
|
virtual ~CfdpMessage();
|
||||||
static void setPutRequest(CommandMessage* message, store_address_t putRequest);
|
static void setCommand(CommandMessage* message, store_address_t cfdpPacket);
|
||||||
|
|
||||||
static store_address_t getStoreId(const CommandMessage* message);
|
static store_address_t getStoreId(const CommandMessage* message);
|
||||||
|
|
||||||
|
|
|
@ -8,14 +8,11 @@
|
||||||
|
|
||||||
namespace cfdp {
|
namespace cfdp {
|
||||||
|
|
||||||
/**
|
struct FileSize : public SerializeIF {
|
||||||
* Helper type for the CFDP File Size Sensitive (FSS) fields.
|
|
||||||
*/
|
|
||||||
struct Fss : public SerializeIF {
|
|
||||||
public:
|
public:
|
||||||
Fss() = default;
|
FileSize() = default;
|
||||||
|
|
||||||
explicit Fss(uint64_t fileSize, bool isLarge = false) { setFileSize(fileSize, isLarge); };
|
explicit FileSize(uint64_t fileSize, bool isLarge = false) { setFileSize(fileSize, isLarge); };
|
||||||
|
|
||||||
[[nodiscard]] uint64_t value() const { return fileSize; }
|
[[nodiscard]] uint64_t value() const { return fileSize; }
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
#include "fsfw/serialize/SerializeAdapter.h"
|
#include "fsfw/serialize/SerializeAdapter.h"
|
||||||
#include "fsfw/serviceinterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
cfdp::VarLenField::VarLenField(cfdp::WidthInBytes width, uint64_t value) : VarLenField() {
|
cfdp::VarLenField::VarLenField(cfdp::WidthInBytes width, size_t value) : VarLenField() {
|
||||||
ReturnValue_t result = this->setValueAndWidth(width, value);
|
ReturnValue_t result = this->setValue(width, value);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
#if FSFW_DISABLE_PRINTOUT == 0
|
#if FSFW_DISABLE_PRINTOUT == 0
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
@ -20,8 +20,8 @@ cfdp::VarLenField::VarLenField() : width(cfdp::WidthInBytes::ONE_BYTE) { value.o
|
||||||
|
|
||||||
cfdp::WidthInBytes cfdp::VarLenField::getWidth() const { return width; }
|
cfdp::WidthInBytes cfdp::VarLenField::getWidth() const { return width; }
|
||||||
|
|
||||||
ReturnValue_t cfdp::VarLenField::setValueAndWidth(cfdp::WidthInBytes width_, uint64_t value_) {
|
ReturnValue_t cfdp::VarLenField::setValue(cfdp::WidthInBytes widthInBytes, size_t value_) {
|
||||||
switch (width_) {
|
switch (widthInBytes) {
|
||||||
case (cfdp::WidthInBytes::ONE_BYTE): {
|
case (cfdp::WidthInBytes::ONE_BYTE): {
|
||||||
if (value_ > UINT8_MAX) {
|
if (value_ > UINT8_MAX) {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
|
@ -43,18 +43,15 @@ ReturnValue_t cfdp::VarLenField::setValueAndWidth(cfdp::WidthInBytes width_, uin
|
||||||
this->value.fourBytes = value_;
|
this->value.fourBytes = value_;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (cfdp::WidthInBytes::EIGHT_BYTES): {
|
|
||||||
this->value.eightBytes = value_;
|
|
||||||
}
|
|
||||||
default: {
|
default: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this->width = width_;
|
this->width = widthInBytes;
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t cfdp::VarLenField::getValue() const {
|
size_t cfdp::VarLenField::getValue() const {
|
||||||
switch (width) {
|
switch (width) {
|
||||||
case (cfdp::WidthInBytes::ONE_BYTE): {
|
case (cfdp::WidthInBytes::ONE_BYTE): {
|
||||||
return value.oneByte;
|
return value.oneByte;
|
||||||
|
@ -65,9 +62,6 @@ uint64_t cfdp::VarLenField::getValue() const {
|
||||||
case (cfdp::WidthInBytes::FOUR_BYTES): {
|
case (cfdp::WidthInBytes::FOUR_BYTES): {
|
||||||
return value.fourBytes;
|
return value.fourBytes;
|
||||||
}
|
}
|
||||||
case (cfdp::WidthInBytes::EIGHT_BYTES): {
|
|
||||||
return value.eightBytes;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -90,10 +84,6 @@ ReturnValue_t cfdp::VarLenField::serialize(uint8_t **buffer, size_t *size, size_
|
||||||
case (cfdp::WidthInBytes::FOUR_BYTES): {
|
case (cfdp::WidthInBytes::FOUR_BYTES): {
|
||||||
return SerializeAdapter::serialize(&value.fourBytes, buffer, size, maxSize, streamEndianness);
|
return SerializeAdapter::serialize(&value.fourBytes, buffer, size, maxSize, streamEndianness);
|
||||||
}
|
}
|
||||||
case (cfdp::WidthInBytes::EIGHT_BYTES): {
|
|
||||||
return SerializeAdapter::serialize(&value.eightBytes, buffer, size, maxSize,
|
|
||||||
streamEndianness);
|
|
||||||
}
|
|
||||||
default: {
|
default: {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
@ -108,16 +98,11 @@ ReturnValue_t cfdp::VarLenField::deSerialize(cfdp::WidthInBytes width_, const ui
|
||||||
return deSerialize(buffer, size, streamEndianness);
|
return deSerialize(buffer, size, streamEndianness);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t cfdp::VarLenField::setValue(uint64_t value_) {
|
|
||||||
return setValueAndWidth(getWidth(), value_);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t cfdp::VarLenField::deSerialize(const uint8_t **buffer, size_t *size,
|
ReturnValue_t cfdp::VarLenField::deSerialize(const uint8_t **buffer, size_t *size,
|
||||||
Endianness streamEndianness) {
|
Endianness streamEndianness) {
|
||||||
switch (width) {
|
switch (width) {
|
||||||
case (cfdp::WidthInBytes::ONE_BYTE): {
|
case (cfdp::WidthInBytes::ONE_BYTE): {
|
||||||
value.oneByte = **buffer;
|
value.oneByte = **buffer;
|
||||||
*buffer += 1;
|
|
||||||
*size += 1;
|
*size += 1;
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
@ -127,9 +112,6 @@ ReturnValue_t cfdp::VarLenField::deSerialize(const uint8_t **buffer, size_t *siz
|
||||||
case (cfdp::WidthInBytes::FOUR_BYTES): {
|
case (cfdp::WidthInBytes::FOUR_BYTES): {
|
||||||
return SerializeAdapter::deSerialize(&value.fourBytes, buffer, size, streamEndianness);
|
return SerializeAdapter::deSerialize(&value.fourBytes, buffer, size, streamEndianness);
|
||||||
}
|
}
|
||||||
case (cfdp::WidthInBytes::EIGHT_BYTES): {
|
|
||||||
return SerializeAdapter::deSerialize(&value.eightBytes, buffer, size, streamEndianness);
|
|
||||||
}
|
|
||||||
default: {
|
default: {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
@ -153,5 +135,3 @@ bool cfdp::VarLenField::operator==(const cfdp::VarLenField &other) const {
|
||||||
bool cfdp::VarLenField::operator!=(const cfdp::VarLenField &other) const {
|
bool cfdp::VarLenField::operator!=(const cfdp::VarLenField &other) const {
|
||||||
return not(*this == other);
|
return not(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cfdp::VarLenField::setWidth(cfdp::WidthInBytes width_) { this->width = width_; }
|
|
||||||
|
|
|
@ -25,15 +25,13 @@ class VarLenField : public SerializeIF {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
explicit VarLenField(UnsignedByteField<T> byteField);
|
explicit VarLenField(UnsignedByteField<T> byteField);
|
||||||
|
|
||||||
VarLenField(cfdp::WidthInBytes width, uint64_t value);
|
VarLenField(cfdp::WidthInBytes width, size_t value);
|
||||||
|
|
||||||
bool operator==(const VarLenField &other) const;
|
bool operator==(const VarLenField &other) const;
|
||||||
bool operator!=(const VarLenField &other) const;
|
bool operator!=(const VarLenField &other) const;
|
||||||
bool operator<(const VarLenField &other) const;
|
bool operator<(const VarLenField &other) const;
|
||||||
|
|
||||||
ReturnValue_t setValueAndWidth(cfdp::WidthInBytes width, uint64_t value);
|
ReturnValue_t setValue(cfdp::WidthInBytes, size_t value);
|
||||||
void setWidth(cfdp::WidthInBytes width);
|
|
||||||
ReturnValue_t setValue(uint64_t value);
|
|
||||||
|
|
||||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||||
Endianness streamEndianness) const override;
|
Endianness streamEndianness) const override;
|
||||||
|
@ -44,7 +42,7 @@ class VarLenField : public SerializeIF {
|
||||||
Endianness streamEndianness);
|
Endianness streamEndianness);
|
||||||
|
|
||||||
[[nodiscard]] cfdp::WidthInBytes getWidth() const;
|
[[nodiscard]] cfdp::WidthInBytes getWidth() const;
|
||||||
[[nodiscard]] uint64_t getValue() const;
|
[[nodiscard]] size_t getValue() const;
|
||||||
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
friend std::ostream &operator<<(std::ostream &os, const VarLenField &id) {
|
friend std::ostream &operator<<(std::ostream &os, const VarLenField &id) {
|
||||||
|
@ -53,9 +51,8 @@ class VarLenField : public SerializeIF {
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using SerializeIF::deSerialize; // we overloaded above, so this is needed to uncofuse the
|
|
||||||
// compiler
|
|
||||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||||
Endianness streamEndianness) override;
|
Endianness streamEndianness) override;
|
||||||
|
|
||||||
|
@ -67,7 +64,7 @@ template <typename T>
|
||||||
cfdp::VarLenField::VarLenField(UnsignedByteField<T> byteField)
|
cfdp::VarLenField::VarLenField(UnsignedByteField<T> byteField)
|
||||||
: width(static_cast<cfdp::WidthInBytes>(sizeof(T))) {
|
: width(static_cast<cfdp::WidthInBytes>(sizeof(T))) {
|
||||||
static_assert((sizeof(T) % 2) == 0);
|
static_assert((sizeof(T) % 2) == 0);
|
||||||
setValueAndWidth(width, byteField.getValue());
|
setValue(width, byteField.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EntityId : public VarLenField {
|
struct EntityId : public VarLenField {
|
||||||
|
@ -76,32 +73,6 @@ struct EntityId : public VarLenField {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
explicit EntityId(UnsignedByteField<T> byteField) : VarLenField(byteField) {}
|
explicit EntityId(UnsignedByteField<T> byteField) : VarLenField(byteField) {}
|
||||||
EntityId(cfdp::WidthInBytes width, size_t entityId) : VarLenField(width, entityId) {}
|
EntityId(cfdp::WidthInBytes width, size_t entityId) : VarLenField(width, entityId) {}
|
||||||
|
|
||||||
ReturnValue_t serializeAsLv(uint8_t **buffer, size_t *size, size_t maxSize) const {
|
|
||||||
if (buffer == nullptr or size == nullptr) {
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
if (*size + 1 + getWidth() > maxSize) {
|
|
||||||
return SerializeIF::BUFFER_TOO_SHORT;
|
|
||||||
}
|
|
||||||
**buffer = getWidth();
|
|
||||||
*buffer += 1;
|
|
||||||
*size += 1;
|
|
||||||
return serialize(buffer, size, maxSize, SerializeIF::Endianness::NETWORK);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t deSerializeFromLv(const uint8_t **buffer, size_t *deserLen) {
|
|
||||||
if (buffer == nullptr or deserLen == nullptr) {
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
if (*deserLen < 2) {
|
|
||||||
return SerializeIF::STREAM_TOO_SHORT;
|
|
||||||
}
|
|
||||||
auto width = static_cast<WidthInBytes>(**buffer);
|
|
||||||
*buffer += 1;
|
|
||||||
*deserLen -= 1;
|
|
||||||
return VarLenField::deSerialize(width, buffer, deserLen, SerializeIF::Endianness::NETWORK);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TransactionSeqNum : public VarLenField {
|
struct TransactionSeqNum : public VarLenField {
|
||||||
|
|
|
@ -17,7 +17,7 @@ static constexpr char CFDP_VERSION_2_NAME[] = "CCSDS 727.0-B-5";
|
||||||
static constexpr uint8_t CFDP_VERSION_2 = 0b001;
|
static constexpr uint8_t CFDP_VERSION_2 = 0b001;
|
||||||
static constexpr uint8_t VERSION_BITS = CFDP_VERSION_2 << 5;
|
static constexpr uint8_t VERSION_BITS = CFDP_VERSION_2 << 5;
|
||||||
|
|
||||||
static constexpr uint8_t CFDP_CLASS_ID = CLASS_ID::CFDP_BASE;
|
static constexpr uint8_t CFDP_CLASS_ID = CLASS_ID::CFDP;
|
||||||
|
|
||||||
static constexpr ReturnValue_t INVALID_TLV_TYPE = returnvalue::makeCode(CFDP_CLASS_ID, 1);
|
static constexpr ReturnValue_t INVALID_TLV_TYPE = returnvalue::makeCode(CFDP_CLASS_ID, 1);
|
||||||
static constexpr ReturnValue_t INVALID_DIRECTIVE_FIELD = returnvalue::makeCode(CFDP_CLASS_ID, 2);
|
static constexpr ReturnValue_t INVALID_DIRECTIVE_FIELD = returnvalue::makeCode(CFDP_CLASS_ID, 2);
|
||||||
|
@ -68,7 +68,6 @@ enum WidthInBytes : uint8_t {
|
||||||
ONE_BYTE = 1,
|
ONE_BYTE = 1,
|
||||||
TWO_BYTES = 2,
|
TWO_BYTES = 2,
|
||||||
FOUR_BYTES = 4,
|
FOUR_BYTES = 4,
|
||||||
EIGHT_BYTES = 8
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum FileDirective : uint8_t {
|
enum FileDirective : uint8_t {
|
||||||
|
@ -143,20 +142,6 @@ enum RecordContinuationState {
|
||||||
CONTAINS_START_AND_END = 0b11
|
CONTAINS_START_AND_END = 0b11
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ProxyOpMessageType : uint8_t {
|
|
||||||
PUT_REQUEST = 0x00,
|
|
||||||
MSG_TO_USR = 0x01,
|
|
||||||
FS_REQUEST = 0x02,
|
|
||||||
FAULT_HANDLER_OVERRIDE = 0x03,
|
|
||||||
TRANSMISSION_MODE = 0x04,
|
|
||||||
FLOW_LABEL = 0x05,
|
|
||||||
SEG_CTRL = 0x06,
|
|
||||||
PUT_RESPONSE = 0x07,
|
|
||||||
FS_RESPONSE = 0x08,
|
|
||||||
PUT_CANCEL = 0x09,
|
|
||||||
CLOSURE = 0x0b
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace cfdp
|
} // namespace cfdp
|
||||||
|
|
||||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_DEFINITIONS_H_ */
|
#endif /* FSFW_SRC_FSFW_CFDP_PDU_DEFINITIONS_H_ */
|
||||||
|
|
|
@ -1,4 +1,2 @@
|
||||||
target_sources(
|
target_sources(${LIB_FSFW_NAME} PRIVATE SourceHandler.cpp DestHandler.cpp
|
||||||
${LIB_FSFW_NAME}
|
FaultHandlerBase.cpp UserBase.cpp)
|
||||||
PRIVATE SourceHandler.cpp DestHandler.cpp PutRequest.cpp
|
|
||||||
ReservedMessageParser.cpp FaultHandlerBase.cpp UserBase.cpp)
|
|
||||||
|
|
|
@ -16,26 +16,25 @@ using namespace returnvalue;
|
||||||
|
|
||||||
cfdp::DestHandler::DestHandler(DestHandlerParams params, FsfwParams fsfwParams)
|
cfdp::DestHandler::DestHandler(DestHandlerParams params, FsfwParams fsfwParams)
|
||||||
: tlvVec(params.maxTlvsInOnePdu),
|
: tlvVec(params.maxTlvsInOnePdu),
|
||||||
msgToUserVec(params.maxTlvsInOnePdu),
|
userTlvVec(params.maxTlvsInOnePdu),
|
||||||
transactionParams(params.maxFilenameLen),
|
dp(std::move(params)),
|
||||||
destParams(std::move(params)),
|
fp(fsfwParams),
|
||||||
fsfwParams(fsfwParams) {
|
tp(params.maxFilenameLen) {
|
||||||
transactionParams.pduConf.direction = cfdp::Direction::TOWARDS_SENDER;
|
tp.pduConf.direction = cfdp::Direction::TOWARDS_SENDER;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cfdp::DestHandler::FsmResult& cfdp::DestHandler::stateMachine() {
|
const cfdp::DestHandler::FsmResult& cfdp::DestHandler::performStateMachine() {
|
||||||
ReturnValue_t result;
|
ReturnValue_t result;
|
||||||
uint8_t errorIdx = 0;
|
uint8_t errorIdx = 0;
|
||||||
fsmRes.resetOfIteration();
|
fsmRes.resetOfIteration();
|
||||||
if (fsmRes.step == TransactionStep::IDLE) {
|
if (fsmRes.step == TransactionStep::IDLE) {
|
||||||
for (auto infoIter = destParams.packetListRef.begin();
|
for (auto infoIter = dp.packetListRef.begin(); infoIter != dp.packetListRef.end();) {
|
||||||
infoIter != destParams.packetListRef.end();) {
|
|
||||||
if (infoIter->pduType == PduType::FILE_DIRECTIVE and
|
if (infoIter->pduType == PduType::FILE_DIRECTIVE and
|
||||||
infoIter->directiveType == FileDirective::METADATA) {
|
infoIter->directiveType == FileDirective::METADATA) {
|
||||||
result = handleMetadataPdu(*infoIter);
|
result = handleMetadataPdu(*infoIter);
|
||||||
checkAndHandleError(result, errorIdx);
|
checkAndHandleError(result, errorIdx);
|
||||||
// Store data was deleted in PDU handler because a store guard is used
|
// Store data was deleted in PDU handler because a store guard is used
|
||||||
destParams.packetListRef.erase(infoIter++);
|
dp.packetListRef.erase(infoIter++);
|
||||||
} else {
|
} else {
|
||||||
infoIter++;
|
infoIter++;
|
||||||
}
|
}
|
||||||
|
@ -43,12 +42,11 @@ const cfdp::DestHandler::FsmResult& cfdp::DestHandler::stateMachine() {
|
||||||
if (fsmRes.step == TransactionStep::IDLE) {
|
if (fsmRes.step == TransactionStep::IDLE) {
|
||||||
// To decrease the already high complexity of the software, all packets arriving before
|
// To decrease the already high complexity of the software, all packets arriving before
|
||||||
// a metadata PDU are deleted.
|
// a metadata PDU are deleted.
|
||||||
for (auto infoIter = destParams.packetListRef.begin();
|
for (auto infoIter = dp.packetListRef.begin(); infoIter != dp.packetListRef.end();) {
|
||||||
infoIter != destParams.packetListRef.end();) {
|
fp.tcStore->deleteData(infoIter->storeId);
|
||||||
fsfwParams.tcStore->deleteData(infoIter->storeId);
|
|
||||||
infoIter++;
|
infoIter++;
|
||||||
}
|
}
|
||||||
destParams.packetListRef.clear();
|
dp.packetListRef.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fsmRes.step != TransactionStep::IDLE) {
|
if (fsmRes.step != TransactionStep::IDLE) {
|
||||||
|
@ -56,22 +54,21 @@ const cfdp::DestHandler::FsmResult& cfdp::DestHandler::stateMachine() {
|
||||||
}
|
}
|
||||||
return updateFsmRes(errorIdx);
|
return updateFsmRes(errorIdx);
|
||||||
}
|
}
|
||||||
if (fsmRes.state == CfdpState::BUSY_CLASS_1_NACKED) {
|
if (fsmRes.state == CfdpStates::BUSY_CLASS_1_NACKED) {
|
||||||
if (fsmRes.step == TransactionStep::RECEIVING_FILE_DATA_PDUS) {
|
if (fsmRes.step == TransactionStep::RECEIVING_FILE_DATA_PDUS) {
|
||||||
for (auto infoIter = destParams.packetListRef.begin();
|
for (auto infoIter = dp.packetListRef.begin(); infoIter != dp.packetListRef.end();) {
|
||||||
infoIter != destParams.packetListRef.end();) {
|
|
||||||
if (infoIter->pduType == PduType::FILE_DATA) {
|
if (infoIter->pduType == PduType::FILE_DATA) {
|
||||||
result = handleFileDataPdu(*infoIter);
|
result = handleFileDataPdu(*infoIter);
|
||||||
checkAndHandleError(result, errorIdx);
|
checkAndHandleError(result, errorIdx);
|
||||||
// Store data was deleted in PDU handler because a store guard is used
|
// Store data was deleted in PDU handler because a store guard is used
|
||||||
destParams.packetListRef.erase(infoIter++);
|
dp.packetListRef.erase(infoIter++);
|
||||||
} else if (infoIter->pduType == PduType::FILE_DIRECTIVE and
|
} else if (infoIter->pduType == PduType::FILE_DIRECTIVE and
|
||||||
infoIter->directiveType == FileDirective::EOF_DIRECTIVE) {
|
infoIter->directiveType == FileDirective::EOF_DIRECTIVE) {
|
||||||
// TODO: Support for check timer missing
|
// TODO: Support for check timer missing
|
||||||
result = handleEofPdu(*infoIter);
|
result = handleEofPdu(*infoIter);
|
||||||
checkAndHandleError(result, errorIdx);
|
checkAndHandleError(result, errorIdx);
|
||||||
// Store data was deleted in PDU handler because a store guard is used
|
// Store data was deleted in PDU handler because a store guard is used
|
||||||
destParams.packetListRef.erase(infoIter++);
|
dp.packetListRef.erase(infoIter++);
|
||||||
} else {
|
} else {
|
||||||
infoIter++;
|
infoIter++;
|
||||||
}
|
}
|
||||||
|
@ -88,7 +85,7 @@ const cfdp::DestHandler::FsmResult& cfdp::DestHandler::stateMachine() {
|
||||||
}
|
}
|
||||||
return updateFsmRes(errorIdx);
|
return updateFsmRes(errorIdx);
|
||||||
}
|
}
|
||||||
if (fsmRes.state == CfdpState::BUSY_CLASS_2_ACKED) {
|
if (fsmRes.state == CfdpStates::BUSY_CLASS_2_ACKED) {
|
||||||
// TODO: Will be implemented at a later stage
|
// TODO: Will be implemented at a later stage
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "CFDP state machine for acknowledged mode not implemented yet" << std::endl;
|
sif::warning << "CFDP state machine for acknowledged mode not implemented yet" << std::endl;
|
||||||
|
@ -98,29 +95,29 @@ const cfdp::DestHandler::FsmResult& cfdp::DestHandler::stateMachine() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t cfdp::DestHandler::passPacket(PacketInfo packet) {
|
ReturnValue_t cfdp::DestHandler::passPacket(PacketInfo packet) {
|
||||||
if (destParams.packetListRef.full()) {
|
if (dp.packetListRef.full()) {
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
destParams.packetListRef.push_back(packet);
|
dp.packetListRef.push_back(packet);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t cfdp::DestHandler::initialize() {
|
ReturnValue_t cfdp::DestHandler::initialize() {
|
||||||
if (fsfwParams.tmStore == nullptr) {
|
if (fp.tmStore == nullptr) {
|
||||||
fsfwParams.tmStore = ObjectManager::instance()->get<StorageManagerIF>(objects::TM_STORE);
|
fp.tmStore = ObjectManager::instance()->get<StorageManagerIF>(objects::TM_STORE);
|
||||||
if (fsfwParams.tmStore == nullptr) {
|
if (fp.tmStore == nullptr) {
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fsfwParams.tcStore == nullptr) {
|
if (fp.tcStore == nullptr) {
|
||||||
fsfwParams.tcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::TC_STORE);
|
fp.tcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::TC_STORE);
|
||||||
if (fsfwParams.tcStore == nullptr) {
|
if (fp.tcStore == nullptr) {
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fsfwParams.msgQueue == nullptr) {
|
if (fp.msgQueue == nullptr) {
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
|
@ -128,16 +125,18 @@ ReturnValue_t cfdp::DestHandler::initialize() {
|
||||||
|
|
||||||
ReturnValue_t cfdp::DestHandler::handleMetadataPdu(const PacketInfo& info) {
|
ReturnValue_t cfdp::DestHandler::handleMetadataPdu(const PacketInfo& info) {
|
||||||
// Process metadata PDU
|
// Process metadata PDU
|
||||||
auto constAccessorPair = fsfwParams.tcStore->getData(info.storeId);
|
auto constAccessorPair = fp.tcStore->getData(info.storeId);
|
||||||
if (constAccessorPair.first != OK) {
|
if (constAccessorPair.first != OK) {
|
||||||
// TODO: This is not a CFDP error. Event and/or warning?
|
// TODO: This is not a CFDP error. Event and/or warning?
|
||||||
return constAccessorPair.first;
|
return constAccessorPair.first;
|
||||||
}
|
}
|
||||||
cfdp::StringLv sourceFileName;
|
cfdp::StringLv sourceFileName;
|
||||||
cfdp::StringLv destFileName;
|
cfdp::StringLv destFileName;
|
||||||
MetadataGenericInfo metadataInfo(transactionParams.fileSize);
|
MetadataInfo metadataInfo(tp.fileSize, sourceFileName, destFileName);
|
||||||
|
cfdp::Tlv* tlvArrayAsPtr = tlvVec.data();
|
||||||
|
metadataInfo.setOptionsArray(&tlvArrayAsPtr, std::nullopt, tlvVec.size());
|
||||||
MetadataPduReader reader(constAccessorPair.second.data(), constAccessorPair.second.size(),
|
MetadataPduReader reader(constAccessorPair.second.data(), constAccessorPair.second.size(),
|
||||||
metadataInfo, tlvVec.data(), tlvVec.size());
|
metadataInfo);
|
||||||
ReturnValue_t result = reader.parseData();
|
ReturnValue_t result = reader.parseData();
|
||||||
// TODO: The standard does not really specify what happens if this kind of error happens
|
// TODO: The standard does not really specify what happens if this kind of error happens
|
||||||
// I think it might be a good idea to cache some sort of error code, which
|
// I think it might be a good idea to cache some sort of error code, which
|
||||||
|
@ -146,17 +145,18 @@ ReturnValue_t cfdp::DestHandler::handleMetadataPdu(const PacketInfo& info) {
|
||||||
return handleMetadataParseError(result, constAccessorPair.second.data(),
|
return handleMetadataParseError(result, constAccessorPair.second.data(),
|
||||||
constAccessorPair.second.size());
|
constAccessorPair.second.size());
|
||||||
}
|
}
|
||||||
return startTransaction(reader);
|
return startTransaction(reader, metadataInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t cfdp::DestHandler::handleFileDataPdu(const cfdp::PacketInfo& info) {
|
ReturnValue_t cfdp::DestHandler::handleFileDataPdu(const cfdp::PacketInfo& info) {
|
||||||
// Process file data PDU
|
// Process file data PDU
|
||||||
auto constAccessorPair = fsfwParams.tcStore->getData(info.storeId);
|
auto constAccessorPair = fp.tcStore->getData(info.storeId);
|
||||||
if (constAccessorPair.first != OK) {
|
if (constAccessorPair.first != OK) {
|
||||||
// TODO: This is not a CFDP error. Event and/or warning?
|
// TODO: This is not a CFDP error. Event and/or warning?
|
||||||
return constAccessorPair.first;
|
return constAccessorPair.first;
|
||||||
}
|
}
|
||||||
FileDataInfo fdInfo;
|
cfdp::FileSize offset;
|
||||||
|
FileDataInfo fdInfo(offset);
|
||||||
FileDataReader reader(constAccessorPair.second.data(), constAccessorPair.second.size(), fdInfo);
|
FileDataReader reader(constAccessorPair.second.data(), constAccessorPair.second.size(), fdInfo);
|
||||||
ReturnValue_t result = reader.parseData();
|
ReturnValue_t result = reader.parseData();
|
||||||
if (result != OK) {
|
if (result != OK) {
|
||||||
|
@ -164,46 +164,46 @@ ReturnValue_t cfdp::DestHandler::handleFileDataPdu(const cfdp::PacketInfo& info)
|
||||||
}
|
}
|
||||||
size_t fileSegmentLen = 0;
|
size_t fileSegmentLen = 0;
|
||||||
const uint8_t* fileData = fdInfo.getFileData(&fileSegmentLen);
|
const uint8_t* fileData = fdInfo.getFileData(&fileSegmentLen);
|
||||||
FileOpParams fileOpParams(transactionParams.destName.data(), fileSegmentLen);
|
FileOpParams fileOpParams(tp.destName.data(), fileSegmentLen);
|
||||||
fileOpParams.offset = fdInfo.getOffset().value();
|
fileOpParams.offset = offset.value();
|
||||||
if (destParams.cfg.indicCfg.fileSegmentRecvIndicRequired) {
|
if (dp.cfg.indicCfg.fileSegmentRecvIndicRequired) {
|
||||||
FileSegmentRecvdParams segParams;
|
FileSegmentRecvdParams segParams;
|
||||||
segParams.offset = fdInfo.getOffset().value();
|
segParams.offset = offset.value();
|
||||||
segParams.id = transactionParams.transactionId;
|
segParams.id = tp.transactionId;
|
||||||
segParams.length = fileSegmentLen;
|
segParams.length = fileSegmentLen;
|
||||||
segParams.recContState = fdInfo.getRecordContinuationState();
|
segParams.recContState = fdInfo.getRecordContinuationState();
|
||||||
size_t segmentMetadatLen = 0;
|
size_t segmentMetadatLen = 0;
|
||||||
auto* segMetadata = fdInfo.getSegmentMetadata(&segmentMetadatLen);
|
auto* segMetadata = fdInfo.getSegmentMetadata(&segmentMetadatLen);
|
||||||
segParams.segmentMetadata = {segMetadata, segmentMetadatLen};
|
segParams.segmentMetadata = {segMetadata, segmentMetadatLen};
|
||||||
destParams.user.fileSegmentRecvdIndication(segParams);
|
dp.user.fileSegmentRecvdIndication(segParams);
|
||||||
}
|
}
|
||||||
result = destParams.user.vfs.writeToFile(fileOpParams, fileData);
|
result = dp.user.vfs.writeToFile(fileOpParams, fileData);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
// TODO: Proper Error handling
|
// TODO: Proper Error handling
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "cfdp::DestHandler: VFS file write error with code 0x" << std::hex << std::setw(2)
|
sif::error << "cfdp::DestHandler: VFS file write error with code 0x" << std::hex << std::setw(2)
|
||||||
<< result << std::endl;
|
<< result << std::endl;
|
||||||
#endif
|
#endif
|
||||||
transactionParams.vfsErrorCount++;
|
tp.vfsErrorCount++;
|
||||||
if (transactionParams.vfsErrorCount < 3) {
|
if (tp.vfsErrorCount < 3) {
|
||||||
// TODO: Provide execution step as parameter
|
// TODO: Provide execution step as parameter
|
||||||
fsfwParams.eventReporter->forwardEvent(events::FILESTORE_ERROR,
|
fp.eventReporter->forwardEvent(events::FILESTORE_ERROR, static_cast<uint8_t>(fsmRes.step),
|
||||||
static_cast<uint8_t>(fsmRes.step), result);
|
result);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
transactionParams.deliveryStatus = FileDeliveryStatus::RETAINED_IN_FILESTORE;
|
tp.deliveryStatus = FileDeliveryStatus::RETAINED_IN_FILESTORE;
|
||||||
transactionParams.vfsErrorCount = 0;
|
tp.vfsErrorCount = 0;
|
||||||
}
|
}
|
||||||
if (fdInfo.getOffset().value() + fileSegmentLen > transactionParams.progress) {
|
if (offset.value() + fileSegmentLen > tp.progress) {
|
||||||
transactionParams.progress = fdInfo.getOffset().value() + fileSegmentLen;
|
tp.progress = offset.value() + fileSegmentLen;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t cfdp::DestHandler::handleEofPdu(const cfdp::PacketInfo& info) {
|
ReturnValue_t cfdp::DestHandler::handleEofPdu(const cfdp::PacketInfo& info) {
|
||||||
// Process EOF PDU
|
// Process EOF PDU
|
||||||
auto constAccessorPair = fsfwParams.tcStore->getData(info.storeId);
|
auto constAccessorPair = fp.tcStore->getData(info.storeId);
|
||||||
if (constAccessorPair.first != OK) {
|
if (constAccessorPair.first != OK) {
|
||||||
// TODO: This is not a CFDP error. Event and/or warning?
|
// TODO: This is not a CFDP error. Event and/or warning?
|
||||||
return constAccessorPair.first;
|
return constAccessorPair.first;
|
||||||
|
@ -216,21 +216,21 @@ ReturnValue_t cfdp::DestHandler::handleEofPdu(const cfdp::PacketInfo& info) {
|
||||||
}
|
}
|
||||||
// TODO: Error handling
|
// TODO: Error handling
|
||||||
if (eofInfo.getConditionCode() == ConditionCode::NO_ERROR) {
|
if (eofInfo.getConditionCode() == ConditionCode::NO_ERROR) {
|
||||||
transactionParams.crc = eofInfo.getChecksum();
|
tp.crc = eofInfo.getChecksum();
|
||||||
uint64_t fileSizeFromEof = eofInfo.getFileSize().value();
|
uint64_t fileSizeFromEof = eofInfo.getFileSize().value();
|
||||||
// CFDP 4.6.1.2.9: Declare file size error if progress exceeds file size
|
// CFDP 4.6.1.2.9: Declare file size error if progress exceeds file size
|
||||||
if (fileSizeFromEof > transactionParams.progress) {
|
if (fileSizeFromEof > tp.progress) {
|
||||||
// TODO: File size error
|
// TODO: File size error
|
||||||
}
|
}
|
||||||
transactionParams.fileSize.setFileSize(fileSizeFromEof, std::nullopt);
|
tp.fileSize.setFileSize(fileSizeFromEof, std::nullopt);
|
||||||
}
|
}
|
||||||
if (destParams.cfg.indicCfg.eofRecvIndicRequired) {
|
if (dp.cfg.indicCfg.eofRecvIndicRequired) {
|
||||||
destParams.user.eofRecvIndication(getTransactionId());
|
dp.user.eofRecvIndication(getTransactionId());
|
||||||
}
|
}
|
||||||
if (fsmRes.step == TransactionStep::RECEIVING_FILE_DATA_PDUS) {
|
if (fsmRes.step == TransactionStep::RECEIVING_FILE_DATA_PDUS) {
|
||||||
if (fsmRes.state == CfdpState::BUSY_CLASS_1_NACKED) {
|
if (fsmRes.state == CfdpStates::BUSY_CLASS_1_NACKED) {
|
||||||
fsmRes.step = TransactionStep::TRANSFER_COMPLETION;
|
fsmRes.step = TransactionStep::TRANSFER_COMPLETION;
|
||||||
} else if (fsmRes.state == CfdpState::BUSY_CLASS_2_ACKED) {
|
} else if (fsmRes.state == CfdpStates::BUSY_CLASS_2_ACKED) {
|
||||||
fsmRes.step = TransactionStep::SENDING_ACK_PDU;
|
fsmRes.step = TransactionStep::SENDING_ACK_PDU;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,7 +260,7 @@ ReturnValue_t cfdp::DestHandler::handleMetadataParseError(ReturnValue_t result,
|
||||||
cfdp::EntityId destId;
|
cfdp::EntityId destId;
|
||||||
headerReader.getDestId(destId);
|
headerReader.getDestId(destId);
|
||||||
RemoteEntityCfg* remoteCfg;
|
RemoteEntityCfg* remoteCfg;
|
||||||
if (not destParams.remoteCfgTable.getRemoteCfg(destId, &remoteCfg)) {
|
if (not dp.remoteCfgTable.getRemoteCfg(destId, &remoteCfg)) {
|
||||||
// TODO: No remote config for dest ID. I consider this a configuration error, which is not
|
// TODO: No remote config for dest ID. I consider this a configuration error, which is not
|
||||||
// covered by the standard.
|
// covered by the standard.
|
||||||
// Warning or error, yield or cache appropriate returnvalue
|
// Warning or error, yield or cache appropriate returnvalue
|
||||||
|
@ -274,57 +274,51 @@ ReturnValue_t cfdp::DestHandler::handleMetadataParseError(ReturnValue_t result,
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t cfdp::DestHandler::startTransaction(const MetadataPduReader& reader) {
|
ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, MetadataInfo& info) {
|
||||||
if (fsmRes.state != CfdpState::IDLE) {
|
if (fsmRes.state != CfdpStates::IDLE) {
|
||||||
// According to standard, discard metadata PDU if we are busy
|
// According to standard, discard metadata PDU if we are busy
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
ReturnValue_t result = OK;
|
ReturnValue_t result = OK;
|
||||||
size_t sourceNameSize = 0;
|
size_t sourceNameSize = 0;
|
||||||
|
|
||||||
if (not reader.getSourceFileName().isEmpty()) {
|
const uint8_t* sourceNamePtr = info.getSourceFileName().getValue(&sourceNameSize);
|
||||||
const uint8_t* sourceNamePtr = reader.getSourceFileName().getValue(&sourceNameSize);
|
if (sourceNameSize + 1 > tp.sourceName.size()) {
|
||||||
if (sourceNameSize + 1 > transactionParams.sourceName.size()) {
|
fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "source filename too large");
|
||||||
fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "source filename too large");
|
return FAILED;
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
std::memcpy(transactionParams.sourceName.data(), sourceNamePtr, sourceNameSize);
|
|
||||||
transactionParams.sourceName[sourceNameSize] = '\0';
|
|
||||||
}
|
}
|
||||||
|
std::memcpy(tp.sourceName.data(), sourceNamePtr, sourceNameSize);
|
||||||
|
tp.sourceName[sourceNameSize] = '\0';
|
||||||
size_t destNameSize = 0;
|
size_t destNameSize = 0;
|
||||||
if (not reader.getDestFileName().isEmpty()) {
|
const uint8_t* destNamePtr = info.getDestFileName().getValue(&destNameSize);
|
||||||
const uint8_t* destNamePtr = reader.getDestFileName().getValue(&destNameSize);
|
if (destNameSize + 1 > tp.destName.size()) {
|
||||||
if (destNameSize + 1 > transactionParams.destName.size()) {
|
fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "dest filename too large");
|
||||||
fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "dest filename too large");
|
return FAILED;
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
std::memcpy(transactionParams.destName.data(), destNamePtr, destNameSize);
|
|
||||||
transactionParams.destName[destNameSize] = '\0';
|
|
||||||
}
|
}
|
||||||
|
std::memcpy(tp.destName.data(), destNamePtr, destNameSize);
|
||||||
|
tp.destName[destNameSize] = '\0';
|
||||||
|
|
||||||
transactionParams.metadataOnly = true;
|
|
||||||
// If both dest name size and source name size are 0, we are dealing with a metadata only PDU,
|
// If both dest name size and source name size are 0, we are dealing with a metadata only PDU,
|
||||||
// so there is no need to create a file or truncate an existing file
|
// so there is no need to create a file or truncate an existing file
|
||||||
if (destNameSize > 0 and sourceNameSize > 0) {
|
if (destNameSize > 0 and sourceNameSize > 0) {
|
||||||
transactionParams.metadataOnly = false;
|
FilesystemParams fparams(tp.destName.data());
|
||||||
FilesystemParams fparams(transactionParams.destName.data());
|
|
||||||
// handling to allow only specifying target directory. Example:
|
// handling to allow only specifying target directory. Example:
|
||||||
// Source path /test/hello.txt, dest path /tmp -> dest path /tmp/hello.txt
|
// Source path /test/hello.txt, dest path /tmp -> dest path /tmp/hello.txt
|
||||||
if (destParams.user.vfs.isDirectory(transactionParams.destName.data())) {
|
if (dp.user.vfs.isDirectory(tp.destName.data())) {
|
||||||
result = tryBuildingAbsoluteDestName(destNameSize);
|
result = tryBuildingAbsoluteDestName(destNameSize);
|
||||||
if (result != OK) {
|
if (result != OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (destParams.user.vfs.fileExists(fparams)) {
|
if (dp.user.vfs.fileExists(fparams)) {
|
||||||
result = destParams.user.vfs.truncateFile(fparams);
|
result = dp.user.vfs.truncateFile(fparams);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
fileErrorHandler(events::FILESTORE_ERROR, result, "file truncation error");
|
fileErrorHandler(events::FILESTORE_ERROR, result, "file truncation error");
|
||||||
return FAILED;
|
return FAILED;
|
||||||
// TODO: Relevant for filestore rejection error?
|
// TODO: Relevant for filestore rejection error?
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result = destParams.user.vfs.createFile(fparams);
|
result = dp.user.vfs.createFile(fparams);
|
||||||
if (result != OK) {
|
if (result != OK) {
|
||||||
fileErrorHandler(events::FILESTORE_ERROR, result, "file creation error");
|
fileErrorHandler(events::FILESTORE_ERROR, result, "file creation error");
|
||||||
return FAILED;
|
return FAILED;
|
||||||
|
@ -334,135 +328,122 @@ ReturnValue_t cfdp::DestHandler::startTransaction(const MetadataPduReader& reade
|
||||||
}
|
}
|
||||||
EntityId sourceId;
|
EntityId sourceId;
|
||||||
reader.getSourceId(sourceId);
|
reader.getSourceId(sourceId);
|
||||||
if (not destParams.remoteCfgTable.getRemoteCfg(sourceId, &transactionParams.remoteCfg)) {
|
if (not dp.remoteCfgTable.getRemoteCfg(sourceId, &tp.remoteCfg)) {
|
||||||
// TODO: Warning, event etc.
|
// TODO: Warning, event etc.
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "cfdp::DestHandler" << __func__
|
sif::warning << "cfdp::DestHandler" << __func__
|
||||||
<< ": No remote configuration found for destination ID "
|
<< ": No remote configuration found for destination ID "
|
||||||
<< transactionParams.pduConf.sourceId.getValue() << std::endl;
|
<< tp.pduConf.sourceId.getValue() << std::endl;
|
||||||
#endif
|
#endif
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
fsmRes.step = TransactionStep::TRANSACTION_START;
|
||||||
if (reader.getTransmissionMode() == TransmissionMode::UNACKNOWLEDGED) {
|
if (reader.getTransmissionMode() == TransmissionMode::UNACKNOWLEDGED) {
|
||||||
fsmRes.state = CfdpState::BUSY_CLASS_1_NACKED;
|
fsmRes.state = CfdpStates::BUSY_CLASS_1_NACKED;
|
||||||
} else if (reader.getTransmissionMode() == TransmissionMode::ACKNOWLEDGED) {
|
} else if (reader.getTransmissionMode() == TransmissionMode::ACKNOWLEDGED) {
|
||||||
fsmRes.state = CfdpState::BUSY_CLASS_2_ACKED;
|
fsmRes.state = CfdpStates::BUSY_CLASS_2_ACKED;
|
||||||
}
|
}
|
||||||
if (transactionParams.metadataOnly) {
|
tp.checksumType = info.getChecksumType();
|
||||||
fsmRes.step = TransactionStep::TRANSFER_COMPLETION;
|
tp.closureRequested = info.isClosureRequested();
|
||||||
} else {
|
reader.fillConfig(tp.pduConf);
|
||||||
// Kind of ugly, make FSM working on packet per packet basis..
|
tp.pduConf.direction = Direction::TOWARDS_SENDER;
|
||||||
fsmRes.step = TransactionStep::TRANSACTION_START;
|
tp.transactionId.entityId = tp.pduConf.sourceId;
|
||||||
fsmRes.step = TransactionStep::RECEIVING_FILE_DATA_PDUS;
|
tp.transactionId.seqNum = tp.pduConf.seqNum;
|
||||||
}
|
fsmRes.step = TransactionStep::RECEIVING_FILE_DATA_PDUS;
|
||||||
auto& info = reader.getGenericInfo();
|
MetadataRecvdParams params(tp.transactionId, tp.pduConf.sourceId);
|
||||||
transactionParams.checksumType = info.getChecksumType();
|
params.fileSize = tp.fileSize.getSize();
|
||||||
transactionParams.closureRequested = info.isClosureRequested();
|
params.destFileName = tp.destName.data();
|
||||||
reader.fillConfig(transactionParams.pduConf);
|
params.sourceFileName = tp.sourceName.data();
|
||||||
transactionParams.pduConf.direction = Direction::TOWARDS_SENDER;
|
params.msgsToUserArray = dynamic_cast<MessageToUserTlv*>(userTlvVec.data());
|
||||||
transactionParams.transactionId.entityId = transactionParams.pduConf.sourceId;
|
params.msgsToUserLen = info.getOptionsLen();
|
||||||
transactionParams.transactionId.seqNum = transactionParams.pduConf.seqNum;
|
dp.user.metadataRecvdIndication(params);
|
||||||
transactionParams.fileSize = info.getFileSize();
|
|
||||||
MetadataRecvdParams params(transactionParams.transactionId, transactionParams.pduConf.sourceId,
|
|
||||||
transactionParams.fileSize);
|
|
||||||
params.destFileName = transactionParams.destName.data();
|
|
||||||
params.sourceFileName = transactionParams.sourceName.data();
|
|
||||||
params.numberOfMsgsToUser = 0;
|
|
||||||
for (const auto& opt : tlvVec) {
|
|
||||||
if (opt.getType() == TlvType::MSG_TO_USER) {
|
|
||||||
msgToUserVec[params.numberOfMsgsToUser] =
|
|
||||||
MessageToUserTlv(opt.getValue(), opt.getLengthField());
|
|
||||||
params.numberOfMsgsToUser++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
params.msgsToUserArray = msgToUserVec.data();
|
|
||||||
destParams.user.metadataRecvdIndication(params);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
cfdp::CfdpState cfdp::DestHandler::getCfdpState() const { return fsmRes.state; }
|
cfdp::CfdpStates cfdp::DestHandler::getCfdpState() const { return fsmRes.state; }
|
||||||
|
|
||||||
ReturnValue_t cfdp::DestHandler::handleTransferCompletion() {
|
ReturnValue_t cfdp::DestHandler::handleTransferCompletion() {
|
||||||
ReturnValue_t result;
|
ReturnValue_t result;
|
||||||
if (transactionParams.checksumType != ChecksumType::NULL_CHECKSUM) {
|
if (tp.checksumType != ChecksumType::NULL_CHECKSUM) {
|
||||||
result = checksumVerification();
|
result = checksumVerification();
|
||||||
if (result != OK) {
|
if (result != OK) {
|
||||||
// TODO: Warning / error handling?
|
// TODO: Warning / error handling?
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
transactionParams.conditionCode = ConditionCode::NO_ERROR;
|
tp.conditionCode = ConditionCode::NO_ERROR;
|
||||||
}
|
}
|
||||||
result = noticeOfCompletion();
|
result = noticeOfCompletion();
|
||||||
if (result != OK) {
|
if (result != OK) {
|
||||||
}
|
}
|
||||||
if (fsmRes.state == CfdpState::BUSY_CLASS_1_NACKED) {
|
if (fsmRes.state == CfdpStates::BUSY_CLASS_1_NACKED) {
|
||||||
if (transactionParams.closureRequested) {
|
if (tp.closureRequested) {
|
||||||
fsmRes.step = TransactionStep::SENDING_FINISHED_PDU;
|
fsmRes.step = TransactionStep::SENDING_FINISHED_PDU;
|
||||||
} else {
|
} else {
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
} else if (fsmRes.state == CfdpState::BUSY_CLASS_2_ACKED) {
|
} else if (fsmRes.state == CfdpStates::BUSY_CLASS_2_ACKED) {
|
||||||
fsmRes.step = TransactionStep::SENDING_FINISHED_PDU;
|
fsmRes.step = TransactionStep::SENDING_FINISHED_PDU;
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t cfdp::DestHandler::tryBuildingAbsoluteDestName(size_t destNameSize) {
|
ReturnValue_t cfdp::DestHandler::tryBuildingAbsoluteDestName(size_t destNameSize) {
|
||||||
// A path may only have a maximum of 256 characters in CFDP, so this buffer should be sufficient
|
// Maximum allowed path size is 255 characters, so this should be enough to hold the full
|
||||||
// for all use-cases.
|
// base name in any case.
|
||||||
char baseNameBuf[512]{};
|
char baseNameBuf[524]{};
|
||||||
FilesystemParams fparamsSrc(transactionParams.sourceName.data());
|
FilesystemParams fparamsSrc(tp.sourceName.data());
|
||||||
size_t baseNameLen = 0;
|
size_t baseNameLen = 0;
|
||||||
ReturnValue_t result = destParams.user.vfs.getBaseFilename(fparamsSrc, baseNameBuf,
|
ReturnValue_t result =
|
||||||
sizeof(baseNameBuf), baseNameLen);
|
dp.user.vfs.getBaseFilename(fparamsSrc, baseNameBuf, sizeof(baseNameBuf), baseNameLen);
|
||||||
if (result != returnvalue::OK or baseNameLen == 0) {
|
if (result != returnvalue::OK or baseNameLen == 0) {
|
||||||
fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "error retrieving source base name");
|
fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "error retrieving source base name");
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
// Destination name + slash + base name + null termination
|
// Destination name + slash + base name + null termination
|
||||||
if (destNameSize + 1 + baseNameLen + 1 > transactionParams.destName.size()) {
|
if (destNameSize + 1 + baseNameLen + 1 > tp.destName.size()) {
|
||||||
fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0,
|
fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0,
|
||||||
"dest filename too large after adding source base name");
|
"dest filename too large after adding source base name");
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
transactionParams.destName[destNameSize++] = '/';
|
tp.destName[destNameSize++] = '/';
|
||||||
std::memcpy(transactionParams.destName.data() + destNameSize, baseNameBuf, baseNameLen);
|
std::memcpy(tp.destName.data() + destNameSize, baseNameBuf, baseNameLen);
|
||||||
destNameSize += baseNameLen;
|
destNameSize += baseNameLen;
|
||||||
transactionParams.destName[destNameSize++] = '\0';
|
tp.destName[destNameSize++] = '\0';
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cfdp::DestHandler::fileErrorHandler(Event event, ReturnValue_t result,
|
void cfdp::DestHandler::fileErrorHandler(Event event, ReturnValue_t result, const char* info) {
|
||||||
const char* info) const {
|
fp.eventReporter->forwardEvent(events::FILENAME_TOO_LARGE_ERROR,
|
||||||
fsfwParams.eventReporter->forwardEvent(event, static_cast<uint8_t>(fsmRes.step), result);
|
static_cast<uint8_t>(fsmRes.step), result);
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "cfdp::DestHandler: " << info << std::endl;
|
sif::warning << "cfdp::DestHandler: " << info << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void cfdp::DestHandler::finish() {
|
void cfdp::DestHandler::finish() {
|
||||||
transactionParams.reset();
|
tp.reset();
|
||||||
destParams.packetListRef.clear();
|
dp.packetListRef.clear();
|
||||||
fsmRes.state = CfdpState::IDLE;
|
fsmRes.state = CfdpStates::IDLE;
|
||||||
fsmRes.step = TransactionStep::IDLE;
|
fsmRes.step = TransactionStep::IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t cfdp::DestHandler::checksumVerification() {
|
ReturnValue_t cfdp::DestHandler::checksumVerification() {
|
||||||
std::array<uint8_t, 1024> buf{};
|
std::array<uint8_t, 1024> buf{};
|
||||||
|
// TODO: Checksum verification and notice of completion
|
||||||
etl::crc32 crcCalc;
|
etl::crc32 crcCalc;
|
||||||
uint64_t currentOffset = 0;
|
uint64_t currentOffset = 0;
|
||||||
FileOpParams params(transactionParams.destName.data(), transactionParams.fileSize.value());
|
FileOpParams params(tp.destName.data(), tp.fileSize.value());
|
||||||
while (currentOffset < transactionParams.fileSize.value()) {
|
while (currentOffset < tp.fileSize.value()) {
|
||||||
uint64_t readLen;
|
uint64_t readLen;
|
||||||
if (currentOffset + buf.size() > transactionParams.fileSize.value()) {
|
if (currentOffset + buf.size() > tp.fileSize.value()) {
|
||||||
readLen = transactionParams.fileSize.value() - currentOffset;
|
readLen = tp.fileSize.value() - currentOffset;
|
||||||
} else {
|
} else {
|
||||||
readLen = buf.size();
|
readLen = buf.size();
|
||||||
}
|
}
|
||||||
if (readLen > 0) {
|
if (readLen > 0) {
|
||||||
params.offset = currentOffset;
|
params.offset = currentOffset;
|
||||||
params.size = readLen;
|
params.size = readLen;
|
||||||
auto result = destParams.user.vfs.readFromFile(params, buf.data(), buf.size());
|
auto result = dp.user.vfs.readFromFile(params, buf.data(), buf.size());
|
||||||
if (result != OK) {
|
if (result != OK) {
|
||||||
// TODO: I think this is a case for a filestore rejection, but it might sense to print
|
// TODO: I think this is a case for a filestore rejection, but it might sense to print
|
||||||
// a warning or trigger an event because this should generally not happen
|
// a warning or trigger an event because this should generally not happen
|
||||||
|
@ -474,43 +455,40 @@ ReturnValue_t cfdp::DestHandler::checksumVerification() {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t value = crcCalc.value();
|
uint32_t value = crcCalc.value();
|
||||||
if (value == transactionParams.crc) {
|
if (value == tp.crc) {
|
||||||
transactionParams.conditionCode = ConditionCode::NO_ERROR;
|
tp.conditionCode = ConditionCode::NO_ERROR;
|
||||||
transactionParams.deliveryCode = FileDeliveryCode::DATA_COMPLETE;
|
tp.deliveryCode = FileDeliveryCode::DATA_COMPLETE;
|
||||||
} else {
|
} else {
|
||||||
// TODO: Proper error handling
|
// TODO: Proper error handling
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "CRC check for file " << transactionParams.destName.data() << " failed"
|
sif::warning << "CRC check for file " << tp.destName.data() << " failed" << std::endl;
|
||||||
<< std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
transactionParams.conditionCode = ConditionCode::FILE_CHECKSUM_FAILURE;
|
tp.conditionCode = ConditionCode::FILE_CHECKSUM_FAILURE;
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t cfdp::DestHandler::noticeOfCompletion() {
|
ReturnValue_t cfdp::DestHandler::noticeOfCompletion() {
|
||||||
if (destParams.cfg.indicCfg.transactionFinishedIndicRequired) {
|
if (dp.cfg.indicCfg.transactionFinishedIndicRequired) {
|
||||||
TransactionFinishedParams params(
|
TransactionFinishedParams params(tp.transactionId, tp.conditionCode, tp.deliveryCode,
|
||||||
transactionParams.transactionId, transactionParams.conditionCode,
|
tp.deliveryStatus);
|
||||||
transactionParams.deliveryCode, transactionParams.deliveryStatus);
|
dp.user.transactionFinishedIndication(params);
|
||||||
destParams.user.transactionFinishedIndication(params);
|
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t cfdp::DestHandler::sendFinishedPdu() {
|
ReturnValue_t cfdp::DestHandler::sendFinishedPdu() {
|
||||||
FinishedInfo info(transactionParams.conditionCode, transactionParams.deliveryCode,
|
FinishedInfo info(tp.conditionCode, tp.deliveryCode, tp.deliveryStatus);
|
||||||
transactionParams.deliveryStatus);
|
FinishPduCreator finishedPdu(tp.pduConf, info);
|
||||||
FinishPduCreator finishedPdu(transactionParams.pduConf, info);
|
|
||||||
store_address_t storeId;
|
store_address_t storeId;
|
||||||
uint8_t* dataPtr = nullptr;
|
uint8_t* dataPtr = nullptr;
|
||||||
ReturnValue_t result =
|
ReturnValue_t result =
|
||||||
fsfwParams.tmStore->getFreeElement(&storeId, finishedPdu.getSerializedSize(), &dataPtr);
|
fp.tmStore->getFreeElement(&storeId, finishedPdu.getSerializedSize(), &dataPtr);
|
||||||
if (result != OK) {
|
if (result != OK) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "cfdp::DestHandler:sendFinishedPdu: Getting store slot failed" << std::endl;
|
sif::warning << "cfdp::DestHandler:sendFinishedPdu: Getting store slot failed" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
fsfwParams.eventReporter->forwardEvent(events::STORE_ERROR, result, 0);
|
fp.eventReporter->forwardEvent(events::STORE_ERROR, result, 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
size_t serLen = 0;
|
size_t serLen = 0;
|
||||||
|
@ -520,16 +498,16 @@ ReturnValue_t cfdp::DestHandler::sendFinishedPdu() {
|
||||||
sif::warning << "cfdp::DestHandler::sendFinishedPdu: Serializing Finished PDU failed"
|
sif::warning << "cfdp::DestHandler::sendFinishedPdu: Serializing Finished PDU failed"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
#endif
|
#endif
|
||||||
fsfwParams.eventReporter->forwardEvent(events::SERIALIZATION_ERROR, result, 0);
|
fp.eventReporter->forwardEvent(events::SERIALIZATION_ERROR, result, 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
TmTcMessage msg(storeId);
|
TmTcMessage msg(storeId);
|
||||||
result = fsfwParams.msgQueue->sendMessage(fsfwParams.packetDest.getReportReceptionQueue(), &msg);
|
result = fp.msgQueue->sendMessage(fp.packetDest.getReportReceptionQueue(), &msg);
|
||||||
if (result != OK) {
|
if (result != OK) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "cfdp::DestHandler::sendFinishedPdu: Sending PDU failed" << std::endl;
|
sif::warning << "cfdp::DestHandler::sendFinishedPdu: Sending PDU failed" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
fsfwParams.eventReporter->forwardEvent(events::MSG_QUEUE_ERROR, result, 0);
|
fp.eventReporter->forwardEvent(events::MSG_QUEUE_ERROR, result, 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
fsmRes.packetsSent++;
|
fsmRes.packetsSent++;
|
||||||
|
@ -549,9 +527,7 @@ const cfdp::DestHandler::FsmResult& cfdp::DestHandler::updateFsmRes(uint8_t erro
|
||||||
return fsmRes;
|
return fsmRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cfdp::TransactionId& cfdp::DestHandler::getTransactionId() const {
|
const cfdp::TransactionId& cfdp::DestHandler::getTransactionId() const { return tp.transactionId; }
|
||||||
return transactionParams.transactionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cfdp::DestHandler::checkAndHandleError(ReturnValue_t result, uint8_t& errorIdx) {
|
void cfdp::DestHandler::checkAndHandleError(ReturnValue_t result, uint8_t& errorIdx) {
|
||||||
if (result != OK and errorIdx < 3) {
|
if (result != OK and errorIdx < 3) {
|
||||||
|
@ -560,15 +536,13 @@ void cfdp::DestHandler::checkAndHandleError(ReturnValue_t result, uint8_t& error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cfdp::DestHandler::setMsgQueue(MessageQueueIF& queue) { fsfwParams.msgQueue = &queue; }
|
void cfdp::DestHandler::setMsgQueue(MessageQueueIF& queue) { fp.msgQueue = &queue; }
|
||||||
|
|
||||||
void cfdp::DestHandler::setEventReporter(EventReportingProxyIF& reporter) {
|
void cfdp::DestHandler::setEventReporter(EventReportingProxyIF& reporter) {
|
||||||
fsfwParams.eventReporter = &reporter;
|
fp.eventReporter = &reporter;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cfdp::DestHandlerParams& cfdp::DestHandler::getDestHandlerParams() const {
|
const cfdp::DestHandlerParams& cfdp::DestHandler::getDestHandlerParams() const { return dp; }
|
||||||
return destParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
StorageManagerIF* cfdp::DestHandler::getTmStore() const { return fsfwParams.tmStore; }
|
StorageManagerIF* cfdp::DestHandler::getTmStore() const { return fp.tmStore; }
|
||||||
StorageManagerIF* cfdp::DestHandler::getTcStore() const { return fsfwParams.tcStore; }
|
StorageManagerIF* cfdp::DestHandler::getTcStore() const { return fp.tcStore; }
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
#include <etl/list.h>
|
#include <etl/list.h>
|
||||||
#include <etl/set.h>
|
#include <etl/set.h>
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
#include "RemoteConfigTableIF.h"
|
#include "RemoteConfigTableIF.h"
|
||||||
#include "UserBase.h"
|
#include "UserBase.h"
|
||||||
|
@ -14,7 +14,6 @@
|
||||||
#include "fsfw/cfdp/handler/mib.h"
|
#include "fsfw/cfdp/handler/mib.h"
|
||||||
#include "fsfw/cfdp/pdu/MetadataPduReader.h"
|
#include "fsfw/cfdp/pdu/MetadataPduReader.h"
|
||||||
#include "fsfw/cfdp/pdu/PduConfig.h"
|
#include "fsfw/cfdp/pdu/PduConfig.h"
|
||||||
#include "fsfw/cfdp/tlv/MessageToUserTlv.h"
|
|
||||||
#include "fsfw/container/DynamicFIFO.h"
|
#include "fsfw/container/DynamicFIFO.h"
|
||||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||||
#include "fsfw/storagemanager/storeAddress.h"
|
#include "fsfw/storagemanager/storeAddress.h"
|
||||||
|
@ -22,9 +21,23 @@
|
||||||
|
|
||||||
namespace cfdp {
|
namespace cfdp {
|
||||||
|
|
||||||
|
struct PacketInfo {
|
||||||
|
PacketInfo(PduType type, store_address_t storeId,
|
||||||
|
std::optional<FileDirective> directive = std::nullopt)
|
||||||
|
: pduType(type), directiveType(directive), storeId(storeId) {}
|
||||||
|
|
||||||
|
PduType pduType = PduType::FILE_DATA;
|
||||||
|
std::optional<FileDirective> directiveType = FileDirective::INVALID_DIRECTIVE;
|
||||||
|
store_address_t storeId = store_address_t::invalid();
|
||||||
|
PacketInfo() = default;
|
||||||
|
};
|
||||||
|
|
||||||
template <size_t SIZE>
|
template <size_t SIZE>
|
||||||
using LostSegmentsList = etl::set<etl::pair<uint64_t, uint64_t>, SIZE>;
|
using LostSegmentsList = etl::set<etl::pair<uint64_t, uint64_t>, SIZE>;
|
||||||
|
template <size_t SIZE>
|
||||||
|
using PacketInfoList = etl::list<PacketInfo, SIZE>;
|
||||||
using LostSegmentsListBase = etl::iset<etl::pair<uint64_t, uint64_t>>;
|
using LostSegmentsListBase = etl::iset<etl::pair<uint64_t, uint64_t>>;
|
||||||
|
using PacketInfoListBase = etl::ilist<PacketInfo>;
|
||||||
|
|
||||||
struct DestHandlerParams {
|
struct DestHandlerParams {
|
||||||
DestHandlerParams(LocalEntityCfg cfg, UserBase& user, RemoteConfigTableIF& remoteCfgTable,
|
DestHandlerParams(LocalEntityCfg cfg, UserBase& user, RemoteConfigTableIF& remoteCfgTable,
|
||||||
|
@ -32,9 +45,6 @@ struct DestHandlerParams {
|
||||||
// TODO: This container can potentially take tons of space. For a better
|
// TODO: This container can potentially take tons of space. For a better
|
||||||
// memory efficient implementation, an additional abstraction could be
|
// memory efficient implementation, an additional abstraction could be
|
||||||
// be used so users can use uint32_t as the pair type
|
// be used so users can use uint32_t as the pair type
|
||||||
// TODO: Actually, we can provide a better abstraction via interface, which
|
|
||||||
// allows using something like a bounded map. This simplifies
|
|
||||||
// the implementation significantly.
|
|
||||||
LostSegmentsListBase& lostSegmentsContainer)
|
LostSegmentsListBase& lostSegmentsContainer)
|
||||||
: cfg(std::move(cfg)),
|
: cfg(std::move(cfg)),
|
||||||
user(user),
|
user(user),
|
||||||
|
@ -48,10 +58,31 @@ struct DestHandlerParams {
|
||||||
|
|
||||||
PacketInfoListBase& packetListRef;
|
PacketInfoListBase& packetListRef;
|
||||||
LostSegmentsListBase& lostSegmentsContainer;
|
LostSegmentsListBase& lostSegmentsContainer;
|
||||||
uint8_t maxTlvsInOnePdu = 20;
|
uint8_t maxTlvsInOnePdu = 10;
|
||||||
size_t maxFilenameLen = 255;
|
size_t maxFilenameLen = 255;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FsfwParams {
|
||||||
|
FsfwParams(AcceptsTelemetryIF& packetDest, MessageQueueIF* msgQueue,
|
||||||
|
EventReportingProxyIF* eventReporter, StorageManagerIF& tcStore,
|
||||||
|
StorageManagerIF& tmStore)
|
||||||
|
: FsfwParams(packetDest, msgQueue, eventReporter) {
|
||||||
|
this->tcStore = &tcStore;
|
||||||
|
this->tmStore = &tmStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
FsfwParams(AcceptsTelemetryIF& packetDest, MessageQueueIF* msgQueue,
|
||||||
|
EventReportingProxyIF* eventReporter)
|
||||||
|
: packetDest(packetDest), msgQueue(msgQueue), eventReporter(eventReporter) {}
|
||||||
|
AcceptsTelemetryIF& packetDest;
|
||||||
|
MessageQueueIF* msgQueue;
|
||||||
|
EventReportingProxyIF* eventReporter = nullptr;
|
||||||
|
StorageManagerIF* tcStore = nullptr;
|
||||||
|
StorageManagerIF* tmStore = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class CallStatus { DONE, CALL_AFTER_DELAY, CALL_AGAIN };
|
||||||
|
|
||||||
class DestHandler {
|
class DestHandler {
|
||||||
public:
|
public:
|
||||||
enum class TransactionStep : uint8_t {
|
enum class TransactionStep : uint8_t {
|
||||||
|
@ -68,7 +99,7 @@ class DestHandler {
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
CallStatus callStatus = CallStatus::CALL_AFTER_DELAY;
|
CallStatus callStatus = CallStatus::CALL_AFTER_DELAY;
|
||||||
TransactionStep step = TransactionStep::IDLE;
|
TransactionStep step = TransactionStep::IDLE;
|
||||||
CfdpState state = CfdpState::IDLE;
|
CfdpStates state = CfdpStates::IDLE;
|
||||||
uint32_t packetsSent = 0;
|
uint32_t packetsSent = 0;
|
||||||
uint8_t errors = 0;
|
uint8_t errors = 0;
|
||||||
std::array<ReturnValue_t, 3> errorCodes = {};
|
std::array<ReturnValue_t, 3> errorCodes = {};
|
||||||
|
@ -93,7 +124,7 @@ class DestHandler {
|
||||||
* - @c returnvalue::OK State machine OK for this execution cycle
|
* - @c returnvalue::OK State machine OK for this execution cycle
|
||||||
* - @c CALL_FSM_AGAIN State machine should be called again.
|
* - @c CALL_FSM_AGAIN State machine should be called again.
|
||||||
*/
|
*/
|
||||||
const FsmResult& stateMachine();
|
const FsmResult& performStateMachine();
|
||||||
void setMsgQueue(MessageQueueIF& queue);
|
void setMsgQueue(MessageQueueIF& queue);
|
||||||
void setEventReporter(EventReportingProxyIF& reporter);
|
void setEventReporter(EventReportingProxyIF& reporter);
|
||||||
|
|
||||||
|
@ -101,7 +132,7 @@ class DestHandler {
|
||||||
|
|
||||||
ReturnValue_t initialize();
|
ReturnValue_t initialize();
|
||||||
|
|
||||||
[[nodiscard]] CfdpState getCfdpState() const;
|
[[nodiscard]] CfdpStates getCfdpState() const;
|
||||||
[[nodiscard]] TransactionStep getTransactionStep() const;
|
[[nodiscard]] TransactionStep getTransactionStep() const;
|
||||||
[[nodiscard]] const TransactionId& getTransactionId() const;
|
[[nodiscard]] const TransactionId& getTransactionId() const;
|
||||||
[[nodiscard]] const DestHandlerParams& getDestHandlerParams() const;
|
[[nodiscard]] const DestHandlerParams& getDestHandlerParams() const;
|
||||||
|
@ -126,19 +157,17 @@ class DestHandler {
|
||||||
crc = 0;
|
crc = 0;
|
||||||
progress = 0;
|
progress = 0;
|
||||||
remoteCfg = nullptr;
|
remoteCfg = nullptr;
|
||||||
metadataOnly = false;
|
|
||||||
closureRequested = false;
|
closureRequested = false;
|
||||||
vfsErrorCount = 0;
|
vfsErrorCount = 0;
|
||||||
checksumType = ChecksumType::NULL_CHECKSUM;
|
checksumType = ChecksumType::NULL_CHECKSUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool metadataOnly = false;
|
|
||||||
ChecksumType checksumType = ChecksumType::NULL_CHECKSUM;
|
ChecksumType checksumType = ChecksumType::NULL_CHECKSUM;
|
||||||
bool closureRequested = false;
|
bool closureRequested = false;
|
||||||
uint16_t vfsErrorCount = 0;
|
uint16_t vfsErrorCount = 0;
|
||||||
std::vector<char> sourceName;
|
std::vector<char> sourceName;
|
||||||
std::vector<char> destName;
|
std::vector<char> destName;
|
||||||
cfdp::Fss fileSize;
|
cfdp::FileSize fileSize;
|
||||||
TransactionId transactionId;
|
TransactionId transactionId;
|
||||||
PduConfig pduConf;
|
PduConfig pduConf;
|
||||||
ConditionCode conditionCode = ConditionCode::NO_ERROR;
|
ConditionCode conditionCode = ConditionCode::NO_ERROR;
|
||||||
|
@ -150,13 +179,13 @@ class DestHandler {
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<cfdp::Tlv> tlvVec;
|
std::vector<cfdp::Tlv> tlvVec;
|
||||||
std::vector<MessageToUserTlv> msgToUserVec;
|
std::vector<cfdp::Tlv> userTlvVec;
|
||||||
TransactionParams transactionParams;
|
DestHandlerParams dp;
|
||||||
DestHandlerParams destParams;
|
FsfwParams fp;
|
||||||
cfdp::FsfwParams fsfwParams;
|
TransactionParams tp;
|
||||||
FsmResult fsmRes;
|
FsmResult fsmRes;
|
||||||
|
|
||||||
ReturnValue_t startTransaction(const MetadataPduReader& reader);
|
ReturnValue_t startTransaction(MetadataPduReader& reader, MetadataInfo& info);
|
||||||
ReturnValue_t handleMetadataPdu(const PacketInfo& info);
|
ReturnValue_t handleMetadataPdu(const PacketInfo& info);
|
||||||
ReturnValue_t handleFileDataPdu(const PacketInfo& info);
|
ReturnValue_t handleFileDataPdu(const PacketInfo& info);
|
||||||
ReturnValue_t handleEofPdu(const PacketInfo& info);
|
ReturnValue_t handleEofPdu(const PacketInfo& info);
|
||||||
|
@ -167,7 +196,7 @@ class DestHandler {
|
||||||
ReturnValue_t sendFinishedPdu();
|
ReturnValue_t sendFinishedPdu();
|
||||||
ReturnValue_t noticeOfCompletion();
|
ReturnValue_t noticeOfCompletion();
|
||||||
ReturnValue_t checksumVerification();
|
ReturnValue_t checksumVerification();
|
||||||
void fileErrorHandler(Event event, ReturnValue_t result, const char* info) const;
|
void fileErrorHandler(Event event, ReturnValue_t result, const char* info);
|
||||||
const FsmResult& updateFsmRes(uint8_t errors);
|
const FsmResult& updateFsmRes(uint8_t errors);
|
||||||
void checkAndHandleError(ReturnValue_t result, uint8_t& errorIdx);
|
void checkAndHandleError(ReturnValue_t result, uint8_t& errorIdx);
|
||||||
void finish();
|
void finish();
|
||||||
|
|
|
@ -1,201 +0,0 @@
|
||||||
#include "PutRequest.h"
|
|
||||||
|
|
||||||
using namespace returnvalue;
|
|
||||||
|
|
||||||
cfdp::PutRequest::PutRequest(cfdp::EntityId destId, const uint8_t *msgsToUser,
|
|
||||||
size_t msgsToUserTotalSize, const uint8_t *fsRequests,
|
|
||||||
size_t fsRequestsSize)
|
|
||||||
: destId(std::move(destId)),
|
|
||||||
metadataOnly(true),
|
|
||||||
msgsToUsersTotalSize(msgsToUserTotalSize),
|
|
||||||
msgsToUserStartPtr(msgsToUser),
|
|
||||||
fsRequestsTotalSize(fsRequestsSize),
|
|
||||||
fsRequestStartPtr(fsRequests) {}
|
|
||||||
|
|
||||||
cfdp::PutRequest::PutRequest(cfdp::EntityId destId, cfdp::StringLv &sourceName,
|
|
||||||
cfdp::StringLv &destName)
|
|
||||||
: destId(std::move(destId)), sourceName(std::move(sourceName)), destName(std::move(destName)) {}
|
|
||||||
|
|
||||||
[[nodiscard]] bool cfdp::PutRequest::isMetadataOnly() const { return metadataOnly; }
|
|
||||||
|
|
||||||
ReturnValue_t cfdp::PutRequest::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
|
||||||
SerializeIF::Endianness streamEndianness) const {
|
|
||||||
if (buffer == nullptr or size == nullptr) {
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
if (*size + getSerializedSize() > maxSize) {
|
|
||||||
return SerializeIF::BUFFER_TOO_SHORT;
|
|
||||||
}
|
|
||||||
ReturnValue_t result = destId.serializeAsLv(buffer, size, maxSize);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = SerializeAdapter::serialize(&metadataOnly, buffer, size, maxSize, streamEndianness);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
if (!metadataOnly) {
|
|
||||||
result = sourceName.serialize(buffer, size, maxSize, streamEndianness);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = destName.serialize(buffer, size, maxSize, streamEndianness);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result =
|
|
||||||
SerializeAdapter::serialize(&hasTransmissionMode, buffer, size, maxSize, streamEndianness);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result =
|
|
||||||
SerializeAdapter::serialize(&transmissionMode, buffer, size, maxSize, streamEndianness);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result =
|
|
||||||
SerializeAdapter::serialize(&hasClosureRequested, buffer, size, maxSize, streamEndianness);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result =
|
|
||||||
SerializeAdapter::serialize(&closureRequested, buffer, size, maxSize, streamEndianness);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result =
|
|
||||||
SerializeAdapter::serialize(&msgsToUsersTotalSize, buffer, size, maxSize, streamEndianness);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
std::memcpy(*buffer, msgsToUserStartPtr, msgsToUsersTotalSize);
|
|
||||||
*buffer += msgsToUsersTotalSize;
|
|
||||||
*size += msgsToUsersTotalSize;
|
|
||||||
|
|
||||||
result =
|
|
||||||
SerializeAdapter::serialize(&fsRequestsTotalSize, buffer, size, maxSize, streamEndianness);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
std::memcpy(*buffer, fsRequestStartPtr, fsRequestsTotalSize);
|
|
||||||
*buffer += fsRequestsTotalSize;
|
|
||||||
*size += fsRequestsTotalSize;
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t cfdp::PutRequest::deSerialize(const uint8_t **buffer, size_t *size,
|
|
||||||
SerializeIF::Endianness streamEndianness) {
|
|
||||||
if (buffer == nullptr or size == nullptr) {
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
ReturnValue_t result = destId.deSerializeFromLv(buffer, size);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = SerializeAdapter::deSerialize(&metadataOnly, buffer, size, streamEndianness);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
if (!metadataOnly) {
|
|
||||||
result = sourceName.deSerialize(buffer, size, streamEndianness);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = destName.deSerialize(buffer, size, streamEndianness);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = SerializeAdapter::deSerialize(&hasTransmissionMode, buffer, size, streamEndianness);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = SerializeAdapter::deSerialize(&transmissionMode, buffer, size, streamEndianness);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = SerializeAdapter::deSerialize(&hasClosureRequested, buffer, size, streamEndianness);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = SerializeAdapter::deSerialize(&closureRequested, buffer, size, streamEndianness);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result = SerializeAdapter::deSerialize(&msgsToUsersTotalSize, buffer, size, streamEndianness);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
msgsToUserStartPtr = *buffer;
|
|
||||||
*buffer += msgsToUsersTotalSize;
|
|
||||||
*size += msgsToUsersTotalSize;
|
|
||||||
|
|
||||||
result = SerializeAdapter::deSerialize(&fsRequestsTotalSize, buffer, size, streamEndianness);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
fsRequestStartPtr = *buffer;
|
|
||||||
*buffer += fsRequestsTotalSize;
|
|
||||||
*size += fsRequestsTotalSize;
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t cfdp::PutRequest::getSerializedSize() const {
|
|
||||||
// Entity ID LV (1 leading size byte) and the metadata only flag.
|
|
||||||
size_t baseSize = 1 + destId.getSerializedSize() + 1;
|
|
||||||
if (!metadataOnly) {
|
|
||||||
baseSize += sourceName.getSerializedSize() + destName.getSerializedSize() + 4;
|
|
||||||
}
|
|
||||||
baseSize += sizeof(msgsToUsersTotalSize) + msgsToUsersTotalSize + sizeof(fsRequestsTotalSize) +
|
|
||||||
fsRequestsTotalSize;
|
|
||||||
return baseSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cfdp::PutRequest::setSourceAndDestName(cfdp::StringLv &sourceName_,
|
|
||||||
cfdp::StringLv &destName_) {
|
|
||||||
metadataOnly = false;
|
|
||||||
this->sourceName = std::move(sourceName_);
|
|
||||||
this->destName = std::move(destName_);
|
|
||||||
}
|
|
||||||
|
|
||||||
const cfdp::StringLv &cfdp::PutRequest::getSourceName() const { return sourceName; }
|
|
||||||
|
|
||||||
const cfdp::StringLv &cfdp::PutRequest::getDestName() const { return destName; }
|
|
||||||
|
|
||||||
const cfdp::EntityId &cfdp::PutRequest::getDestId() const { return destId; }
|
|
||||||
|
|
||||||
void cfdp::PutRequest::setDestId(cfdp::EntityId id) { destId = std::move(id); }
|
|
||||||
|
|
||||||
void cfdp::PutRequest::setTransmissionMode(cfdp::TransmissionMode transmissionMode_) {
|
|
||||||
this->transmissionMode = transmissionMode_;
|
|
||||||
hasTransmissionMode = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cfdp::PutRequest::clearTransmissionMode() { hasTransmissionMode = false; }
|
|
||||||
|
|
||||||
void cfdp::PutRequest::clearClosureRequest() { hasClosureRequested = false; }
|
|
||||||
|
|
||||||
void cfdp::PutRequest::setClosureRequest(bool closureRequested_) {
|
|
||||||
this->closureRequested = closureRequested_;
|
|
||||||
hasClosureRequested = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint8_t *cfdp::PutRequest::getMessagesToUser(size_t &totalSize) {
|
|
||||||
totalSize = this->msgsToUsersTotalSize;
|
|
||||||
return msgsToUserStartPtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cfdp::PutRequest::getClosureRequested(bool &closureRequested_) const {
|
|
||||||
if (hasClosureRequested) {
|
|
||||||
closureRequested_ = this->closureRequested;
|
|
||||||
}
|
|
||||||
return hasClosureRequested;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cfdp::PutRequest::getTransmissionMode(cfdp::TransmissionMode &mode) const {
|
|
||||||
if (hasTransmissionMode) {
|
|
||||||
mode = static_cast<cfdp::TransmissionMode>(this->transmissionMode);
|
|
||||||
}
|
|
||||||
return hasTransmissionMode;
|
|
||||||
}
|
|
|
@ -1,82 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <optional>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "fsfw/cfdp/VarLenFields.h"
|
|
||||||
#include "fsfw/cfdp/tlv/FilestoreRequestTlv.h"
|
|
||||||
#include "fsfw/cfdp/tlv/MessageToUserTlv.h"
|
|
||||||
|
|
||||||
namespace cfdp {
|
|
||||||
|
|
||||||
class PutRequest : public SerializeIF {
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Metadata only constructor.
|
|
||||||
* @param destId
|
|
||||||
* @param msgsToUser
|
|
||||||
* @param msgsToUserTotalSize
|
|
||||||
* @param fsRequests
|
|
||||||
* @param fsRequestsSize
|
|
||||||
*/
|
|
||||||
PutRequest(EntityId destId, const uint8_t* msgsToUser, size_t msgsToUserTotalSize,
|
|
||||||
const uint8_t* fsRequests, size_t fsRequestsSize);
|
|
||||||
/**
|
|
||||||
* Put request to initiate file transfers. By default, the transmission mode and closure requested
|
|
||||||
* parameter are not present, thereby being derived from the remote configuration for a
|
|
||||||
* particular destination ID.
|
|
||||||
* @param destId
|
|
||||||
* @param sourceName
|
|
||||||
* @param destName
|
|
||||||
*/
|
|
||||||
PutRequest(EntityId destId, cfdp::StringLv& sourceName, cfdp::StringLv& destName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor for deserialization.
|
|
||||||
*/
|
|
||||||
PutRequest() = default;
|
|
||||||
|
|
||||||
[[nodiscard]] ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
|
||||||
Endianness streamEndianness) const override;
|
|
||||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
|
||||||
Endianness streamEndianness) override;
|
|
||||||
[[nodiscard]] size_t getSerializedSize() const override;
|
|
||||||
void setSourceAndDestName(cfdp::StringLv& sourceName, cfdp::StringLv& destName);
|
|
||||||
|
|
||||||
[[nodiscard]] const cfdp::StringLv& getSourceName() const;
|
|
||||||
[[nodiscard]] const cfdp::StringLv& getDestName() const;
|
|
||||||
|
|
||||||
void setTransmissionMode(cfdp::TransmissionMode transmissionMode);
|
|
||||||
void clearTransmissionMode();
|
|
||||||
void setClosureRequest(bool closureRequested);
|
|
||||||
void clearClosureRequest();
|
|
||||||
|
|
||||||
const uint8_t* getMessagesToUser(size_t& msgSize);
|
|
||||||
|
|
||||||
[[nodiscard]] bool isMetadataOnly() const;
|
|
||||||
|
|
||||||
bool getTransmissionMode(TransmissionMode& mode) const;
|
|
||||||
bool getClosureRequested(bool& closureRequested) const;
|
|
||||||
|
|
||||||
[[nodiscard]] const EntityId& getDestId() const;
|
|
||||||
void setDestId(EntityId id);
|
|
||||||
|
|
||||||
private:
|
|
||||||
EntityId destId;
|
|
||||||
uint8_t metadataOnly = true;
|
|
||||||
// Transaction parameters. Omitted if the put request is metadata only.
|
|
||||||
cfdp::StringLv sourceName;
|
|
||||||
|
|
||||||
cfdp::StringLv destName;
|
|
||||||
bool hasTransmissionMode = false;
|
|
||||||
uint8_t transmissionMode = TransmissionMode::UNACKNOWLEDGED;
|
|
||||||
bool hasClosureRequested = false;
|
|
||||||
uint8_t closureRequested = false;
|
|
||||||
// Metadata
|
|
||||||
size_t msgsToUsersTotalSize = 0;
|
|
||||||
const uint8_t* msgsToUserStartPtr = nullptr;
|
|
||||||
size_t fsRequestsTotalSize = 0;
|
|
||||||
const uint8_t* fsRequestStartPtr = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace cfdp
|
|
|
@ -16,7 +16,7 @@ class RemoteConfigTableIF {
|
||||||
*/
|
*/
|
||||||
class OneRemoteConfigProvider : public RemoteConfigTableIF {
|
class OneRemoteConfigProvider : public RemoteConfigTableIF {
|
||||||
public:
|
public:
|
||||||
explicit OneRemoteConfigProvider(RemoteEntityCfg& cfg) : cfg(cfg) {}
|
explicit OneRemoteConfigProvider(RemoteEntityCfg cfg) : cfg(std::move(cfg)) {}
|
||||||
|
|
||||||
bool getRemoteCfg(const EntityId& remoteId, cfdp::RemoteEntityCfg** cfg_) override {
|
bool getRemoteCfg(const EntityId& remoteId, cfdp::RemoteEntityCfg** cfg_) override {
|
||||||
if (remoteId != cfg.remoteId) {
|
if (remoteId != cfg.remoteId) {
|
||||||
|
@ -27,7 +27,7 @@ class OneRemoteConfigProvider : public RemoteConfigTableIF {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RemoteEntityCfg& cfg;
|
RemoteEntityCfg cfg;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace cfdp
|
} // namespace cfdp
|
||||||
|
|
|
@ -1,74 +0,0 @@
|
||||||
#include "ReservedMessageParser.h"
|
|
||||||
|
|
||||||
#include "fsfw/cfdp/CfdpMessage.h"
|
|
||||||
#include "fsfw/cfdp/handler/PutRequest.h"
|
|
||||||
#include "fsfw/cfdp/tlv/MessageToUserTlv.h"
|
|
||||||
#include "fsfw/ipc/CommandMessage.h"
|
|
||||||
#include "fsfw/ipc/QueueFactory.h"
|
|
||||||
|
|
||||||
using namespace returnvalue;
|
|
||||||
|
|
||||||
cfdp::ReservedMessageParser::ReservedMessageParser(StorageManagerIF& ipcStore,
|
|
||||||
MessageQueueIF& msgQueue,
|
|
||||||
MessageQueueId_t userDestination)
|
|
||||||
: msgQueue(msgQueue), ipcStore(ipcStore), userDestination(userDestination) {}
|
|
||||||
|
|
||||||
ReturnValue_t cfdp::ReservedMessageParser::parse(const MessageToUserTlv* msgsToUserArray,
|
|
||||||
size_t numMsgToUser) {
|
|
||||||
ReturnValue_t result = returnvalue::OK;
|
|
||||||
cfdp::StringLv sourceFileName;
|
|
||||||
cfdp::StringLv destFileName;
|
|
||||||
PutRequest putRequest;
|
|
||||||
const uint8_t* currentPtr = nullptr;
|
|
||||||
size_t deserSize = 0;
|
|
||||||
bool needToSendPutRequest = false;
|
|
||||||
for (size_t idx = 0; idx < numMsgToUser; idx++) {
|
|
||||||
if (&msgsToUserArray[idx] == nullptr) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
uint8_t messageType = 0;
|
|
||||||
if (msgsToUserArray[idx].isReservedCfdpMessage(messageType, ¤tPtr, deserSize)) {
|
|
||||||
if (messageType == static_cast<uint8_t>(ProxyOpMessageType::PUT_REQUEST)) {
|
|
||||||
EntityId entityIdLv;
|
|
||||||
result = entityIdLv.deSerializeFromLv(¤tPtr, &deserSize);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
putRequest.setDestId(entityIdLv);
|
|
||||||
result =
|
|
||||||
sourceFileName.deSerialize(¤tPtr, &deserSize, SerializeIF::Endianness::NETWORK);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result =
|
|
||||||
destFileName.deSerialize(¤tPtr, &deserSize, SerializeIF::Endianness::NETWORK);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
putRequest.setSourceAndDestName(sourceFileName, destFileName);
|
|
||||||
needToSendPutRequest = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (needToSendPutRequest) {
|
|
||||||
store_address_t storeId;
|
|
||||||
uint8_t* dataPtr;
|
|
||||||
result = ipcStore.getFreeElement(&storeId, putRequest.getSerializedSize(), &dataPtr);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
size_t serLen = 0;
|
|
||||||
result = putRequest.serialize(&dataPtr, &serLen, putRequest.getSerializedSize(),
|
|
||||||
SerializeIF::Endianness::MACHINE);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
CommandMessage msg;
|
|
||||||
CfdpMessage::setPutRequest(&msg, storeId);
|
|
||||||
result = msgQueue.sendMessage(userDestination, &msg);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return OK;
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "fsfw/cfdp/tlv/MessageToUserTlv.h"
|
|
||||||
#include "fsfw/ipc/MessageQueueIF.h"
|
|
||||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
|
||||||
|
|
||||||
namespace cfdp {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class parses messages to user for special CFDP messages and converts them to appropriate
|
|
||||||
* CFDP requests sent via the IPC store where applicable. It also provides an API to retrieve
|
|
||||||
* custom messages which are not special CFDP messages from a provided bytestream.
|
|
||||||
*/
|
|
||||||
class ReservedMessageParser {
|
|
||||||
public:
|
|
||||||
ReservedMessageParser(StorageManagerIF& ipcStore, MessageQueueIF& msgQueue,
|
|
||||||
MessageQueueId_t userDestination);
|
|
||||||
|
|
||||||
ReturnValue_t parse(const MessageToUserTlv* msgsToUserArray, size_t numMsgsToUser);
|
|
||||||
|
|
||||||
private:
|
|
||||||
MessageQueueIF& msgQueue;
|
|
||||||
StorageManagerIF& ipcStore;
|
|
||||||
MessageQueueId_t userDestination;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace cfdp
|
|
|
@ -1,376 +1 @@
|
||||||
#include "SourceHandler.h"
|
#include "SourceHandler.h"
|
||||||
|
|
||||||
#include <etl/crc32.h>
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
|
|
||||||
#include "fsfw/cfdp/pdu/EofPduCreator.h"
|
|
||||||
#include "fsfw/cfdp/pdu/FileDataCreator.h"
|
|
||||||
#include "fsfw/cfdp/pdu/MetadataPduCreator.h"
|
|
||||||
#include "fsfw/filesystem/HasFileSystemIF.h"
|
|
||||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
|
||||||
#include "fsfw/objectmanager.h"
|
|
||||||
#include "fsfw/serviceinterface.h"
|
|
||||||
#include "fsfw/tasks/TaskFactory.h"
|
|
||||||
#include "fsfw/tmtcservices/TmTcMessage.h"
|
|
||||||
|
|
||||||
using namespace returnvalue;
|
|
||||||
|
|
||||||
cfdp::SourceHandler::SourceHandler(SourceHandlerParams params, FsfwParams fsfwParams)
|
|
||||||
: sourceParams(std::move(params)), fsfwParams(fsfwParams) {
|
|
||||||
// The entity ID portion of the transaction ID will always remain fixed.
|
|
||||||
transactionParams.id.entityId = sourceParams.cfg.localId;
|
|
||||||
transactionParams.pduConf.sourceId = sourceParams.cfg.localId;
|
|
||||||
if (sourceParams.seqCountProvider.bitWidth() == 8) {
|
|
||||||
transactionParams.pduConf.seqNum.setWidth(cfdp::WidthInBytes::ONE_BYTE);
|
|
||||||
} else if (sourceParams.seqCountProvider.bitWidth() == 16) {
|
|
||||||
transactionParams.pduConf.seqNum.setWidth(cfdp::WidthInBytes::TWO_BYTES);
|
|
||||||
} else if (sourceParams.seqCountProvider.bitWidth() == 32) {
|
|
||||||
transactionParams.pduConf.seqNum.setWidth(cfdp::WidthInBytes::FOUR_BYTES);
|
|
||||||
} else if (sourceParams.seqCountProvider.bitWidth() == 64) {
|
|
||||||
transactionParams.pduConf.seqNum.setWidth(cfdp::WidthInBytes::EIGHT_BYTES);
|
|
||||||
} else {
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::error << "cfdp::SourceHandler: Seq count provider bit width "
|
|
||||||
<< sourceParams.seqCountProvider.bitWidth() << " not allowed" << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printError("cfdp::SourceHandler: Seq count provider bit width %d not allowed\n",
|
|
||||||
sourceParams.seqCountProvider.bitWidth());
|
|
||||||
#endif
|
|
||||||
// Yeah, what am I supposed to do here? Can't throw an exception in the FSFW..
|
|
||||||
transactionParams.pduConf.seqNum.setWidth(cfdp::WidthInBytes::ONE_BYTE);
|
|
||||||
}
|
|
||||||
transactionParams.pduConf.seqNum.setValue(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() {
|
|
||||||
ReturnValue_t result;
|
|
||||||
if (step == TransactionStep::IDLE) {
|
|
||||||
step = TransactionStep::TRANSACTION_START;
|
|
||||||
}
|
|
||||||
if (step == TransactionStep::TRANSACTION_START) {
|
|
||||||
sourceParams.user.transactionIndication(transactionParams.id);
|
|
||||||
result = checksumGeneration();
|
|
||||||
if (result != OK) {
|
|
||||||
addError(result);
|
|
||||||
}
|
|
||||||
step = TransactionStep::SENDING_METADATA;
|
|
||||||
}
|
|
||||||
if (step == TransactionStep::SENDING_METADATA) {
|
|
||||||
result = prepareAndSendMetadataPdu();
|
|
||||||
if (result != OK) {
|
|
||||||
addError(result);
|
|
||||||
}
|
|
||||||
fsmResult.callStatus = CallStatus::CALL_AGAIN;
|
|
||||||
return fsmResult;
|
|
||||||
}
|
|
||||||
if (step == TransactionStep::SENDING_FILE_DATA) {
|
|
||||||
bool noFdPdu = false;
|
|
||||||
result = prepareAndSendNextFileDataPdu(noFdPdu);
|
|
||||||
if (result == OK and !noFdPdu) {
|
|
||||||
fsmResult.callStatus = CallStatus::CALL_AGAIN;
|
|
||||||
return fsmResult;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (step == TransactionStep::SENDING_EOF) {
|
|
||||||
result = prepareAndSendEofPdu();
|
|
||||||
if (result != OK) {
|
|
||||||
addError(result);
|
|
||||||
}
|
|
||||||
if (sourceParams.cfg.indicCfg.eofSentIndicRequired) {
|
|
||||||
sourceParams.user.eofSentIndication(transactionParams.id);
|
|
||||||
}
|
|
||||||
if (transactionParams.closureRequested) {
|
|
||||||
step = TransactionStep::WAIT_FOR_FINISH;
|
|
||||||
fsmResult.callStatus = CallStatus::CALL_AFTER_DELAY;
|
|
||||||
} else {
|
|
||||||
step = TransactionStep::NOTICE_OF_COMPLETION;
|
|
||||||
fsmResult.callStatus = CallStatus::CALL_AGAIN;
|
|
||||||
}
|
|
||||||
return fsmResult;
|
|
||||||
}
|
|
||||||
if (step == TransactionStep::WAIT_FOR_FINISH) {
|
|
||||||
// TODO: In case this is a request with closure, wait for finish.
|
|
||||||
// Done, issue notice of completion
|
|
||||||
step = TransactionStep::NOTICE_OF_COMPLETION;
|
|
||||||
}
|
|
||||||
if (step == TransactionStep::NOTICE_OF_COMPLETION) {
|
|
||||||
noticeOfCompletion();
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
return fsmResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
const cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::stateMachine() {
|
|
||||||
fsmResult.packetsSent = 0;
|
|
||||||
fsmResult.errors = 0;
|
|
||||||
fsmResult.callStatus = CallStatus::DONE;
|
|
||||||
if (state == cfdp::CfdpState::IDLE) {
|
|
||||||
return fsmResult;
|
|
||||||
}
|
|
||||||
if (state == cfdp::CfdpState::BUSY_CLASS_1_NACKED) {
|
|
||||||
return fsmNacked();
|
|
||||||
}
|
|
||||||
return fsmResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t cfdp::SourceHandler::checksumGeneration() {
|
|
||||||
if (transactionParams.fileSize.value() == 0) {
|
|
||||||
// NULL checksum for empty file.
|
|
||||||
transactionParams.crc = 0;
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
std::array<uint8_t, 1024> buf{};
|
|
||||||
etl::crc32 crcCalc;
|
|
||||||
uint64_t currentOffset = 0;
|
|
||||||
FileOpParams params(transactionParams.sourceName.data(), transactionParams.fileSize.value());
|
|
||||||
while (currentOffset < transactionParams.fileSize.value()) {
|
|
||||||
uint64_t readLen;
|
|
||||||
if (currentOffset + buf.size() > transactionParams.fileSize.value()) {
|
|
||||||
readLen = transactionParams.fileSize.value() - currentOffset;
|
|
||||||
} else {
|
|
||||||
readLen = buf.size();
|
|
||||||
}
|
|
||||||
if (readLen > 0) {
|
|
||||||
params.offset = currentOffset;
|
|
||||||
params.size = readLen;
|
|
||||||
auto result = sourceParams.user.vfs.readFromFile(params, buf.data(), buf.size());
|
|
||||||
if (result != OK) {
|
|
||||||
addError(result);
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
crcCalc.add(buf.begin(), buf.begin() + readLen);
|
|
||||||
}
|
|
||||||
currentOffset += readLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
transactionParams.crc = crcCalc.value();
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t cfdp::SourceHandler::transactionStart(PutRequest& putRequest, RemoteEntityCfg& cfg) {
|
|
||||||
if (state != CfdpState::IDLE) {
|
|
||||||
return SOURCE_TRANSACTION_PENDING;
|
|
||||||
}
|
|
||||||
if (cfg.remoteId != putRequest.getDestId()) {
|
|
||||||
return WRONG_REMOTE_CFG_ENTITY_ID;
|
|
||||||
}
|
|
||||||
if (putRequest.getSourceName().getValueLen() == 0) {
|
|
||||||
return SOURCE_NAME_EMPTY;
|
|
||||||
}
|
|
||||||
if (putRequest.getDestName().getValueLen() == 0) {
|
|
||||||
return DEST_NAME_EMPTY;
|
|
||||||
}
|
|
||||||
const char* srcNamePtr = putRequest.getSourceName().getCString(transactionParams.sourceNameSize);
|
|
||||||
const char* destNamePtr = putRequest.getDestName().getCString(transactionParams.destNameSize);
|
|
||||||
std::strncpy(transactionParams.sourceName.data(), srcNamePtr, transactionParams.sourceNameSize);
|
|
||||||
std::strncpy(transactionParams.destName.data(), destNamePtr, transactionParams.destNameSize);
|
|
||||||
// Add 0 termination. The source and dest name size can not be larger than UINT8_MAX, so this
|
|
||||||
// operation is safe.
|
|
||||||
transactionParams.sourceName[transactionParams.sourceNameSize] = '\0';
|
|
||||||
transactionParams.destName[transactionParams.destNameSize] = '\0';
|
|
||||||
FilesystemParams params(transactionParams.sourceName.data());
|
|
||||||
if (!sourceParams.user.vfs.fileExists(params)) {
|
|
||||||
return FILE_DOES_NOT_EXIST;
|
|
||||||
}
|
|
||||||
if (cfg.maxFileSegmentLen > fileBuf.size() or cfg.maxFileSegmentLen == 0) {
|
|
||||||
return FILE_SEGMENT_LEN_INVALID;
|
|
||||||
}
|
|
||||||
// If transmission mode is not set, use default transmission mode for the remote entity.
|
|
||||||
if (not putRequest.getTransmissionMode(transactionParams.pduConf.mode)) {
|
|
||||||
transactionParams.pduConf.mode = cfg.defaultTransmissionMode;
|
|
||||||
}
|
|
||||||
// If closure request field is not set, use default option for the remote entity.
|
|
||||||
if (not putRequest.getClosureRequested(transactionParams.closureRequested)) {
|
|
||||||
transactionParams.closureRequested = cfg.closureRequested;
|
|
||||||
}
|
|
||||||
const EntityId& destId = putRequest.getDestId();
|
|
||||||
// The width of the source and destination ID must be the same. Use the larger ID value to
|
|
||||||
// ensure the width is large enough for both IDs
|
|
||||||
if (destId.getWidth() > transactionParams.pduConf.sourceId.getWidth()) {
|
|
||||||
transactionParams.pduConf.destId = destId;
|
|
||||||
transactionParams.pduConf.sourceId.setWidth(destId.getWidth());
|
|
||||||
} else {
|
|
||||||
transactionParams.pduConf.destId.setValueAndWidth(transactionParams.pduConf.sourceId.getWidth(),
|
|
||||||
destId.getValue());
|
|
||||||
}
|
|
||||||
// Only used for PDU forwarding, file is sent to file receiver regularly here.
|
|
||||||
transactionParams.pduConf.direction = Direction::TOWARDS_RECEIVER;
|
|
||||||
transactionParams.pduConf.seqNum.setValue(sourceParams.seqCountProvider.getAndIncrement());
|
|
||||||
transactionParams.id.seqNum = transactionParams.pduConf.seqNum;
|
|
||||||
|
|
||||||
if (transactionParams.pduConf.mode == TransmissionMode::ACKNOWLEDGED) {
|
|
||||||
state = cfdp::CfdpState::BUSY_CLASS_2_ACKED;
|
|
||||||
} else if (transactionParams.pduConf.mode == TransmissionMode::UNACKNOWLEDGED) {
|
|
||||||
state = cfdp::CfdpState::BUSY_CLASS_1_NACKED;
|
|
||||||
}
|
|
||||||
step = TransactionStep::IDLE;
|
|
||||||
uint64_t fileSize = 0;
|
|
||||||
sourceParams.user.vfs.getFileSize(params, fileSize);
|
|
||||||
transactionParams.pduConf.largeFile = false;
|
|
||||||
if (fileSize > UINT32_MAX) {
|
|
||||||
transactionParams.pduConf.largeFile = true;
|
|
||||||
}
|
|
||||||
if (fileSize == 0) {
|
|
||||||
transactionParams.checksumType = ChecksumType::NULL_CHECKSUM;
|
|
||||||
} else {
|
|
||||||
transactionParams.checksumType = ChecksumType::CRC_32;
|
|
||||||
}
|
|
||||||
transactionParams.fileSize.setFileSize(fileSize, transactionParams.pduConf.largeFile);
|
|
||||||
transactionParams.progress = 0;
|
|
||||||
transactionParams.remoteCfg = cfg;
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t cfdp::SourceHandler::prepareAndSendMetadataPdu() {
|
|
||||||
cfdp::StringLv sourceName(transactionParams.sourceName.data(), transactionParams.sourceNameSize);
|
|
||||||
cfdp::StringLv destName(transactionParams.destName.data(), transactionParams.destNameSize);
|
|
||||||
auto metadataInfo =
|
|
||||||
MetadataGenericInfo(transactionParams.closureRequested, transactionParams.checksumType,
|
|
||||||
transactionParams.fileSize);
|
|
||||||
auto metadataPdu =
|
|
||||||
MetadataPduCreator(transactionParams.pduConf, metadataInfo, sourceName, destName, nullptr, 0);
|
|
||||||
ReturnValue_t result = sendGenericPdu(metadataPdu);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
// Advance FSM if everything works
|
|
||||||
step = TransactionStep::SENDING_FILE_DATA;
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t cfdp::SourceHandler::prepareAndSendNextFileDataPdu(bool& noFileDataPdu) {
|
|
||||||
cfdp::Fss offset(transactionParams.progress);
|
|
||||||
uint64_t readLen;
|
|
||||||
uint64_t fileSize = transactionParams.fileSize.value();
|
|
||||||
noFileDataPdu = false;
|
|
||||||
if (fileSize == 0) {
|
|
||||||
// We are done, no need to send file data PDUs for an empty file.
|
|
||||||
step = TransactionStep::SENDING_EOF;
|
|
||||||
noFileDataPdu = true;
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
if (fileSize < transactionParams.remoteCfg.maxFileSegmentLen) {
|
|
||||||
readLen = transactionParams.fileSize.value();
|
|
||||||
} else {
|
|
||||||
if (transactionParams.progress + transactionParams.remoteCfg.maxFileSegmentLen > fileSize) {
|
|
||||||
readLen = fileSize - transactionParams.progress;
|
|
||||||
} else {
|
|
||||||
readLen = transactionParams.remoteCfg.maxFileSegmentLen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FileOpParams fileParams(transactionParams.sourceName.data(), readLen);
|
|
||||||
fileParams.offset = transactionParams.progress;
|
|
||||||
ReturnValue_t result =
|
|
||||||
sourceParams.user.vfs.readFromFile(fileParams, fileBuf.data(), fileBuf.size());
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
addError(result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
auto fileDataInfo = FileDataInfo(offset, fileBuf.data(), readLen);
|
|
||||||
auto fileDataPdu = FileDataCreator(transactionParams.pduConf, fileDataInfo);
|
|
||||||
result = sendGenericPdu(fileDataPdu);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
transactionParams.progress += readLen;
|
|
||||||
if (transactionParams.progress >= fileSize) {
|
|
||||||
// Advance FSM after all file data PDUs were sent.
|
|
||||||
step = TransactionStep::SENDING_EOF;
|
|
||||||
}
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t cfdp::SourceHandler::prepareAndSendEofPdu() {
|
|
||||||
auto eofInfo =
|
|
||||||
EofInfo(ConditionCode::NO_ERROR, transactionParams.crc, transactionParams.fileSize);
|
|
||||||
auto eofPdu = EofPduCreator(transactionParams.pduConf, eofInfo);
|
|
||||||
ReturnValue_t result = sendGenericPdu(eofPdu);
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t cfdp::SourceHandler::initialize() {
|
|
||||||
if (fsfwParams.tmStore == nullptr) {
|
|
||||||
fsfwParams.tmStore = ObjectManager::instance()->get<StorageManagerIF>(objects::TM_STORE);
|
|
||||||
if (fsfwParams.tmStore == nullptr) {
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fsfwParams.tcStore == nullptr) {
|
|
||||||
fsfwParams.tcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::TC_STORE);
|
|
||||||
if (fsfwParams.tcStore == nullptr) {
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fsfwParams.msgQueue == nullptr) {
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t cfdp::SourceHandler::sendGenericPdu(const SerializeIF& pdu) {
|
|
||||||
uint8_t* dataPtr;
|
|
||||||
store_address_t storeId;
|
|
||||||
ReturnValue_t result =
|
|
||||||
fsfwParams.tmStore->getFreeElement(&storeId, pdu.getSerializedSize(), &dataPtr);
|
|
||||||
if (result != OK) {
|
|
||||||
addError(result);
|
|
||||||
fsmResult.callStatus = CallStatus::CALL_AFTER_DELAY;
|
|
||||||
if (result == StorageManagerIF::DATA_STORAGE_FULL) {
|
|
||||||
return TM_STORE_FULL;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
size_t serializedLen = 0;
|
|
||||||
result = pdu.serializeBe(dataPtr, serializedLen, pdu.getSerializedSize());
|
|
||||||
if (result != OK) {
|
|
||||||
addError(result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
TmTcMessage tmMsg(storeId);
|
|
||||||
result =
|
|
||||||
fsfwParams.msgQueue->sendMessage(fsfwParams.packetDest.getReportReceptionQueue(), &tmMsg);
|
|
||||||
if (result != OK) {
|
|
||||||
fsmResult.callStatus = CallStatus::CALL_AFTER_DELAY;
|
|
||||||
}
|
|
||||||
if (result == MessageQueueIF::FULL) {
|
|
||||||
return TARGET_MSG_QUEUE_FULL;
|
|
||||||
} else if (result == OK) {
|
|
||||||
fsmResult.packetsSent += 1;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t cfdp::SourceHandler::noticeOfCompletion() {
|
|
||||||
if (sourceParams.cfg.indicCfg.transactionFinishedIndicRequired) {
|
|
||||||
cfdp::TransactionFinishedParams params(transactionParams.id, ConditionCode::NO_ERROR,
|
|
||||||
FileDeliveryCode::DATA_COMPLETE,
|
|
||||||
FileDeliveryStatus::RETAINED_IN_FILESTORE);
|
|
||||||
sourceParams.user.transactionFinishedIndication(params);
|
|
||||||
}
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t cfdp::SourceHandler::reset() {
|
|
||||||
step = TransactionStep::IDLE;
|
|
||||||
state = cfdp::CfdpState::IDLE;
|
|
||||||
fsmResult.callStatus = CallStatus::DONE;
|
|
||||||
transactionParams.reset();
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
cfdp::CfdpState cfdp::SourceHandler::getState() const { return state; }
|
|
||||||
|
|
||||||
cfdp::SourceHandler::TransactionStep cfdp::SourceHandler::getStep() const { return step; }
|
|
||||||
|
|
||||||
void cfdp::SourceHandler::addError(ReturnValue_t error) {
|
|
||||||
if (fsmResult.errors < fsmResult.errorCodes.size()) {
|
|
||||||
fsmResult.errorCodes[fsmResult.errors] = error;
|
|
||||||
fsmResult.errors++;
|
|
||||||
fsmResult.result = error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,110 +1,6 @@
|
||||||
#ifndef FSFW_CFDP_CFDPSOURCEHANDLER_H
|
#ifndef FSFW_CFDP_CFDPSOURCEHANDLER_H
|
||||||
#define FSFW_CFDP_CFDPSOURCEHANDLER_H
|
#define FSFW_CFDP_CFDPSOURCEHANDLER_H
|
||||||
|
|
||||||
#include <cstdint>
|
class SourceHandler {};
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "UserBase.h"
|
|
||||||
#include "defs.h"
|
|
||||||
#include "fsfw/cfdp/Fss.h"
|
|
||||||
#include "fsfw/cfdp/handler/PutRequest.h"
|
|
||||||
#include "fsfw/cfdp/handler/mib.h"
|
|
||||||
#include "fsfw/events/EventReportingProxyIF.h"
|
|
||||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
|
||||||
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
|
|
||||||
#include "fsfw/util/ProvidesSeqCountIF.h"
|
|
||||||
|
|
||||||
namespace cfdp {
|
|
||||||
|
|
||||||
struct SourceHandlerParams {
|
|
||||||
SourceHandlerParams(LocalEntityCfg cfg, UserBase& user, ProvidesSeqCountIF& seqCountProvider)
|
|
||||||
: cfg(std::move(cfg)), user(user), seqCountProvider(seqCountProvider) {}
|
|
||||||
|
|
||||||
LocalEntityCfg cfg;
|
|
||||||
UserBase& user;
|
|
||||||
ProvidesSeqCountIF& seqCountProvider;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SourceHandler {
|
|
||||||
public:
|
|
||||||
enum class TransactionStep : uint8_t {
|
|
||||||
IDLE = 0,
|
|
||||||
TRANSACTION_START = 1,
|
|
||||||
SENDING_METADATA = 3,
|
|
||||||
SENDING_FILE_DATA = 4,
|
|
||||||
SENDING_EOF = 5,
|
|
||||||
WAIT_FOR_ACK = 6,
|
|
||||||
WAIT_FOR_FINISH = 7,
|
|
||||||
NOTICE_OF_COMPLETION = 8
|
|
||||||
};
|
|
||||||
struct FsmResult {
|
|
||||||
public:
|
|
||||||
ReturnValue_t result = returnvalue::OK;
|
|
||||||
CallStatus callStatus = CallStatus::CALL_AFTER_DELAY;
|
|
||||||
CfdpState state = CfdpState::IDLE;
|
|
||||||
uint32_t packetsSent = 0;
|
|
||||||
uint8_t errors = 0;
|
|
||||||
std::array<ReturnValue_t, 3> errorCodes = {};
|
|
||||||
};
|
|
||||||
|
|
||||||
SourceHandler(SourceHandlerParams params, FsfwParams fsfwParams);
|
|
||||||
|
|
||||||
[[nodiscard]] CfdpState getState() const;
|
|
||||||
[[nodiscard]] TransactionStep getStep() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pass a put request to the source handler, which might initiate a CFDP transaction and start
|
|
||||||
* the state machine
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
ReturnValue_t transactionStart(PutRequest& putRequest, RemoteEntityCfg& cfg);
|
|
||||||
const FsmResult& stateMachine();
|
|
||||||
|
|
||||||
ReturnValue_t initialize();
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct TransactionParams {
|
|
||||||
uint32_t crc{};
|
|
||||||
std::array<char, UINT8_MAX + 1> sourceName{};
|
|
||||||
size_t sourceNameSize = 0;
|
|
||||||
std::array<char, UINT8_MAX + 1> destName{};
|
|
||||||
size_t destNameSize = 0;
|
|
||||||
cfdp::Fss fileSize;
|
|
||||||
size_t progress = 0;
|
|
||||||
bool closureRequested = false;
|
|
||||||
ChecksumType checksumType = ChecksumType::NULL_CHECKSUM;
|
|
||||||
RemoteEntityCfg remoteCfg;
|
|
||||||
PduConfig pduConf;
|
|
||||||
cfdp::TransactionId id{};
|
|
||||||
|
|
||||||
void reset() {
|
|
||||||
sourceNameSize = 0;
|
|
||||||
destNameSize = 0;
|
|
||||||
fileSize.setFileSize(0, false);
|
|
||||||
progress = 0;
|
|
||||||
closureRequested = false;
|
|
||||||
}
|
|
||||||
} transactionParams;
|
|
||||||
|
|
||||||
cfdp::CfdpState state = cfdp::CfdpState::IDLE;
|
|
||||||
TransactionStep step = TransactionStep::IDLE;
|
|
||||||
std::array<uint8_t, 4096> fileBuf{};
|
|
||||||
SourceHandlerParams sourceParams;
|
|
||||||
cfdp::FsfwParams fsfwParams;
|
|
||||||
FsmResult fsmResult;
|
|
||||||
|
|
||||||
FsmResult& fsmNacked();
|
|
||||||
ReturnValue_t checksumGeneration();
|
|
||||||
ReturnValue_t prepareAndSendMetadataPdu();
|
|
||||||
ReturnValue_t prepareAndSendNextFileDataPdu(bool& noFileDataPdu);
|
|
||||||
ReturnValue_t prepareAndSendEofPdu();
|
|
||||||
ReturnValue_t noticeOfCompletion();
|
|
||||||
ReturnValue_t reset();
|
|
||||||
|
|
||||||
[[nodiscard]] ReturnValue_t sendGenericPdu(const SerializeIF& pdu);
|
|
||||||
void addError(ReturnValue_t error);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace cfdp
|
|
||||||
|
|
||||||
#endif // FSFW_CFDP_CFDPSOURCEHANDLER_H
|
#endif // FSFW_CFDP_CFDPSOURCEHANDLER_H
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "StatusReportIF.h"
|
#include "StatusReportIF.h"
|
||||||
#include "fsfw/cfdp/Fss.h"
|
|
||||||
#include "fsfw/cfdp/VarLenFields.h"
|
#include "fsfw/cfdp/VarLenFields.h"
|
||||||
#include "fsfw/cfdp/tlv/FilestoreResponseTlv.h"
|
#include "fsfw/cfdp/tlv/FilestoreResponseTlv.h"
|
||||||
#include "fsfw/cfdp/tlv/MessageToUserTlv.h"
|
#include "fsfw/cfdp/tlv/MessageToUserTlv.h"
|
||||||
|
@ -28,14 +27,14 @@ struct TransactionFinishedParams {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MetadataRecvdParams {
|
struct MetadataRecvdParams {
|
||||||
MetadataRecvdParams(const TransactionId& id, const EntityId& sourceId, Fss fileSize)
|
MetadataRecvdParams(const TransactionId& id, const EntityId& sourceId)
|
||||||
: id(id), sourceId(sourceId), fileSize(std::move(fileSize)) {}
|
: id(id), sourceId(sourceId) {}
|
||||||
const TransactionId& id;
|
const TransactionId& id;
|
||||||
const EntityId& sourceId;
|
const EntityId& sourceId;
|
||||||
Fss fileSize{};
|
uint64_t fileSize = 0;
|
||||||
const char* sourceFileName = "";
|
const char* sourceFileName = "";
|
||||||
const char* destFileName = "";
|
const char* destFileName = "";
|
||||||
size_t numberOfMsgsToUser = 0;
|
size_t msgsToUserLen = 0;
|
||||||
const MessageToUserTlv* msgsToUserArray = nullptr;
|
const MessageToUserTlv* msgsToUserArray = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -66,7 +65,6 @@ struct FileSegmentRecvdParams {
|
||||||
*/
|
*/
|
||||||
class UserBase {
|
class UserBase {
|
||||||
friend class DestHandler;
|
friend class DestHandler;
|
||||||
friend class SourceHandler;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit UserBase(HasFileSystemIF& vfs);
|
explicit UserBase(HasFileSystemIF& vfs);
|
||||||
|
|
|
@ -1,54 +1,11 @@
|
||||||
#ifndef FSFW_CFDP_HANDLER_DEFS_H
|
#ifndef FSFW_CFDP_HANDLER_DEFS_H
|
||||||
#define FSFW_CFDP_HANDLER_DEFS_H
|
#define FSFW_CFDP_HANDLER_DEFS_H
|
||||||
|
|
||||||
#include <etl/list.h>
|
|
||||||
|
|
||||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
|
||||||
#include "fsfw/storagemanager/storeAddress.h"
|
|
||||||
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
|
|
||||||
|
|
||||||
namespace cfdp {
|
namespace cfdp {
|
||||||
|
|
||||||
enum class CfdpState { IDLE, BUSY_CLASS_1_NACKED, BUSY_CLASS_2_ACKED, SUSPENDED };
|
enum class CfdpStates { IDLE, BUSY_CLASS_1_NACKED, BUSY_CLASS_2_ACKED, SUSPENDED };
|
||||||
|
|
||||||
static constexpr uint8_t SSID = SUBSYSTEM_ID::CFDP;
|
static constexpr uint8_t SSID = SUBSYSTEM_ID::CFDP;
|
||||||
static constexpr uint8_t CID = CLASS_ID::CFDP_HANDLER;
|
|
||||||
|
|
||||||
struct PacketInfo {
|
|
||||||
PacketInfo(PduType type, store_address_t storeId,
|
|
||||||
std::optional<FileDirective> directive = std::nullopt)
|
|
||||||
: pduType(type), directiveType(directive), storeId(storeId) {}
|
|
||||||
|
|
||||||
PduType pduType = PduType::FILE_DATA;
|
|
||||||
std::optional<FileDirective> directiveType = FileDirective::INVALID_DIRECTIVE;
|
|
||||||
store_address_t storeId = store_address_t::invalid();
|
|
||||||
PacketInfo() = default;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FsfwParams {
|
|
||||||
FsfwParams(AcceptsTelemetryIF& packetDest, MessageQueueIF* msgQueue,
|
|
||||||
EventReportingProxyIF* eventReporter, StorageManagerIF& tcStore,
|
|
||||||
StorageManagerIF& tmStore)
|
|
||||||
: FsfwParams(packetDest, msgQueue, eventReporter) {
|
|
||||||
this->tcStore = &tcStore;
|
|
||||||
this->tmStore = &tmStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
FsfwParams(AcceptsTelemetryIF& packetDest, MessageQueueIF* msgQueue,
|
|
||||||
EventReportingProxyIF* eventReporter)
|
|
||||||
: packetDest(packetDest), msgQueue(msgQueue), eventReporter(eventReporter) {}
|
|
||||||
AcceptsTelemetryIF& packetDest;
|
|
||||||
MessageQueueIF* msgQueue;
|
|
||||||
EventReportingProxyIF* eventReporter = nullptr;
|
|
||||||
StorageManagerIF* tcStore = nullptr;
|
|
||||||
StorageManagerIF* tmStore = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <size_t SIZE>
|
|
||||||
using PacketInfoList = etl::list<PacketInfo, SIZE>;
|
|
||||||
using PacketInfoListBase = etl::ilist<PacketInfo>;
|
|
||||||
|
|
||||||
enum class CallStatus { DONE, CALL_AFTER_DELAY, CALL_AGAIN };
|
|
||||||
|
|
||||||
namespace events {
|
namespace events {
|
||||||
|
|
||||||
|
@ -58,19 +15,8 @@ static constexpr Event SERIALIZATION_ERROR = event::makeEvent(SSID, 2, severity:
|
||||||
static constexpr Event FILESTORE_ERROR = event::makeEvent(SSID, 3, severity::LOW);
|
static constexpr Event FILESTORE_ERROR = event::makeEvent(SSID, 3, severity::LOW);
|
||||||
//! [EXPORT] : [COMMENT] P1: Transaction step ID, P2: 0 for source file name, 1 for dest file name
|
//! [EXPORT] : [COMMENT] P1: Transaction step ID, P2: 0 for source file name, 1 for dest file name
|
||||||
static constexpr Event FILENAME_TOO_LARGE_ERROR = event::makeEvent(SSID, 4, severity::LOW);
|
static constexpr Event FILENAME_TOO_LARGE_ERROR = event::makeEvent(SSID, 4, severity::LOW);
|
||||||
//! [EXPORT] : [COMMENT] CFDP request handling failed. P2: Returncode.
|
|
||||||
static constexpr Event HANDLING_CFDP_REQUEST_FAILED = event::makeEvent(SSID, 5, severity::LOW);
|
|
||||||
|
|
||||||
} // namespace events
|
} // namespace events
|
||||||
|
|
||||||
static constexpr ReturnValue_t SOURCE_TRANSACTION_PENDING = returnvalue::makeCode(CID, 0);
|
|
||||||
static constexpr ReturnValue_t FILE_DOES_NOT_EXIST = returnvalue::makeCode(CID, 1);
|
|
||||||
static constexpr ReturnValue_t FILE_SEGMENT_LEN_INVALID = returnvalue::makeCode(CID, 2);
|
|
||||||
static constexpr ReturnValue_t SOURCE_NAME_EMPTY = returnvalue::makeCode(CID, 3);
|
|
||||||
static constexpr ReturnValue_t DEST_NAME_EMPTY = returnvalue::makeCode(CID, 4);
|
|
||||||
static constexpr ReturnValue_t WRONG_REMOTE_CFG_ENTITY_ID = returnvalue::makeCode(CID, 5);
|
|
||||||
static constexpr ReturnValue_t TARGET_MSG_QUEUE_FULL = returnvalue::makeCode(CID, 6);
|
|
||||||
static constexpr ReturnValue_t TM_STORE_FULL = returnvalue::makeCode(CID, 7);
|
|
||||||
|
|
||||||
} // namespace cfdp
|
} // namespace cfdp
|
||||||
#endif // FSFW_CFDP_HANDLER_DEFS_H
|
#endif // FSFW_CFDP_HANDLER_DEFS_H
|
||||||
|
|
|
@ -27,15 +27,14 @@ struct LocalEntityCfg {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RemoteEntityCfg {
|
struct RemoteEntityCfg {
|
||||||
RemoteEntityCfg() = default;
|
|
||||||
explicit RemoteEntityCfg(EntityId id) : remoteId(std::move(id)) {}
|
explicit RemoteEntityCfg(EntityId id) : remoteId(std::move(id)) {}
|
||||||
EntityId remoteId;
|
EntityId remoteId;
|
||||||
size_t maxFileSegmentLen = 1024;
|
size_t maxFileSegmentLen = 2048;
|
||||||
bool closureRequested = false;
|
bool closureRequested = false;
|
||||||
bool crcOnTransmission = false;
|
bool crcOnTransmission = false;
|
||||||
TransmissionMode defaultTransmissionMode = TransmissionMode::UNACKNOWLEDGED;
|
TransmissionMode defaultTransmissionMode = TransmissionMode::UNACKNOWLEDGED;
|
||||||
ChecksumType defaultChecksum = ChecksumType::NULL_CHECKSUM;
|
ChecksumType defaultChecksum = ChecksumType::NULL_CHECKSUM;
|
||||||
uint8_t version = CFDP_VERSION_2;
|
const uint8_t version = CFDP_VERSION_2;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace cfdp
|
} // namespace cfdp
|
||||||
|
|
|
@ -17,7 +17,7 @@ target_sources(
|
||||||
FinishedInfo.cpp
|
FinishedInfo.cpp
|
||||||
FinishedPduCreator.cpp
|
FinishedPduCreator.cpp
|
||||||
FinishedPduReader.cpp
|
FinishedPduReader.cpp
|
||||||
MetadataGenericInfo.cpp
|
MetadataInfo.cpp
|
||||||
MetadataPduCreator.cpp
|
MetadataPduCreator.cpp
|
||||||
MetadataPduReader.cpp
|
MetadataPduReader.cpp
|
||||||
KeepAlivePduCreator.cpp
|
KeepAlivePduCreator.cpp
|
||||||
|
|
|
@ -1,13 +1,8 @@
|
||||||
#include "EofInfo.h"
|
#include "EofInfo.h"
|
||||||
|
|
||||||
#include <utility>
|
EofInfo::EofInfo(cfdp::ConditionCode conditionCode, uint32_t checksum, cfdp::FileSize fileSize,
|
||||||
|
|
||||||
EofInfo::EofInfo(cfdp::ConditionCode conditionCode, uint32_t checksum, cfdp::Fss fileSize,
|
|
||||||
EntityIdTlv* faultLoc)
|
EntityIdTlv* faultLoc)
|
||||||
: conditionCode(conditionCode),
|
: conditionCode(conditionCode), checksum(checksum), fileSize(fileSize), faultLoc(faultLoc) {}
|
||||||
checksum(checksum),
|
|
||||||
fileSize(std::move(fileSize)),
|
|
||||||
faultLoc(faultLoc) {}
|
|
||||||
|
|
||||||
EofInfo::EofInfo(EntityIdTlv* faultLoc)
|
EofInfo::EofInfo(EntityIdTlv* faultLoc)
|
||||||
: conditionCode(cfdp::ConditionCode::NO_CONDITION_FIELD),
|
: conditionCode(cfdp::ConditionCode::NO_CONDITION_FIELD),
|
||||||
|
@ -21,15 +16,15 @@ cfdp::ConditionCode EofInfo::getConditionCode() const { return conditionCode; }
|
||||||
|
|
||||||
EntityIdTlv* EofInfo::getFaultLoc() const { return faultLoc; }
|
EntityIdTlv* EofInfo::getFaultLoc() const { return faultLoc; }
|
||||||
|
|
||||||
cfdp::Fss& EofInfo::getFileSize() { return fileSize; }
|
cfdp::FileSize& EofInfo::getFileSize() { return fileSize; }
|
||||||
|
|
||||||
void EofInfo::setChecksum(uint32_t checksum_) { this->checksum = checksum_; }
|
void EofInfo::setChecksum(uint32_t checksum) { this->checksum = checksum; }
|
||||||
|
|
||||||
void EofInfo::setConditionCode(cfdp::ConditionCode conditionCode_) {
|
void EofInfo::setConditionCode(cfdp::ConditionCode conditionCode) {
|
||||||
this->conditionCode = conditionCode_;
|
this->conditionCode = conditionCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EofInfo::setFaultLoc(EntityIdTlv* faultLoc_) { this->faultLoc = faultLoc_; }
|
void EofInfo::setFaultLoc(EntityIdTlv* faultLoc) { this->faultLoc = faultLoc; }
|
||||||
|
|
||||||
size_t EofInfo::getSerializedSize(bool fssLarge) {
|
size_t EofInfo::getSerializedSize(bool fssLarge) {
|
||||||
// Condition code + spare + 4 byte checksum
|
// Condition code + spare + 4 byte checksum
|
||||||
|
@ -47,6 +42,6 @@ size_t EofInfo::getSerializedSize(bool fssLarge) {
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t EofInfo::setFileSize(size_t fileSize_, bool isLarge) {
|
ReturnValue_t EofInfo::setFileSize(size_t fileSize, bool isLarge) {
|
||||||
return this->fileSize.setFileSize(fileSize_, isLarge);
|
return this->fileSize.setFileSize(fileSize, isLarge);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_EOFINFO_H_
|
#ifndef FSFW_SRC_FSFW_CFDP_PDU_EOFINFO_H_
|
||||||
#define FSFW_SRC_FSFW_CFDP_PDU_EOFINFO_H_
|
#define FSFW_SRC_FSFW_CFDP_PDU_EOFINFO_H_
|
||||||
|
|
||||||
#include "../Fss.h"
|
#include "../FileSize.h"
|
||||||
#include "../definitions.h"
|
#include "../definitions.h"
|
||||||
#include "fsfw/cfdp/tlv/EntityIdTlv.h"
|
#include "fsfw/cfdp/tlv/EntityIdTlv.h"
|
||||||
|
|
||||||
struct EofInfo {
|
struct EofInfo {
|
||||||
public:
|
public:
|
||||||
explicit EofInfo(EntityIdTlv* faultLoc = nullptr);
|
explicit EofInfo(EntityIdTlv* faultLoc = nullptr);
|
||||||
EofInfo(cfdp::ConditionCode conditionCode, uint32_t checksum, cfdp::Fss fileSize,
|
EofInfo(cfdp::ConditionCode conditionCode, uint32_t checksum, cfdp::FileSize fileSize,
|
||||||
EntityIdTlv* faultLoc = nullptr);
|
EntityIdTlv* faultLoc = nullptr);
|
||||||
|
|
||||||
size_t getSerializedSize(bool fssLarge = false);
|
size_t getSerializedSize(bool fssLarge = false);
|
||||||
|
@ -17,7 +17,7 @@ struct EofInfo {
|
||||||
[[nodiscard]] cfdp::ConditionCode getConditionCode() const;
|
[[nodiscard]] cfdp::ConditionCode getConditionCode() const;
|
||||||
|
|
||||||
[[nodiscard]] EntityIdTlv* getFaultLoc() const;
|
[[nodiscard]] EntityIdTlv* getFaultLoc() const;
|
||||||
cfdp::Fss& getFileSize();
|
cfdp::FileSize& getFileSize();
|
||||||
void setChecksum(uint32_t checksum);
|
void setChecksum(uint32_t checksum);
|
||||||
void setConditionCode(cfdp::ConditionCode conditionCode);
|
void setConditionCode(cfdp::ConditionCode conditionCode);
|
||||||
void setFaultLoc(EntityIdTlv* faultLoc);
|
void setFaultLoc(EntityIdTlv* faultLoc);
|
||||||
|
@ -26,7 +26,7 @@ struct EofInfo {
|
||||||
private:
|
private:
|
||||||
cfdp::ConditionCode conditionCode;
|
cfdp::ConditionCode conditionCode;
|
||||||
uint32_t checksum;
|
uint32_t checksum;
|
||||||
cfdp::Fss fileSize;
|
cfdp::FileSize fileSize;
|
||||||
EntityIdTlv* faultLoc = nullptr;
|
EntityIdTlv* faultLoc = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ ReturnValue_t FileDataCreator::serialize(uint8_t** buffer, size_t* size, size_t
|
||||||
*buffer += segmentMetadataLen;
|
*buffer += segmentMetadataLen;
|
||||||
*size += segmentMetadataLen;
|
*size += segmentMetadataLen;
|
||||||
}
|
}
|
||||||
cfdp::Fss& offset = info.getOffset();
|
cfdp::FileSize& offset = info.getOffset();
|
||||||
result = offset.serialize(this->getLargeFileFlag(), buffer, size, maxSize, streamEndianness);
|
result = offset.serialize(this->getLargeFileFlag(), buffer, size, maxSize, streamEndianness);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#include "FileDataInfo.h"
|
#include "FileDataInfo.h"
|
||||||
|
|
||||||
#include <utility>
|
FileDataInfo::FileDataInfo(cfdp::FileSize &offset, const uint8_t *fileData, size_t fileSize)
|
||||||
|
: offset(offset), fileData(fileData), fileSize(fileSize) {}
|
||||||
|
|
||||||
FileDataInfo::FileDataInfo(cfdp::Fss offset, const uint8_t *fileData, size_t fileSize)
|
FileDataInfo::FileDataInfo(cfdp::FileSize &offset) : offset(offset) {}
|
||||||
: offset(std::move(offset)), fileData(fileData), fileSize(fileSize) {}
|
|
||||||
|
|
||||||
void FileDataInfo::setSegmentMetadataFlag(bool enable) {
|
void FileDataInfo::setSegmentMetadataFlag(bool enable) {
|
||||||
if (enable) {
|
if (enable) {
|
||||||
|
@ -71,7 +71,7 @@ const uint8_t *FileDataInfo::getSegmentMetadata(size_t *segmentMetadataLen_) {
|
||||||
return segmentMetadata;
|
return segmentMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
cfdp::Fss &FileDataInfo::getOffset() { return offset; }
|
cfdp::FileSize &FileDataInfo::getOffset() { return offset; }
|
||||||
|
|
||||||
void FileDataInfo::setRecordContinuationState(cfdp::RecordContinuationState recContState) {
|
void FileDataInfo::setRecordContinuationState(cfdp::RecordContinuationState recContState) {
|
||||||
this->recContState = recContState;
|
this->recContState = recContState;
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_FILEDATAINFO_H_
|
#ifndef FSFW_SRC_FSFW_CFDP_PDU_FILEDATAINFO_H_
|
||||||
#define FSFW_SRC_FSFW_CFDP_PDU_FILEDATAINFO_H_
|
#define FSFW_SRC_FSFW_CFDP_PDU_FILEDATAINFO_H_
|
||||||
|
|
||||||
#include <fsfw/cfdp/Fss.h>
|
#include <fsfw/cfdp/FileSize.h>
|
||||||
#include <fsfw/cfdp/definitions.h>
|
#include <fsfw/cfdp/definitions.h>
|
||||||
|
|
||||||
class FileDataInfo {
|
class FileDataInfo {
|
||||||
public:
|
public:
|
||||||
FileDataInfo() = default;
|
explicit FileDataInfo(cfdp::FileSize& offset);
|
||||||
FileDataInfo(cfdp::Fss offset, const uint8_t* fileData, size_t fileSize);
|
FileDataInfo(cfdp::FileSize& offset, const uint8_t* fileData, size_t fileSize);
|
||||||
|
|
||||||
[[nodiscard]] size_t getSerializedSize(bool largeFile = false) const;
|
[[nodiscard]] size_t getSerializedSize(bool largeFile = false) const;
|
||||||
|
|
||||||
cfdp::Fss& getOffset();
|
cfdp::FileSize& getOffset();
|
||||||
const uint8_t* getFileData(size_t* fileSize = nullptr) const;
|
const uint8_t* getFileData(size_t* fileSize = nullptr) const;
|
||||||
void setFileData(const uint8_t* fileData, size_t fileSize);
|
void setFileData(const uint8_t* fileData, size_t fileSize);
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ class FileDataInfo {
|
||||||
private:
|
private:
|
||||||
cfdp::SegmentMetadataFlag segmentMetadataFlag = cfdp::SegmentMetadataFlag::NOT_PRESENT;
|
cfdp::SegmentMetadataFlag segmentMetadataFlag = cfdp::SegmentMetadataFlag::NOT_PRESENT;
|
||||||
cfdp::SegmentationControl segCtrl = cfdp::SegmentationControl::NO_RECORD_BOUNDARIES_PRESERVATION;
|
cfdp::SegmentationControl segCtrl = cfdp::SegmentationControl::NO_RECORD_BOUNDARIES_PRESERVATION;
|
||||||
cfdp::Fss offset;
|
cfdp::FileSize& offset;
|
||||||
const uint8_t* fileData = nullptr;
|
const uint8_t* fileData = nullptr;
|
||||||
size_t fileSize = 0;
|
size_t fileSize = 0;
|
||||||
cfdp::RecordContinuationState recContState = cfdp::RecordContinuationState::NO_START_NO_END;
|
cfdp::RecordContinuationState recContState = cfdp::RecordContinuationState::NO_START_NO_END;
|
||||||
|
|
|
@ -103,11 +103,11 @@ void PduHeaderReader::getTransactionSeqNum(cfdp::TransactionSeqNum &seqNum) cons
|
||||||
}
|
}
|
||||||
|
|
||||||
void PduHeaderReader::assignVarLenField(cfdp::VarLenField *field, cfdp::WidthInBytes width,
|
void PduHeaderReader::assignVarLenField(cfdp::VarLenField *field, cfdp::WidthInBytes width,
|
||||||
void *sourcePtr) {
|
void *sourcePtr) const {
|
||||||
switch (width) {
|
switch (width) {
|
||||||
case (cfdp::WidthInBytes::ONE_BYTE): {
|
case (cfdp::WidthInBytes::ONE_BYTE): {
|
||||||
auto *fieldTyped = static_cast<uint8_t *>(sourcePtr);
|
auto *fieldTyped = static_cast<uint8_t *>(sourcePtr);
|
||||||
field->setValueAndWidth(width, *fieldTyped);
|
field->setValue(width, *fieldTyped);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (cfdp::WidthInBytes::TWO_BYTES): {
|
case (cfdp::WidthInBytes::TWO_BYTES): {
|
||||||
|
@ -115,7 +115,7 @@ void PduHeaderReader::assignVarLenField(cfdp::VarLenField *field, cfdp::WidthInB
|
||||||
size_t deserSize = 0;
|
size_t deserSize = 0;
|
||||||
SerializeAdapter::deSerialize(&fieldTyped, static_cast<uint8_t *>(sourcePtr), &deserSize,
|
SerializeAdapter::deSerialize(&fieldTyped, static_cast<uint8_t *>(sourcePtr), &deserSize,
|
||||||
SerializeIF::Endianness::NETWORK);
|
SerializeIF::Endianness::NETWORK);
|
||||||
field->setValueAndWidth(width, fieldTyped);
|
field->setValue(width, fieldTyped);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (cfdp::WidthInBytes::FOUR_BYTES): {
|
case (cfdp::WidthInBytes::FOUR_BYTES): {
|
||||||
|
@ -123,15 +123,7 @@ void PduHeaderReader::assignVarLenField(cfdp::VarLenField *field, cfdp::WidthInB
|
||||||
size_t deserSize = 0;
|
size_t deserSize = 0;
|
||||||
SerializeAdapter::deSerialize(&fieldTyped, static_cast<uint8_t *>(sourcePtr), &deserSize,
|
SerializeAdapter::deSerialize(&fieldTyped, static_cast<uint8_t *>(sourcePtr), &deserSize,
|
||||||
SerializeIF::Endianness::NETWORK);
|
SerializeIF::Endianness::NETWORK);
|
||||||
field->setValueAndWidth(width, fieldTyped);
|
field->setValue(width, fieldTyped);
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (cfdp::WidthInBytes::EIGHT_BYTES): {
|
|
||||||
uint64_t fieldTyped = 0;
|
|
||||||
size_t deserSize = 0;
|
|
||||||
SerializeAdapter::deSerialize(&fieldTyped, static_cast<uint8_t *>(sourcePtr), &deserSize,
|
|
||||||
SerializeIF::Endianness::NETWORK);
|
|
||||||
field->setValueAndWidth(width, fieldTyped);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "KeepAlivePduCreator.h"
|
#include "KeepAlivePduCreator.h"
|
||||||
|
|
||||||
KeepAlivePduCreator::KeepAlivePduCreator(PduConfig &conf, cfdp::Fss &progress)
|
KeepAlivePduCreator::KeepAlivePduCreator(PduConfig &conf, cfdp::FileSize &progress)
|
||||||
: FileDirectiveCreator(conf, cfdp::FileDirective::KEEP_ALIVE, 4), progress(progress) {
|
: FileDirectiveCreator(conf, cfdp::FileDirective::KEEP_ALIVE, 4), progress(progress) {
|
||||||
updateDirectiveFieldLen();
|
updateDirectiveFieldLen();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#ifndef FSFW_CFDP_PDU_KEEPALIVEPDUSERIALIZER_H_
|
#ifndef FSFW_CFDP_PDU_KEEPALIVEPDUSERIALIZER_H_
|
||||||
#define FSFW_CFDP_PDU_KEEPALIVEPDUSERIALIZER_H_
|
#define FSFW_CFDP_PDU_KEEPALIVEPDUSERIALIZER_H_
|
||||||
|
|
||||||
#include "fsfw/cfdp/Fss.h"
|
#include "fsfw/cfdp/FileSize.h"
|
||||||
#include "fsfw/cfdp/pdu/FileDirectiveCreator.h"
|
#include "fsfw/cfdp/pdu/FileDirectiveCreator.h"
|
||||||
|
|
||||||
class KeepAlivePduCreator : public FileDirectiveCreator {
|
class KeepAlivePduCreator : public FileDirectiveCreator {
|
||||||
public:
|
public:
|
||||||
KeepAlivePduCreator(PduConfig& conf, cfdp::Fss& progress);
|
KeepAlivePduCreator(PduConfig& conf, cfdp::FileSize& progress);
|
||||||
|
|
||||||
void updateDirectiveFieldLen();
|
void updateDirectiveFieldLen();
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ class KeepAlivePduCreator : public FileDirectiveCreator {
|
||||||
Endianness streamEndianness) const override;
|
Endianness streamEndianness) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
cfdp::Fss& progress;
|
cfdp::FileSize& progress;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_CFDP_PDU_KEEPALIVEPDUSERIALIZER_H_ */
|
#endif /* FSFW_CFDP_PDU_KEEPALIVEPDUSERIALIZER_H_ */
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "KeepAlivePduReader.h"
|
#include "KeepAlivePduReader.h"
|
||||||
|
|
||||||
KeepAlivePduReader::KeepAlivePduReader(const uint8_t* pduBuf, size_t maxSize, cfdp::Fss& progress)
|
KeepAlivePduReader::KeepAlivePduReader(const uint8_t* pduBuf, size_t maxSize,
|
||||||
|
cfdp::FileSize& progress)
|
||||||
: FileDirectiveReader(pduBuf, maxSize), progress(progress) {}
|
: FileDirectiveReader(pduBuf, maxSize), progress(progress) {}
|
||||||
|
|
||||||
ReturnValue_t KeepAlivePduReader::parseData() {
|
ReturnValue_t KeepAlivePduReader::parseData() {
|
||||||
|
@ -14,4 +15,4 @@ ReturnValue_t KeepAlivePduReader::parseData() {
|
||||||
return progress.deSerialize(&buffer, &remLen, getEndianness());
|
return progress.deSerialize(&buffer, &remLen, getEndianness());
|
||||||
}
|
}
|
||||||
|
|
||||||
cfdp::Fss& KeepAlivePduReader::getProgress() { return progress; }
|
cfdp::FileSize& KeepAlivePduReader::getProgress() { return progress; }
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
#ifndef FSFW_CFDP_PDU_KEEPALIVEREADER_H_
|
#ifndef FSFW_CFDP_PDU_KEEPALIVEREADER_H_
|
||||||
#define FSFW_CFDP_PDU_KEEPALIVEREADER_H_
|
#define FSFW_CFDP_PDU_KEEPALIVEREADER_H_
|
||||||
|
|
||||||
#include "fsfw/cfdp/Fss.h"
|
#include "fsfw/cfdp/FileSize.h"
|
||||||
#include "fsfw/cfdp/pdu/FileDirectiveReader.h"
|
#include "fsfw/cfdp/pdu/FileDirectiveReader.h"
|
||||||
|
|
||||||
class KeepAlivePduReader : public FileDirectiveReader {
|
class KeepAlivePduReader : public FileDirectiveReader {
|
||||||
public:
|
public:
|
||||||
KeepAlivePduReader(const uint8_t* pduBuf, size_t maxSize, cfdp::Fss& progress);
|
KeepAlivePduReader(const uint8_t* pduBuf, size_t maxSize, cfdp::FileSize& progress);
|
||||||
|
|
||||||
ReturnValue_t parseData() override;
|
ReturnValue_t parseData() override;
|
||||||
|
|
||||||
cfdp::Fss& getProgress();
|
cfdp::FileSize& getProgress();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
cfdp::Fss& progress;
|
cfdp::FileSize& progress;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_CFDP_PDU_KEEPALIVEPDUREADER_H_ */
|
#endif /* FSFW_CFDP_PDU_KEEPALIVEPDUREADER_H_ */
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
#include "MetadataGenericInfo.h"
|
|
||||||
|
|
||||||
MetadataGenericInfo::MetadataGenericInfo(bool closureRequested, cfdp::ChecksumType checksumType,
|
|
||||||
cfdp::Fss fileSize)
|
|
||||||
: MetadataGenericInfo(std::move(fileSize)) {
|
|
||||||
this->closureRequested = closureRequested;
|
|
||||||
this->checksumType = checksumType;
|
|
||||||
}
|
|
||||||
|
|
||||||
MetadataGenericInfo::MetadataGenericInfo(cfdp::Fss fileSize) : fileSize(std::move(fileSize)) {}
|
|
||||||
|
|
||||||
cfdp::ChecksumType MetadataGenericInfo::getChecksumType() const { return checksumType; }
|
|
||||||
|
|
||||||
void MetadataGenericInfo::setChecksumType(cfdp::ChecksumType checksumType_) {
|
|
||||||
checksumType = checksumType_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MetadataGenericInfo::isClosureRequested() const { return closureRequested; }
|
|
||||||
|
|
||||||
void MetadataGenericInfo::setClosureRequested(bool closureRequested_) {
|
|
||||||
closureRequested = closureRequested_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const cfdp::Fss& MetadataGenericInfo::getFileSize() const { return fileSize; }
|
|
||||||
|
|
||||||
size_t MetadataGenericInfo::getSerializedSize(bool fssLarge) {
|
|
||||||
// 1 byte + minimal FSS 4 bytes
|
|
||||||
size_t size = 5;
|
|
||||||
if (fssLarge) {
|
|
||||||
size += 4;
|
|
||||||
}
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
cfdp::Fss& MetadataGenericInfo::getMutFileSize() { return fileSize; }
|
|
|
@ -1,35 +0,0 @@
|
||||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_METADATAINFO_H_
|
|
||||||
#define FSFW_SRC_FSFW_CFDP_PDU_METADATAINFO_H_
|
|
||||||
|
|
||||||
#include <optional>
|
|
||||||
|
|
||||||
#include "fsfw/cfdp/Fss.h"
|
|
||||||
#include "fsfw/cfdp/definitions.h"
|
|
||||||
#include "fsfw/cfdp/tlv/Lv.h"
|
|
||||||
#include "fsfw/cfdp/tlv/StringLv.h"
|
|
||||||
#include "fsfw/cfdp/tlv/Tlv.h"
|
|
||||||
|
|
||||||
class MetadataGenericInfo {
|
|
||||||
public:
|
|
||||||
MetadataGenericInfo() = default;
|
|
||||||
explicit MetadataGenericInfo(cfdp::Fss fileSize);
|
|
||||||
MetadataGenericInfo(bool closureRequested, cfdp::ChecksumType checksumType, cfdp::Fss fileSize);
|
|
||||||
|
|
||||||
static size_t getSerializedSize(bool fssLarge = false);
|
|
||||||
|
|
||||||
[[nodiscard]] cfdp::ChecksumType getChecksumType() const;
|
|
||||||
void setChecksumType(cfdp::ChecksumType checksumType);
|
|
||||||
[[nodiscard]] bool isClosureRequested() const;
|
|
||||||
void setClosureRequested(bool closureRequested = false);
|
|
||||||
|
|
||||||
[[nodiscard]] const cfdp::Fss& getFileSize() const;
|
|
||||||
|
|
||||||
cfdp::Fss& getMutFileSize();
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool closureRequested = false;
|
|
||||||
cfdp::ChecksumType checksumType = cfdp::ChecksumType::NULL_CHECKSUM;
|
|
||||||
cfdp::Fss fileSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_METADATAINFO_H_ */
|
|
103
src/fsfw/cfdp/pdu/MetadataInfo.cpp
Normal file
103
src/fsfw/cfdp/pdu/MetadataInfo.cpp
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
#include "MetadataInfo.h"
|
||||||
|
|
||||||
|
MetadataInfo::MetadataInfo(bool closureRequested, cfdp::ChecksumType checksumType,
|
||||||
|
cfdp::FileSize& fileSize, cfdp::StringLv& sourceFileName,
|
||||||
|
cfdp::StringLv& destFileName)
|
||||||
|
: MetadataInfo(fileSize, sourceFileName, destFileName) {
|
||||||
|
this->closureRequested = closureRequested;
|
||||||
|
this->checksumType = checksumType;
|
||||||
|
}
|
||||||
|
|
||||||
|
MetadataInfo::MetadataInfo(cfdp::FileSize& fileSize, cfdp::StringLv& sourceFileName,
|
||||||
|
cfdp::StringLv& destFileName)
|
||||||
|
: fileSize(fileSize), sourceFileName(sourceFileName), destFileName(destFileName) {}
|
||||||
|
|
||||||
|
void MetadataInfo::setOptionsArray(cfdp::Tlv** optionsArray_, std::optional<size_t> optionsLen_,
|
||||||
|
std::optional<size_t> maxOptionsLen_) {
|
||||||
|
this->optionsArray = optionsArray_;
|
||||||
|
if (maxOptionsLen_) {
|
||||||
|
this->maxOptionsLen = maxOptionsLen_.value();
|
||||||
|
}
|
||||||
|
if (optionsLen_) {
|
||||||
|
this->optionsLen = optionsLen_.value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cfdp::ChecksumType MetadataInfo::getChecksumType() const { return checksumType; }
|
||||||
|
|
||||||
|
void MetadataInfo::setChecksumType(cfdp::ChecksumType checksumType_) {
|
||||||
|
checksumType = checksumType_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MetadataInfo::isClosureRequested() const { return closureRequested; }
|
||||||
|
|
||||||
|
void MetadataInfo::setClosureRequested(bool closureRequested_) {
|
||||||
|
closureRequested = closureRequested_;
|
||||||
|
}
|
||||||
|
|
||||||
|
cfdp::StringLv& 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 optionsArray == nullptr) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
*optionsArray_ = optionsArray;
|
||||||
|
if (optionsLen_ != nullptr) {
|
||||||
|
*optionsLen_ = this->optionsLen;
|
||||||
|
}
|
||||||
|
if (maxOptsLen != nullptr) {
|
||||||
|
*maxOptsLen = this->maxOptionsLen;
|
||||||
|
}
|
||||||
|
return returnvalue::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::StringLv& destFileName_) {
|
||||||
|
this->destFileName = destFileName_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MetadataInfo::setSourceFileName(cfdp::StringLv& 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::StringLv& MetadataInfo::getSourceFileName() { return sourceFileName; }
|
55
src/fsfw/cfdp/pdu/MetadataInfo.h
Normal file
55
src/fsfw/cfdp/pdu/MetadataInfo.h
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
#ifndef FSFW_SRC_FSFW_CFDP_PDU_METADATAINFO_H_
|
||||||
|
#define FSFW_SRC_FSFW_CFDP_PDU_METADATAINFO_H_
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include "fsfw/cfdp/FileSize.h"
|
||||||
|
#include "fsfw/cfdp/definitions.h"
|
||||||
|
#include "fsfw/cfdp/tlv/Lv.h"
|
||||||
|
#include "fsfw/cfdp/tlv/StringLv.h"
|
||||||
|
#include "fsfw/cfdp/tlv/Tlv.h"
|
||||||
|
|
||||||
|
class MetadataInfo {
|
||||||
|
public:
|
||||||
|
MetadataInfo(cfdp::FileSize& fileSize, cfdp::StringLv& sourceFileName,
|
||||||
|
cfdp::StringLv& destFileName);
|
||||||
|
MetadataInfo(bool closureRequested, cfdp::ChecksumType checksumType, cfdp::FileSize& fileSize,
|
||||||
|
cfdp::StringLv& sourceFileName, cfdp::StringLv& destFileName);
|
||||||
|
|
||||||
|
size_t getSerializedSize(bool fssLarge = false);
|
||||||
|
|
||||||
|
void setOptionsArray(cfdp::Tlv** optionsArray, std::optional<size_t> optionsLen,
|
||||||
|
std::optional<size_t> maxOptionsLen);
|
||||||
|
[[nodiscard]] cfdp::ChecksumType getChecksumType() const;
|
||||||
|
void setChecksumType(cfdp::ChecksumType checksumType);
|
||||||
|
[[nodiscard]] bool isClosureRequested() const;
|
||||||
|
void setClosureRequested(bool closureRequested = false);
|
||||||
|
|
||||||
|
void setDestFileName(cfdp::StringLv& destFileName);
|
||||||
|
void setSourceFileName(cfdp::StringLv& sourceFileName);
|
||||||
|
|
||||||
|
cfdp::StringLv& getDestFileName();
|
||||||
|
cfdp::StringLv& getSourceFileName();
|
||||||
|
cfdp::FileSize& getFileSize();
|
||||||
|
|
||||||
|
[[nodiscard]] bool hasOptions() const;
|
||||||
|
[[nodiscard]] bool canHoldOptions() const;
|
||||||
|
ReturnValue_t getOptions(cfdp::Tlv*** optionsArray, size_t* optionsLen, size_t* maxOptsLen);
|
||||||
|
void setOptionsLen(size_t optionsLen);
|
||||||
|
[[nodiscard]] size_t getOptionsLen() const;
|
||||||
|
void setMaxOptionsLen(size_t maxOptionsLen);
|
||||||
|
[[nodiscard]] size_t getMaxOptionsLen() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool closureRequested = false;
|
||||||
|
cfdp::ChecksumType checksumType = cfdp::ChecksumType::NULL_CHECKSUM;
|
||||||
|
cfdp::FileSize& fileSize;
|
||||||
|
cfdp::StringLv& sourceFileName;
|
||||||
|
cfdp::StringLv& destFileName;
|
||||||
|
|
||||||
|
cfdp::Tlv** optionsArray = nullptr;
|
||||||
|
size_t optionsLen = 0;
|
||||||
|
size_t maxOptionsLen = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* FSFW_SRC_FSFW_CFDP_PDU_METADATAINFO_H_ */
|
|
@ -1,26 +1,12 @@
|
||||||
#include "MetadataPduCreator.h"
|
#include "MetadataPduCreator.h"
|
||||||
|
|
||||||
MetadataPduCreator::MetadataPduCreator(PduConfig &conf, MetadataGenericInfo &info,
|
MetadataPduCreator::MetadataPduCreator(PduConfig &conf, MetadataInfo &info)
|
||||||
cfdp::StringLv &srcFileName, cfdp::StringLv &destFileName,
|
: FileDirectiveCreator(conf, cfdp::FileDirective::METADATA, 5), info(info) {
|
||||||
cfdp::Tlv **optionsArray, size_t optionsLen)
|
|
||||||
: FileDirectiveCreator(conf, cfdp::FileDirective::METADATA, 5),
|
|
||||||
info(info),
|
|
||||||
srcFileName(srcFileName),
|
|
||||||
destFileName(destFileName),
|
|
||||||
optionsArray(optionsArray),
|
|
||||||
optionsLen(optionsLen) {
|
|
||||||
updateDirectiveFieldLen();
|
updateDirectiveFieldLen();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetadataPduCreator::updateDirectiveFieldLen() {
|
void MetadataPduCreator::updateDirectiveFieldLen() {
|
||||||
size_t dirFieldLen = MetadataGenericInfo::getSerializedSize(HeaderCreator::getLargeFileFlag()) +
|
setDirectiveDataFieldLen(info.getSerializedSize(getLargeFileFlag()));
|
||||||
srcFileName.getSerializedSize() + destFileName.getSerializedSize();
|
|
||||||
if (optionsLen > 0 and optionsArray != nullptr) {
|
|
||||||
for (size_t idx = 0; idx < optionsLen; idx++) {
|
|
||||||
dirFieldLen += optionsArray[idx]->getSerializedSize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setDirectiveDataFieldLen(dirFieldLen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t MetadataPduCreator::getSerializedSize() const {
|
size_t MetadataPduCreator::getSerializedSize() const {
|
||||||
|
@ -43,18 +29,21 @@ ReturnValue_t MetadataPduCreator::serialize(uint8_t **buffer, size_t *size, size
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
result = srcFileName.serialize(buffer, size, maxSize, streamEndianness);
|
result = info.getSourceFileName().serialize(buffer, size, maxSize, streamEndianness);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
result = destFileName.serialize(buffer, size, maxSize, streamEndianness);
|
result = info.getDestFileName().serialize(buffer, size, maxSize, streamEndianness);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optionsLen > 0 and optionsArray != nullptr) {
|
if (info.hasOptions()) {
|
||||||
for (size_t idx = 0; idx < optionsLen; idx++) {
|
cfdp::Tlv **optsArray = nullptr;
|
||||||
result = optionsArray[idx]->serialize(buffer, size, maxSize, streamEndianness);
|
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 != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -62,5 +51,3 @@ ReturnValue_t MetadataPduCreator::serialize(uint8_t **buffer, size_t *size, size
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
const cfdp::StringLv &MetadataPduCreator::getSourceFileName() const { return srcFileName; }
|
|
||||||
const cfdp::StringLv &MetadataPduCreator::getDestFileName() const { return destFileName; }
|
|
||||||
|
|
|
@ -2,30 +2,22 @@
|
||||||
#define FSFW_CFDP_PDU_METADATAPDUCREATOR_H_
|
#define FSFW_CFDP_PDU_METADATAPDUCREATOR_H_
|
||||||
|
|
||||||
#include "fsfw/cfdp/pdu/FileDirectiveCreator.h"
|
#include "fsfw/cfdp/pdu/FileDirectiveCreator.h"
|
||||||
#include "fsfw/cfdp/pdu/MetadataGenericInfo.h"
|
#include "fsfw/cfdp/pdu/MetadataInfo.h"
|
||||||
|
|
||||||
class MetadataPduCreator : public FileDirectiveCreator {
|
class MetadataPduCreator : public FileDirectiveCreator {
|
||||||
public:
|
public:
|
||||||
MetadataPduCreator(PduConfig& conf, MetadataGenericInfo& info, cfdp::StringLv& srcFileName,
|
MetadataPduCreator(PduConfig& conf, MetadataInfo& info);
|
||||||
cfdp::StringLv& destFileName, cfdp::Tlv** optionsArray, size_t optionsLen);
|
|
||||||
|
|
||||||
void updateDirectiveFieldLen();
|
void updateDirectiveFieldLen();
|
||||||
|
|
||||||
[[nodiscard]] size_t getSerializedSize() const override;
|
[[nodiscard]] size_t getSerializedSize() const override;
|
||||||
|
|
||||||
const cfdp::StringLv& getSourceFileName() const;
|
|
||||||
const cfdp::StringLv& getDestFileName() const;
|
|
||||||
|
|
||||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||||
Endianness streamEndianness) const override;
|
Endianness streamEndianness) const override;
|
||||||
using FileDirectiveCreator::serialize;
|
using FileDirectiveCreator::serialize;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MetadataGenericInfo& info;
|
MetadataInfo& info;
|
||||||
cfdp::StringLv& srcFileName;
|
|
||||||
cfdp::StringLv& destFileName;
|
|
||||||
cfdp::Tlv** optionsArray;
|
|
||||||
size_t optionsLen;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_CFDP_PDU_METADATAPDUCREATOR_H_ */
|
#endif /* FSFW_CFDP_PDU_METADATAPDUCREATOR_H_ */
|
||||||
|
|
|
@ -1,15 +1,9 @@
|
||||||
#include "MetadataPduReader.h"
|
#include "MetadataPduReader.h"
|
||||||
|
|
||||||
MetadataPduReader::MetadataPduReader(const uint8_t* pduBuf, size_t maxSize,
|
MetadataPduReader::MetadataPduReader(const uint8_t* pduBuf, size_t maxSize, MetadataInfo& info)
|
||||||
MetadataGenericInfo& info, cfdp::Tlv* optionsArray,
|
: FileDirectiveReader(pduBuf, maxSize), info(info) {}
|
||||||
size_t optArrayMaxSize)
|
|
||||||
: FileDirectiveReader(pduBuf, maxSize),
|
|
||||||
info(info),
|
|
||||||
optionArray(optionsArray),
|
|
||||||
optionArrayMaxSize(optArrayMaxSize) {}
|
|
||||||
|
|
||||||
ReturnValue_t MetadataPduReader::parseData() {
|
ReturnValue_t MetadataPduReader::parseData() {
|
||||||
parsedOptions = 0;
|
|
||||||
ReturnValue_t result = FileDirectiveReader::parseData();
|
ReturnValue_t result = FileDirectiveReader::parseData();
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
|
@ -25,43 +19,39 @@ ReturnValue_t MetadataPduReader::parseData() {
|
||||||
remSize -= 1;
|
remSize -= 1;
|
||||||
buf += 1;
|
buf += 1;
|
||||||
auto endianness = getEndianness();
|
auto endianness = getEndianness();
|
||||||
result = info.getMutFileSize().deSerialize(&buf, &remSize, endianness);
|
result = info.getFileSize().deSerialize(&buf, &remSize, endianness);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
result = srcFileName.deSerialize(&buf, &remSize, endianness);
|
result = info.getSourceFileName().deSerialize(&buf, &remSize, endianness);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
result = destFileName.deSerialize(&buf, &remSize, endianness);
|
result = info.getDestFileName().deSerialize(&buf, &remSize, endianness);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info.setOptionsLen(0);
|
||||||
if (remSize > 0) {
|
if (remSize > 0) {
|
||||||
if (optionArrayMaxSize == 0 or optionArray == nullptr) {
|
if (not info.canHoldOptions()) {
|
||||||
return cfdp::METADATA_CANT_PARSE_OPTIONS;
|
return cfdp::METADATA_CANT_PARSE_OPTIONS;
|
||||||
}
|
}
|
||||||
|
cfdp::Tlv** optionsArray = nullptr;
|
||||||
|
size_t optsMaxLen = 0;
|
||||||
size_t optsIdx = 0;
|
size_t optsIdx = 0;
|
||||||
|
info.getOptions(&optionsArray, nullptr, &optsMaxLen);
|
||||||
while (remSize > 0) {
|
while (remSize > 0) {
|
||||||
if (optsIdx > optionArrayMaxSize) {
|
if (optsIdx > optsMaxLen) {
|
||||||
return cfdp::METADATA_CANT_PARSE_OPTIONS;
|
return cfdp::METADATA_CANT_PARSE_OPTIONS;
|
||||||
}
|
}
|
||||||
result = optionArray[optsIdx].deSerialize(&buf, &remSize, endianness);
|
result = optionsArray[optsIdx]->deSerialize(&buf, &remSize, endianness);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
optsIdx++;
|
optsIdx++;
|
||||||
}
|
}
|
||||||
parsedOptions = optsIdx;
|
info.setOptionsLen(optsIdx);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t MetadataPduReader::getNumberOfParsedOptions() const { return parsedOptions; }
|
|
||||||
|
|
||||||
const cfdp::StringLv& MetadataPduReader::getSourceFileName() const { return srcFileName; }
|
|
||||||
|
|
||||||
const cfdp::StringLv& MetadataPduReader::getDestFileName() const { return destFileName; }
|
|
||||||
|
|
||||||
const MetadataGenericInfo& MetadataPduReader::getGenericInfo() const { return info; }
|
|
||||||
|
|
|
@ -2,28 +2,16 @@
|
||||||
#define FSFW_CFDP_PDU_METADATAPDUREADER_H_
|
#define FSFW_CFDP_PDU_METADATAPDUREADER_H_
|
||||||
|
|
||||||
#include "fsfw/cfdp/pdu/FileDirectiveReader.h"
|
#include "fsfw/cfdp/pdu/FileDirectiveReader.h"
|
||||||
#include "fsfw/cfdp/pdu/MetadataGenericInfo.h"
|
#include "fsfw/cfdp/pdu/MetadataInfo.h"
|
||||||
|
|
||||||
class MetadataPduReader : public FileDirectiveReader {
|
class MetadataPduReader : public FileDirectiveReader {
|
||||||
public:
|
public:
|
||||||
MetadataPduReader(const uint8_t* pduBuf, size_t maxSize, MetadataGenericInfo& info,
|
MetadataPduReader(const uint8_t* pduBuf, size_t maxSize, MetadataInfo& info);
|
||||||
cfdp::Tlv* optionsArray, size_t optArrayMaxSize);
|
|
||||||
|
|
||||||
ReturnValue_t parseData() override;
|
ReturnValue_t parseData() override;
|
||||||
|
|
||||||
[[nodiscard]] const MetadataGenericInfo& getGenericInfo() const;
|
|
||||||
[[nodiscard]] const cfdp::StringLv& getSourceFileName() const;
|
|
||||||
[[nodiscard]] const cfdp::StringLv& getDestFileName() const;
|
|
||||||
|
|
||||||
[[nodiscard]] size_t getNumberOfParsedOptions() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
cfdp::StringLv srcFileName;
|
MetadataInfo& info;
|
||||||
cfdp::StringLv destFileName;
|
|
||||||
MetadataGenericInfo& info;
|
|
||||||
cfdp::Tlv* optionArray;
|
|
||||||
size_t optionArrayMaxSize;
|
|
||||||
size_t parsedOptions = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_CFDP_PDU_METADATAPDUREADER_H_ */
|
#endif /* FSFW_CFDP_PDU_METADATAPDUREADER_H_ */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "NakInfo.h"
|
#include "NakInfo.h"
|
||||||
|
|
||||||
NakInfo::NakInfo(cfdp::Fss startOfScope, cfdp::Fss endOfScope)
|
NakInfo::NakInfo(cfdp::FileSize startOfScope, cfdp::FileSize endOfScope)
|
||||||
: startOfScope(startOfScope), endOfScope(endOfScope) {}
|
: startOfScope(startOfScope), endOfScope(endOfScope) {}
|
||||||
|
|
||||||
size_t NakInfo::getSerializedSize(bool fssLarge) {
|
size_t NakInfo::getSerializedSize(bool fssLarge) {
|
||||||
|
@ -57,9 +57,9 @@ void NakInfo::setSegmentRequests(SegmentRequest* segmentRequests, size_t* segmen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cfdp::Fss& NakInfo::getStartOfScope() { return startOfScope; }
|
cfdp::FileSize& NakInfo::getStartOfScope() { return startOfScope; }
|
||||||
|
|
||||||
cfdp::Fss& NakInfo::getEndOfScope() { return endOfScope; }
|
cfdp::FileSize& NakInfo::getEndOfScope() { return endOfScope; }
|
||||||
|
|
||||||
size_t NakInfo::getSegmentRequestsLen() const { return segmentRequestsLen; }
|
size_t NakInfo::getSegmentRequestsLen() const { return segmentRequestsLen; }
|
||||||
|
|
||||||
|
|
|
@ -3,21 +3,21 @@
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "fsfw/cfdp/Fss.h"
|
#include "fsfw/cfdp/FileSize.h"
|
||||||
|
|
||||||
class NakInfo {
|
class NakInfo {
|
||||||
public:
|
public:
|
||||||
using SegmentRequest = std::pair<cfdp::Fss, cfdp::Fss>;
|
using SegmentRequest = std::pair<cfdp::FileSize, cfdp::FileSize>;
|
||||||
|
|
||||||
NakInfo(cfdp::Fss startOfScope, cfdp::Fss endOfScope);
|
NakInfo(cfdp::FileSize startOfScope, cfdp::FileSize endOfScope);
|
||||||
|
|
||||||
void setSegmentRequests(SegmentRequest* segmentRequests, size_t* segmentRequestLen,
|
void setSegmentRequests(SegmentRequest* segmentRequests, size_t* segmentRequestLen,
|
||||||
size_t* maxSegmentRequestLen);
|
size_t* maxSegmentRequestLen);
|
||||||
|
|
||||||
size_t getSerializedSize(bool fssLarge = false);
|
size_t getSerializedSize(bool fssLarge = false);
|
||||||
|
|
||||||
cfdp::Fss& getStartOfScope();
|
cfdp::FileSize& getStartOfScope();
|
||||||
cfdp::Fss& getEndOfScope();
|
cfdp::FileSize& getEndOfScope();
|
||||||
|
|
||||||
bool hasSegmentRequests() const;
|
bool hasSegmentRequests() const;
|
||||||
bool canHoldSegmentRequests() const;
|
bool canHoldSegmentRequests() const;
|
||||||
|
@ -31,8 +31,8 @@ class NakInfo {
|
||||||
void setSegmentRequestLen(size_t readLen);
|
void setSegmentRequestLen(size_t readLen);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
cfdp::Fss startOfScope;
|
cfdp::FileSize startOfScope;
|
||||||
cfdp::Fss endOfScope;
|
cfdp::FileSize endOfScope;
|
||||||
SegmentRequest* segmentRequests = nullptr;
|
SegmentRequest* segmentRequests = nullptr;
|
||||||
size_t segmentRequestsLen = 0;
|
size_t segmentRequestsLen = 0;
|
||||||
size_t maxSegmentRequestsLen = 0;
|
size_t maxSegmentRequestsLen = 0;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "NakInfo.h"
|
#include "NakInfo.h"
|
||||||
#include "fsfw/cfdp/Fss.h"
|
#include "fsfw/cfdp/FileSize.h"
|
||||||
#include "fsfw/cfdp/definitions.h"
|
#include "fsfw/cfdp/definitions.h"
|
||||||
#include "fsfw/cfdp/pdu/FileDirectiveCreator.h"
|
#include "fsfw/cfdp/pdu/FileDirectiveCreator.h"
|
||||||
|
|
||||||
|
|
|
@ -105,8 +105,7 @@ class PduHeaderReader : public RedirectableDataPointerIF, public PduHeaderIF {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
ReturnValue_t setData(uint8_t* dataPtr, size_t maxSize, void* args) override;
|
ReturnValue_t setData(uint8_t* dataPtr, size_t maxSize, void* args) override;
|
||||||
static void assignVarLenField(cfdp::VarLenField* field, cfdp::WidthInBytes width,
|
void assignVarLenField(cfdp::VarLenField* field, cfdp::WidthInBytes width, void* sourcePtr) const;
|
||||||
void* sourcePtr);
|
|
||||||
void* sourceIdRaw = nullptr;
|
void* sourceIdRaw = nullptr;
|
||||||
void* seqNumRaw = nullptr;
|
void* seqNumRaw = nullptr;
|
||||||
void* destIdRaw = nullptr;
|
void* destIdRaw = nullptr;
|
||||||
|
|
|
@ -8,5 +8,4 @@ target_sources(
|
||||||
StringLv.cpp
|
StringLv.cpp
|
||||||
FlowLabelTlv.cpp
|
FlowLabelTlv.cpp
|
||||||
MessageToUserTlv.cpp
|
MessageToUserTlv.cpp
|
||||||
FaultHandlerOverrideTlv.cpp
|
FaultHandlerOverrideTlv.cpp)
|
||||||
ReservedMessageCreator.cpp)
|
|
||||||
|
|
|
@ -23,8 +23,6 @@ class EntityIdTlv : public TlvIF {
|
||||||
*/
|
*/
|
||||||
ReturnValue_t deSerialize(cfdp::Tlv& tlv, Endianness endianness);
|
ReturnValue_t deSerialize(cfdp::Tlv& tlv, Endianness endianness);
|
||||||
|
|
||||||
using SerializeIF::deSerialize; // we overloaded this function, so this is needed to unconfuse
|
|
||||||
// the compiler
|
|
||||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||||
Endianness streamEndianness) override;
|
Endianness streamEndianness) override;
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,6 @@ class FilestoreResponseTlv : public cfdp::FilestoreTlvBase {
|
||||||
*/
|
*/
|
||||||
ReturnValue_t deSerialize(const cfdp::Tlv& tlv, Endianness endianness);
|
ReturnValue_t deSerialize(const cfdp::Tlv& tlv, Endianness endianness);
|
||||||
|
|
||||||
using SerializeIF::deSerialize; // we overloaded this function, so this is needed to unconfuse
|
|
||||||
// the compiler
|
|
||||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||||
Endianness streamEndianness) override;
|
Endianness streamEndianness) override;
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,23 @@ cfdp::Lv::Lv(const std::vector<uint8_t>& data) : value(data.data(), data.size(),
|
||||||
|
|
||||||
cfdp::Lv::Lv() : value(static_cast<uint8_t*>(nullptr), 0, true) {}
|
cfdp::Lv::Lv() : value(static_cast<uint8_t*>(nullptr), 0, true) {}
|
||||||
|
|
||||||
|
cfdp::Lv::Lv(const Lv& other)
|
||||||
|
: value(other.value.getConstBuffer(), other.value.getSerializedSize() - 1, true) {
|
||||||
|
if (other.value.getSerializedSize() - 1 > 0) {
|
||||||
|
zeroLen = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cfdp::Lv& cfdp::Lv::operator=(const Lv& other) {
|
||||||
|
size_t otherSize = 0;
|
||||||
|
auto* otherVal = const_cast<uint8_t*>(other.getValue(&otherSize));
|
||||||
|
if (otherVal == nullptr or otherSize == 0) {
|
||||||
|
this->zeroLen = true;
|
||||||
|
}
|
||||||
|
this->value.setConstBuffer(otherVal, otherSize);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t cfdp::Lv::serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
ReturnValue_t cfdp::Lv::serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||||
Endianness streamEndianness) const {
|
Endianness streamEndianness) const {
|
||||||
if (maxSize < 1) {
|
if (maxSize < 1) {
|
||||||
|
@ -32,8 +49,10 @@ ReturnValue_t cfdp::Lv::serialize(uint8_t** buffer, size_t* size, size_t maxSize
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t cfdp::Lv::getSerializedSize() const {
|
size_t cfdp::Lv::getSerializedSize() const {
|
||||||
if (zeroLen or value.getConstBuffer() == nullptr) {
|
if (zeroLen) {
|
||||||
return 1;
|
return 1;
|
||||||
|
} else if (value.getConstBuffer() == nullptr) {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return value.getSerializedSize();
|
return value.getSerializedSize();
|
||||||
}
|
}
|
||||||
|
@ -66,34 +85,7 @@ ReturnValue_t cfdp::Lv::deSerialize(const uint8_t** buffer, size_t* size,
|
||||||
const uint8_t* cfdp::Lv::getValue(size_t* size) const {
|
const uint8_t* cfdp::Lv::getValue(size_t* size) const {
|
||||||
if (size != nullptr) {
|
if (size != nullptr) {
|
||||||
// Length without length field
|
// Length without length field
|
||||||
*size = getSerializedSize() - 1;
|
*size = value.getSerializedSize() - 1;
|
||||||
}
|
}
|
||||||
return value.getConstBuffer();
|
return value.getConstBuffer();
|
||||||
}
|
}
|
||||||
cfdp::Lv::Lv(cfdp::Lv&& other) noexcept
|
|
||||||
: value(other.value.getConstBuffer(), other.value.getSerializedSize() - 1, true) {
|
|
||||||
if (other.value.getSerializedSize() - 1 > 0) {
|
|
||||||
zeroLen = false;
|
|
||||||
}
|
|
||||||
// Leave other class in intact state.
|
|
||||||
other.zeroLen = false;
|
|
||||||
other.value = SerialBufferAdapter<uint8_t>();
|
|
||||||
}
|
|
||||||
|
|
||||||
cfdp::Lv& cfdp::Lv::operator=(cfdp::Lv&& other) noexcept {
|
|
||||||
size_t otherSize = 0;
|
|
||||||
this->zeroLen = false;
|
|
||||||
auto* otherVal = const_cast<uint8_t*>(other.getValue(&otherSize));
|
|
||||||
if (otherVal == nullptr or otherSize == 0) {
|
|
||||||
this->zeroLen = true;
|
|
||||||
}
|
|
||||||
this->value.setConstBuffer(otherVal, otherSize);
|
|
||||||
// Leave other class in intact state.
|
|
||||||
other.zeroLen = false;
|
|
||||||
other.value = SerialBufferAdapter<uint8_t>();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t cfdp::Lv::getValueLen() const { return getSerializedSize() - 1; }
|
|
||||||
|
|
||||||
bool cfdp::Lv::isEmpty() const { return zeroLen; }
|
|
||||||
|
|
|
@ -18,12 +18,8 @@ class Lv : public SerializeIF {
|
||||||
Lv(const uint8_t* value, size_t size);
|
Lv(const uint8_t* value, size_t size);
|
||||||
Lv();
|
Lv();
|
||||||
|
|
||||||
// Semantically, this class is a zero-copy helper, so the copy ctor and copy assigment do not
|
Lv(const Lv&);
|
||||||
// really make sense here.
|
Lv& operator=(const Lv&);
|
||||||
Lv(const Lv&) = delete;
|
|
||||||
Lv& operator=(const Lv&) = delete;
|
|
||||||
Lv(Lv&&) noexcept;
|
|
||||||
Lv& operator=(Lv&&) noexcept;
|
|
||||||
|
|
||||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||||
Endianness streamEndianness) const override;
|
Endianness streamEndianness) const override;
|
||||||
|
@ -40,8 +36,6 @@ class Lv : public SerializeIF {
|
||||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||||
Endianness streamEndianness) override;
|
Endianness streamEndianness) override;
|
||||||
|
|
||||||
size_t getValueLen() const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get value field and its size.
|
* Get value field and its size.
|
||||||
* @param size Optionally retrieve size. Size will be the size of the actual value field
|
* @param size Optionally retrieve size. Size will be the size of the actual value field
|
||||||
|
@ -50,8 +44,6 @@ class Lv : public SerializeIF {
|
||||||
*/
|
*/
|
||||||
const uint8_t* getValue(size_t* size) const;
|
const uint8_t* getValue(size_t* size) const;
|
||||||
|
|
||||||
bool isEmpty() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool zeroLen = true;
|
bool zeroLen = true;
|
||||||
SerialBufferAdapter<uint8_t> value;
|
SerialBufferAdapter<uint8_t> value;
|
||||||
|
|
|
@ -7,22 +7,3 @@ MessageToUserTlv::MessageToUserTlv() : Tlv() {}
|
||||||
|
|
||||||
MessageToUserTlv::MessageToUserTlv(const std::vector<uint8_t>& data)
|
MessageToUserTlv::MessageToUserTlv(const std::vector<uint8_t>& data)
|
||||||
: Tlv(cfdp::TlvType::MSG_TO_USER, data.data(), data.size()) {}
|
: Tlv(cfdp::TlvType::MSG_TO_USER, data.data(), data.size()) {}
|
||||||
|
|
||||||
MessageToUserTlv::MessageToUserTlv(const uint8_t* value, size_t size)
|
|
||||||
: Tlv(cfdp::TlvType::MSG_TO_USER, value, size) {}
|
|
||||||
|
|
||||||
bool MessageToUserTlv::isReservedCfdpMessage(uint8_t& messageType, const uint8_t** msgDataStart,
|
|
||||||
size_t& msgLen) const {
|
|
||||||
if (cfdp::Tlv::getLengthField() < 5) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (std::strncmp(reinterpret_cast<const char*>(getValue()), "cfdp", 4) == 0) {
|
|
||||||
messageType = getValue()[4];
|
|
||||||
if (msgDataStart != nullptr) {
|
|
||||||
*msgDataStart = getValue() + 5;
|
|
||||||
}
|
|
||||||
msgLen = cfdp::Tlv::getSerializedSize() - 5;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
|
@ -9,12 +9,8 @@ class MessageToUserTlv : public cfdp::Tlv {
|
||||||
public:
|
public:
|
||||||
MessageToUserTlv();
|
MessageToUserTlv();
|
||||||
MessageToUserTlv(uint8_t* value, size_t size);
|
MessageToUserTlv(uint8_t* value, size_t size);
|
||||||
MessageToUserTlv(const uint8_t* value, size_t size);
|
|
||||||
explicit MessageToUserTlv(const std::vector<uint8_t>& data);
|
explicit MessageToUserTlv(const std::vector<uint8_t>& data);
|
||||||
|
|
||||||
bool isReservedCfdpMessage(uint8_t& messageType, const uint8_t** msgDataStart,
|
|
||||||
size_t& msgLen) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
#include "ReservedMessageCreator.h"
|
|
||||||
|
|
||||||
cfdp::ReservedMessageCreator::ReservedMessageCreator(uint8_t messageType, uint8_t *msgData,
|
|
||||||
size_t msgLen)
|
|
||||||
: messageType(messageType), msgData(msgData), msgSize(msgLen) {}
|
|
||||||
|
|
||||||
ReturnValue_t cfdp::ReservedMessageCreator::serialize(
|
|
||||||
uint8_t **buffer, size_t *size, size_t maxSize,
|
|
||||||
SerializeIF::Endianness streamEndianness) const {
|
|
||||||
if (*size + getSerializedSize() > maxSize) {
|
|
||||||
return SerializeIF::BUFFER_TOO_SHORT;
|
|
||||||
}
|
|
||||||
**buffer = TlvType::MSG_TO_USER;
|
|
||||||
*buffer += 1;
|
|
||||||
*size += 1;
|
|
||||||
**buffer = getSerializedSize() - 2;
|
|
||||||
*size += 1;
|
|
||||||
*buffer += 1;
|
|
||||||
std::memcpy(*buffer, MSG_HEADER, 4);
|
|
||||||
*buffer += 4;
|
|
||||||
*size += 4;
|
|
||||||
**buffer = messageType;
|
|
||||||
*buffer += 1;
|
|
||||||
*size += 1;
|
|
||||||
std::memcpy(*buffer, msgData, msgSize);
|
|
||||||
*buffer += msgSize;
|
|
||||||
*size += msgSize;
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t cfdp::ReservedMessageCreator::getSerializedSize() const {
|
|
||||||
// 2 bytes type and length, 4 bytes CFDP, 1 byte reserved message type, message data.
|
|
||||||
return 2 + 5 + msgSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t cfdp::ReservedMessageCreator::deSerialize(const uint8_t **buffer, size_t *size,
|
|
||||||
SerializeIF::Endianness streamEndianness) {
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Tlv.h"
|
|
||||||
|
|
||||||
namespace cfdp {
|
|
||||||
|
|
||||||
class ReservedMessageCreator : public SerializeIF {
|
|
||||||
public:
|
|
||||||
static constexpr char MSG_HEADER[] = "cfdp";
|
|
||||||
|
|
||||||
ReservedMessageCreator(uint8_t messageType, uint8_t *msgData, size_t msgLen);
|
|
||||||
[[nodiscard]] ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
|
||||||
Endianness streamEndianness) const override;
|
|
||||||
[[nodiscard]] size_t getSerializedSize() const override;
|
|
||||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
|
||||||
Endianness streamEndianness) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint8_t messageType;
|
|
||||||
uint8_t *msgData;
|
|
||||||
size_t msgSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace cfdp
|
|
|
@ -7,12 +7,3 @@ cfdp::StringLv::StringLv(const char* filename, size_t len)
|
||||||
: Lv(reinterpret_cast<const uint8_t*>(filename), len) {}
|
: Lv(reinterpret_cast<const uint8_t*>(filename), len) {}
|
||||||
|
|
||||||
cfdp::StringLv::StringLv() : Lv() {}
|
cfdp::StringLv::StringLv() : Lv() {}
|
||||||
|
|
||||||
const char* cfdp::StringLv::getCString(size_t& fileSize) const {
|
|
||||||
return reinterpret_cast<const char*>(getValue(&fileSize));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string cfdp::StringLv::getString() const {
|
|
||||||
size_t fileSize;
|
|
||||||
return {getCString(fileSize), fileSize};
|
|
||||||
}
|
|
||||||
|
|
|
@ -13,8 +13,6 @@ class StringLv : public Lv {
|
||||||
explicit StringLv(const std::string& fileName);
|
explicit StringLv(const std::string& fileName);
|
||||||
explicit StringLv(const char* filename, size_t len);
|
explicit StringLv(const char* filename, size_t len);
|
||||||
|
|
||||||
const char* getCString(size_t& fileSize) const;
|
|
||||||
std::string getString() const;
|
|
||||||
// Delete the move constructor to avoid passing in a temporary
|
// Delete the move constructor to avoid passing in a temporary
|
||||||
StringLv(const std::string&&) = delete;
|
StringLv(const std::string&&) = delete;
|
||||||
};
|
};
|
||||||
|
|
|
@ -54,7 +54,6 @@ ReturnValue_t cfdp::Tlv::deSerialize(const uint8_t **buffer, size_t *size,
|
||||||
return STREAM_TOO_SHORT;
|
return STREAM_TOO_SHORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
rawData = *buffer;
|
|
||||||
uint8_t rawType = **buffer;
|
uint8_t rawType = **buffer;
|
||||||
if (not checkType(rawType)) {
|
if (not checkType(rawType)) {
|
||||||
return INVALID_TLV_TYPE;
|
return INVALID_TLV_TYPE;
|
||||||
|
@ -103,5 +102,3 @@ void cfdp::Tlv::setValue(uint8_t *value, size_t len) {
|
||||||
uint8_t cfdp::Tlv::getLengthField() const { return this->value.getSerializedSize() - 1; }
|
uint8_t cfdp::Tlv::getLengthField() const { return this->value.getSerializedSize() - 1; }
|
||||||
|
|
||||||
void cfdp::Tlv::setType(TlvType type) { this->type = type; }
|
void cfdp::Tlv::setType(TlvType type) { this->type = type; }
|
||||||
|
|
||||||
const uint8_t *cfdp::Tlv::getRawData() const { return rawData; }
|
|
||||||
|
|
|
@ -47,7 +47,6 @@ class Tlv : public TlvIF {
|
||||||
void setValue(uint8_t *value, size_t len);
|
void setValue(uint8_t *value, size_t len);
|
||||||
|
|
||||||
[[nodiscard]] const uint8_t *getValue() const;
|
[[nodiscard]] const uint8_t *getValue() const;
|
||||||
[[nodiscard]] const uint8_t *getRawData() const;
|
|
||||||
void setType(TlvType type);
|
void setType(TlvType type);
|
||||||
[[nodiscard]] TlvType getType() const override;
|
[[nodiscard]] TlvType getType() const override;
|
||||||
[[nodiscard]] uint8_t getLengthField() const override;
|
[[nodiscard]] uint8_t getLengthField() const override;
|
||||||
|
@ -56,7 +55,6 @@ class Tlv : public TlvIF {
|
||||||
bool checkType(uint8_t rawType);
|
bool checkType(uint8_t rawType);
|
||||||
|
|
||||||
bool zeroLen = true;
|
bool zeroLen = true;
|
||||||
const uint8_t *rawData = nullptr;
|
|
||||||
TlvType type = TlvType::INVALID_TLV;
|
TlvType type = TlvType::INVALID_TLV;
|
||||||
SerialBufferAdapter<uint8_t> value;
|
SerialBufferAdapter<uint8_t> value;
|
||||||
};
|
};
|
||||||
|
|
|
@ -155,8 +155,8 @@ class FixedMap : public SerializeIF {
|
||||||
|
|
||||||
uint32_t maxSize() const { return theMap.maxSize(); }
|
uint32_t maxSize() const { return theMap.maxSize(); }
|
||||||
|
|
||||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||||
Endianness streamEndianness) const override {
|
Endianness streamEndianness) const {
|
||||||
ReturnValue_t result =
|
ReturnValue_t result =
|
||||||
SerializeAdapter::serialize(&this->_size, buffer, size, maxSize, streamEndianness);
|
SerializeAdapter::serialize(&this->_size, buffer, size, maxSize, streamEndianness);
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
|
@ -170,7 +170,7 @@ class FixedMap : public SerializeIF {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t getSerializedSize() const override {
|
virtual size_t getSerializedSize() const {
|
||||||
uint32_t printSize = sizeof(_size);
|
uint32_t printSize = sizeof(_size);
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
|
|
||||||
|
@ -182,8 +182,8 @@ class FixedMap : public SerializeIF {
|
||||||
return printSize;
|
return printSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||||
Endianness streamEndianness) override {
|
Endianness streamEndianness) {
|
||||||
ReturnValue_t result =
|
ReturnValue_t result =
|
||||||
SerializeAdapter::deSerialize(&this->_size, buffer, size, streamEndianness);
|
SerializeAdapter::deSerialize(&this->_size, buffer, size, streamEndianness);
|
||||||
if (this->_size > theMap.maxSize()) {
|
if (this->_size > theMap.maxSize()) {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include "fsfw/container/SharedRingBuffer.h"
|
#include "fsfw/container/SharedRingBuffer.h"
|
||||||
|
|
||||||
#include "SharedRingBuffer.h"
|
|
||||||
#include "fsfw/ipc/MutexFactory.h"
|
#include "fsfw/ipc/MutexFactory.h"
|
||||||
#include "fsfw/ipc/MutexGuard.h"
|
#include "fsfw/ipc/MutexGuard.h"
|
||||||
|
|
||||||
|
@ -16,12 +15,7 @@ SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedRingBuffer::~SharedRingBuffer() {
|
SharedRingBuffer::~SharedRingBuffer() { MutexFactory::instance()->deleteMutex(mutex); }
|
||||||
MutexFactory::instance()->deleteMutex(mutex);
|
|
||||||
if (receiveSizesFifo != nullptr) {
|
|
||||||
delete (receiveSizesFifo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SharedRingBuffer::setToUseReceiveSizeFIFO(size_t fifoDepth) { this->fifoDepth = fifoDepth; }
|
void SharedRingBuffer::setToUseReceiveSizeFIFO(size_t fifoDepth) { this->fifoDepth = fifoDepth; }
|
||||||
|
|
||||||
|
@ -36,31 +30,18 @@ MutexIF* SharedRingBuffer::getMutexHandle() const { return mutex; }
|
||||||
|
|
||||||
ReturnValue_t SharedRingBuffer::initialize() {
|
ReturnValue_t SharedRingBuffer::initialize() {
|
||||||
if (fifoDepth > 0) {
|
if (fifoDepth > 0) {
|
||||||
receiveSizesFifo = new DynamicFIFO<size_t>(fifoDepth);
|
receiveSizesFIFO = new DynamicFIFO<size_t>(fifoDepth);
|
||||||
}
|
}
|
||||||
return SystemObject::initialize();
|
return SystemObject::initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
DynamicFIFO<size_t>* SharedRingBuffer::getReceiveSizesFifo() {
|
DynamicFIFO<size_t>* SharedRingBuffer::getReceiveSizesFIFO() {
|
||||||
if (receiveSizesFifo == nullptr) {
|
if (receiveSizesFIFO == nullptr) {
|
||||||
// Configuration error.
|
// Configuration error.
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "SharedRingBuffer::getReceiveSizesFIFO: Ring buffer"
|
sif::warning << "SharedRingBuffer::getReceiveSizesFIFO: Ring buffer"
|
||||||
<< " was not configured to have sizes FIFO, returning nullptr!" << std::endl;
|
<< " was not configured to have sizes FIFO, returning nullptr!" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return receiveSizesFifo;
|
return receiveSizesFIFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SharedRingBuffer::fifoEmpty(bool& empty, MutexIF::TimeoutType timeoutType,
|
|
||||||
uint32_t timeoutMs) {
|
|
||||||
if (receiveSizesFifo == nullptr) {
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
MutexGuard mg(mutex, timeoutType, timeoutMs);
|
|
||||||
if (mg.getLockResult() != returnvalue::OK) {
|
|
||||||
return mg.getLockResult();
|
|
||||||
}
|
|
||||||
empty = receiveSizesFifo->empty();
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
|
@ -20,7 +20,7 @@ class SharedRingBuffer : public SystemObject, public SimpleRingBuffer {
|
||||||
* This constructor allocates a new internal buffer with the supplied size.
|
* This constructor allocates a new internal buffer with the supplied size.
|
||||||
* @param size
|
* @param size
|
||||||
* @param overwriteOld
|
* @param overwriteOld
|
||||||
* If the ring buffer is overflowing at a write operation, the oldest data
|
* If the ring buffer is overflowing at a write operartion, the oldest data
|
||||||
* will be overwritten.
|
* will be overwritten.
|
||||||
*/
|
*/
|
||||||
SharedRingBuffer(object_id_t objectId, const size_t size, bool overwriteOld,
|
SharedRingBuffer(object_id_t objectId, const size_t size, bool overwriteOld,
|
||||||
|
@ -30,7 +30,7 @@ class SharedRingBuffer : public SystemObject, public SimpleRingBuffer {
|
||||||
* @param buffer
|
* @param buffer
|
||||||
* @param size
|
* @param size
|
||||||
* @param overwriteOld
|
* @param overwriteOld
|
||||||
* If the ring buffer is overflowing at a write operation, the oldest data
|
* If the ring buffer is overflowing at a write operartion, the oldest data
|
||||||
* will be overwritten.
|
* will be overwritten.
|
||||||
*/
|
*/
|
||||||
SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const size_t size, bool overwriteOld,
|
SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const size_t size, bool overwriteOld,
|
||||||
|
@ -78,15 +78,13 @@ class SharedRingBuffer : public SystemObject, public SimpleRingBuffer {
|
||||||
* Do not forget to protect access with a lock if required!
|
* Do not forget to protect access with a lock if required!
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
DynamicFIFO<size_t>* getReceiveSizesFifo();
|
DynamicFIFO<size_t>* getReceiveSizesFIFO();
|
||||||
|
|
||||||
ReturnValue_t fifoEmpty(bool& empty, MutexIF::TimeoutType timeoutType, uint32_t timeoutMs);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MutexIF* mutex = nullptr;
|
MutexIF* mutex = nullptr;
|
||||||
|
|
||||||
size_t fifoDepth = 0;
|
size_t fifoDepth = 0;
|
||||||
DynamicFIFO<size_t>* receiveSizesFifo = nullptr;
|
DynamicFIFO<size_t>* receiveSizesFIFO = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_CONTAINER_SHAREDRINGBUFFER_H_ */
|
#endif /* FSFW_CONTAINER_SHAREDRINGBUFFER_H_ */
|
||||||
|
|
|
@ -72,17 +72,18 @@ void ControllerBase::getMode(Mode_t* mode_, Submode_t* submode_) {
|
||||||
*submode_ = this->submode;
|
*submode_ = this->submode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControllerBase::announceMode(bool recursive) { triggerEvent(MODE_INFO, mode, submode); }
|
|
||||||
|
|
||||||
void ControllerBase::modeChanged(Mode_t mode_, Submode_t submode_) {}
|
|
||||||
|
|
||||||
void ControllerBase::setToExternalControl() { healthHelper.setHealth(EXTERNAL_CONTROL); }
|
void ControllerBase::setToExternalControl() { healthHelper.setHealth(EXTERNAL_CONTROL); }
|
||||||
|
|
||||||
|
void ControllerBase::announceMode(bool recursive) { triggerEvent(MODE_INFO, mode, submode); }
|
||||||
|
|
||||||
ReturnValue_t ControllerBase::performOperation(uint8_t opCode) {
|
ReturnValue_t ControllerBase::performOperation(uint8_t opCode) {
|
||||||
handleQueue();
|
handleQueue();
|
||||||
performControlOperation(opCode);
|
performControlOperation();
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ControllerBase::modeChanged(Mode_t mode_, Submode_t submode_) {}
|
||||||
|
|
||||||
ReturnValue_t ControllerBase::setHealth(HealthState health) {
|
ReturnValue_t ControllerBase::setHealth(HealthState health) {
|
||||||
switch (health) {
|
switch (health) {
|
||||||
case HEALTHY:
|
case HEALTHY:
|
||||||
|
|
|
@ -61,7 +61,7 @@ class ControllerBase : public HasModesIF,
|
||||||
/**
|
/**
|
||||||
* Periodic helper, implemented by child class.
|
* Periodic helper, implemented by child class.
|
||||||
*/
|
*/
|
||||||
virtual void performControlOperation(uint8_t opCode) = 0;
|
virtual void performControlOperation() = 0;
|
||||||
|
|
||||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||||
uint32_t *msToReachTheMode) override = 0;
|
uint32_t *msToReachTheMode) override = 0;
|
||||||
|
|
|
@ -81,7 +81,7 @@ ReturnValue_t ExtendedControllerBase::initializeAfterTaskCreation() {
|
||||||
|
|
||||||
ReturnValue_t ExtendedControllerBase::performOperation(uint8_t opCode) {
|
ReturnValue_t ExtendedControllerBase::performOperation(uint8_t opCode) {
|
||||||
handleQueue();
|
handleQueue();
|
||||||
performControlOperation(opCode);
|
performControlOperation();
|
||||||
/* We do this after performing control operation because variables will be set changed
|
/* We do this after performing control operation because variables will be set changed
|
||||||
in this function. */
|
in this function. */
|
||||||
poolManager.performHkOperation();
|
poolManager.performHkOperation();
|
||||||
|
|
|
@ -44,7 +44,7 @@ class ExtendedControllerBase : public ControllerBase,
|
||||||
/**
|
/**
|
||||||
* Periodic helper from ControllerBase, implemented by child class.
|
* Periodic helper from ControllerBase, implemented by child class.
|
||||||
*/
|
*/
|
||||||
void performControlOperation(uint8_t opCode) override = 0;
|
void performControlOperation() override = 0;
|
||||||
|
|
||||||
// Handle the four messages mentioned above
|
// Handle the four messages mentioned above
|
||||||
void handleQueue() override;
|
void handleQueue() override;
|
||||||
|
|
|
@ -6,8 +6,6 @@
|
||||||
#include "fsfw/globalfunctions/constants.h"
|
#include "fsfw/globalfunctions/constants.h"
|
||||||
#include "fsfw/globalfunctions/math/MatrixOperations.h"
|
#include "fsfw/globalfunctions/math/MatrixOperations.h"
|
||||||
#include "fsfw/globalfunctions/math/VectorOperations.h"
|
#include "fsfw/globalfunctions/math/VectorOperations.h"
|
||||||
#include "fsfw/globalfunctions/sign.h"
|
|
||||||
#include "fsfw/serviceinterface.h"
|
|
||||||
|
|
||||||
void CoordinateTransformations::positionEcfToEci(const double* ecfPosition, double* eciPosition,
|
void CoordinateTransformations::positionEcfToEci(const double* ecfPosition, double* eciPosition,
|
||||||
timeval* timeUTC) {
|
timeval* timeUTC) {
|
||||||
|
@ -99,16 +97,7 @@ void CoordinateTransformations::ecfToEci(const double* ecfCoordinates, double* e
|
||||||
|
|
||||||
double CoordinateTransformations::getJuleanCenturiesTT(timeval timeUTC) {
|
double CoordinateTransformations::getJuleanCenturiesTT(timeval timeUTC) {
|
||||||
timeval timeTT;
|
timeval timeTT;
|
||||||
ReturnValue_t result = Clock::convertUTCToTT(timeUTC, &timeTT);
|
Clock::convertUTCToTT(timeUTC, &timeTT);
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
// i think it is better to continue here than to abort
|
|
||||||
timeTT = timeUTC;
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::error << "CoordinateTransformations::Conversion from UTC to TT failed. Continuing "
|
|
||||||
"calculations with UTC."
|
|
||||||
<< std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
double jD2000TT;
|
double jD2000TT;
|
||||||
Clock::convertTimevalToJD2000(timeTT, &jD2000TT);
|
Clock::convertTimevalToJD2000(timeTT, &jD2000TT);
|
||||||
|
|
||||||
|
@ -218,61 +207,3 @@ void CoordinateTransformations::getTransMatrixECITOECF(timeval timeUTC, double T
|
||||||
|
|
||||||
MatrixOperations<double>::multiply(mTheta[0], Ttemp[0], Tfi[0], 3, 3, 3);
|
MatrixOperations<double>::multiply(mTheta[0], Ttemp[0], Tfi[0], 3, 3, 3);
|
||||||
};
|
};
|
||||||
|
|
||||||
void CoordinateTransformations::cartesianFromLatLongAlt(const double lat, const double longi,
|
|
||||||
const double alt, double* cartesianOutput) {
|
|
||||||
/* @brief: cartesianFromLatLongAlt() - calculates cartesian coordinates in ECEF from latitude,
|
|
||||||
* longitude and altitude
|
|
||||||
* @param: lat geodetic latitude [rad]
|
|
||||||
* longi longitude [rad]
|
|
||||||
* alt altitude [m]
|
|
||||||
* cartesianOutput Cartesian Coordinates in ECEF (3x1)
|
|
||||||
* @source: Fundamentals of Spacecraft Attitude Determination and Control, P.34ff
|
|
||||||
* Landis Markley and John L. Crassidis*/
|
|
||||||
double radiusPolar = 6356752.314;
|
|
||||||
double radiusEqua = 6378137;
|
|
||||||
|
|
||||||
double eccentricity = sqrt(1 - pow(radiusPolar, 2) / pow(radiusEqua, 2));
|
|
||||||
double auxRadius = radiusEqua / sqrt(1 - pow(eccentricity, 2) * pow(sin(lat), 2));
|
|
||||||
|
|
||||||
cartesianOutput[0] = (auxRadius + alt) * cos(lat) * cos(longi);
|
|
||||||
cartesianOutput[1] = (auxRadius + alt) * cos(lat) * sin(longi);
|
|
||||||
cartesianOutput[2] = ((1 - pow(eccentricity, 2)) * auxRadius + alt) * sin(lat);
|
|
||||||
};
|
|
||||||
|
|
||||||
void CoordinateTransformations::latLongAltFromCartesian(const double* vector, double& latitude,
|
|
||||||
double& longitude, double& altitude) {
|
|
||||||
/* @brief: latLongAltFromCartesian() - calculates latitude, longitude and altitude from
|
|
||||||
* cartesian coordinates in ECEF
|
|
||||||
* @param: x x-value of position vector [m]
|
|
||||||
* y y-value of position vector [m]
|
|
||||||
* z z-value of position vector [m]
|
|
||||||
* latitude geodetic latitude [rad]
|
|
||||||
* longitude longitude [rad]
|
|
||||||
* altitude altitude [m]
|
|
||||||
* @source: Fundamentals of Spacecraft Attitude Determination and Control, P.35 f
|
|
||||||
* Landis Markley and John L. Crassidis*/
|
|
||||||
// From World Geodetic System the Earth Radii
|
|
||||||
double a = 6378137.0; // semimajor axis [m]
|
|
||||||
double b = 6356752.3142; // semiminor axis [m]
|
|
||||||
|
|
||||||
// Calculation
|
|
||||||
double e2 = 1 - pow(b, 2) / pow(a, 2);
|
|
||||||
double epsilon2 = pow(a, 2) / pow(b, 2) - 1;
|
|
||||||
double rho = sqrt(pow(vector[0], 2) + pow(vector[1], 2));
|
|
||||||
double p = std::abs(vector[2]) / epsilon2;
|
|
||||||
double s = pow(rho, 2) / (e2 * epsilon2);
|
|
||||||
double q = pow(p, 2) - pow(b, 2) + s;
|
|
||||||
double u = p / sqrt(q);
|
|
||||||
double v = pow(b, 2) * pow(u, 2) / q;
|
|
||||||
double P = 27 * v * s / q;
|
|
||||||
double Q = pow(sqrt(P + 1) + sqrt(P), 2. / 3.);
|
|
||||||
double t = (1 + Q + 1 / Q) / 6;
|
|
||||||
double c = sqrt(pow(u, 2) - 1 + 2 * t);
|
|
||||||
double w = (c - u) / 2;
|
|
||||||
double d = sign(vector[2]) * sqrt(q) * (w + sqrt(sqrt(pow(t, 2) + v) - u * w - t / 2 - 1. / 4.));
|
|
||||||
double N = a * sqrt(1 + epsilon2 * pow(d, 2) / pow(b, 2));
|
|
||||||
latitude = asin((epsilon2 + 1) * d / N);
|
|
||||||
altitude = rho * cos(latitude) + vector[2] * sin(latitude) - pow(a, 2) / N;
|
|
||||||
longitude = atan2(vector[1], vector[0]);
|
|
||||||
}
|
|
||||||
|
|
|
@ -23,12 +23,6 @@ class CoordinateTransformations {
|
||||||
|
|
||||||
static void getEarthRotationMatrix(timeval timeUTC, double matrix[][3]);
|
static void getEarthRotationMatrix(timeval timeUTC, double matrix[][3]);
|
||||||
|
|
||||||
static void cartesianFromLatLongAlt(const double lat, const double longi, const double alt,
|
|
||||||
double* cartesianOutput);
|
|
||||||
|
|
||||||
static void latLongAltFromCartesian(const double* vector, double& latitude, double& longitude,
|
|
||||||
double& altitude);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CoordinateTransformations();
|
CoordinateTransformations();
|
||||||
static void ecfToEci(const double* ecfCoordinates, double* eciCoordinates,
|
static void ecfToEci(const double* ecfCoordinates, double* eciCoordinates,
|
||||||
|
|
|
@ -166,9 +166,9 @@ ReturnValue_t Sgp4Propagator::propagate(double* position, double* velocity, time
|
||||||
timeval timeSinceEpoch = time - epoch;
|
timeval timeSinceEpoch = time - epoch;
|
||||||
double minutesSinceEpoch = timeSinceEpoch.tv_sec / 60. + timeSinceEpoch.tv_usec / 60000000.;
|
double minutesSinceEpoch = timeSinceEpoch.tv_sec / 60. + timeSinceEpoch.tv_usec / 60000000.;
|
||||||
|
|
||||||
double daysSinceEpoch = minutesSinceEpoch / 60 / 24;
|
double yearsSinceEpoch = minutesSinceEpoch / 60 / 24 / 365;
|
||||||
|
|
||||||
if ((daysSinceEpoch > 7) || (daysSinceEpoch < -7)) {
|
if ((yearsSinceEpoch > 1) || (yearsSinceEpoch < -1)) {
|
||||||
return TLE_TOO_OLD;
|
return TLE_TOO_OLD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,8 +64,8 @@ class PoolDataSetBase : public PoolDataSetIF, public SerializeIF {
|
||||||
* - @c SET_WAS_ALREADY_READ if read() is called twice without calling
|
* - @c SET_WAS_ALREADY_READ if read() is called twice without calling
|
||||||
* commit() in between
|
* commit() in between
|
||||||
*/
|
*/
|
||||||
ReturnValue_t read(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
virtual ReturnValue_t read(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||||
uint32_t lockTimeout = 20) override;
|
uint32_t lockTimeout = 20) override;
|
||||||
/**
|
/**
|
||||||
* @brief The commit call initializes writing back the registered variables.
|
* @brief The commit call initializes writing back the registered variables.
|
||||||
* @details
|
* @details
|
||||||
|
@ -84,15 +84,15 @@ class PoolDataSetBase : public PoolDataSetIF, public SerializeIF {
|
||||||
* - @c COMMITING_WITHOUT_READING if set was not read yet and
|
* - @c COMMITING_WITHOUT_READING if set was not read yet and
|
||||||
* contains non write-only variables
|
* contains non write-only variables
|
||||||
*/
|
*/
|
||||||
ReturnValue_t commit(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
virtual ReturnValue_t commit(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||||
uint32_t lockTimeout = 20) override;
|
uint32_t lockTimeout = 20) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register the passed pool variable instance into the data set.
|
* Register the passed pool variable instance into the data set.
|
||||||
* @param variable
|
* @param variable
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
ReturnValue_t registerVariable(PoolVariableIF* variable) override;
|
virtual ReturnValue_t registerVariable(PoolVariableIF* variable) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the means to lock the underlying data structure to ensure
|
* Provides the means to lock the underlying data structure to ensure
|
||||||
|
|
|
@ -349,6 +349,7 @@ ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(subdp::ParamsBase
|
||||||
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, params.sid);
|
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, params.sid);
|
||||||
if (dataSet != nullptr) {
|
if (dataSet != nullptr) {
|
||||||
LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, params.enableReporting);
|
LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, params.enableReporting);
|
||||||
|
LocalPoolDataSetAttorney::setDiagnostic(*dataSet, params.isDiagnostics());
|
||||||
LocalPoolDataSetAttorney::initializePeriodicHelper(*dataSet, params.collectionInterval,
|
LocalPoolDataSetAttorney::initializePeriodicHelper(*dataSet, params.collectionInterval,
|
||||||
owner->getPeriodicOperationFrequency());
|
owner->getPeriodicOperationFrequency());
|
||||||
}
|
}
|
||||||
|
@ -380,6 +381,7 @@ ReturnValue_t LocalDataPoolManager::subscribeForUpdatePacket(subdp::ParamsBase&
|
||||||
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, params.sid);
|
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, params.sid);
|
||||||
if (dataSet != nullptr) {
|
if (dataSet != nullptr) {
|
||||||
LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, true);
|
LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, true);
|
||||||
|
LocalPoolDataSetAttorney::setDiagnostic(*dataSet, params.isDiagnostics());
|
||||||
}
|
}
|
||||||
|
|
||||||
hkReceivers.push_back(hkReceiver);
|
hkReceivers.push_back(hkReceiver);
|
||||||
|
@ -463,37 +465,70 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(CommandMessage* me
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
switch (command) {
|
switch (command) {
|
||||||
// Houskeeping interface handling.
|
// Houskeeping interface handling.
|
||||||
|
case (HousekeepingMessage::ENABLE_PERIODIC_DIAGNOSTICS_GENERATION): {
|
||||||
|
result = togglePeriodicGeneration(sid, true, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case (HousekeepingMessage::DISABLE_PERIODIC_DIAGNOSTICS_GENERATION): {
|
||||||
|
result = togglePeriodicGeneration(sid, false, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case (HousekeepingMessage::ENABLE_PERIODIC_HK_REPORT_GENERATION): {
|
case (HousekeepingMessage::ENABLE_PERIODIC_HK_REPORT_GENERATION): {
|
||||||
result = togglePeriodicGeneration(sid, true);
|
result = togglePeriodicGeneration(sid, true, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case (HousekeepingMessage::DISABLE_PERIODIC_HK_REPORT_GENERATION): {
|
case (HousekeepingMessage::DISABLE_PERIODIC_HK_REPORT_GENERATION): {
|
||||||
result = togglePeriodicGeneration(sid, false);
|
result = togglePeriodicGeneration(sid, false, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case (HousekeepingMessage::REPORT_HK_REPORT_STRUCTURES): {
|
case (HousekeepingMessage::REPORT_DIAGNOSTICS_REPORT_STRUCTURES): {
|
||||||
result = generateSetStructurePacket(sid);
|
result = generateSetStructurePacket(sid, true);
|
||||||
if (result == returnvalue::OK) {
|
if (result == returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case (HousekeepingMessage::REPORT_HK_REPORT_STRUCTURES): {
|
||||||
|
result = generateSetStructurePacket(sid, false);
|
||||||
|
if (result == returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (HousekeepingMessage::MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL):
|
||||||
case (HousekeepingMessage::MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL): {
|
case (HousekeepingMessage::MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL): {
|
||||||
float newCollIntvl = 0;
|
float newCollIntvl = 0;
|
||||||
HousekeepingMessage::getCollectionIntervalModificationCommand(message, &newCollIntvl);
|
HousekeepingMessage::getCollectionIntervalModificationCommand(message, &newCollIntvl);
|
||||||
result = changeCollectionInterval(sid, newCollIntvl);
|
if (command == HousekeepingMessage::MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL) {
|
||||||
|
result = changeCollectionInterval(sid, newCollIntvl);
|
||||||
|
} else {
|
||||||
|
result = changeCollectionInterval(sid, newCollIntvl);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case (HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT): {
|
case (HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT):
|
||||||
|
case (HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT): {
|
||||||
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
||||||
if (dataSet == nullptr) {
|
if (dataSet == nullptr) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "handleHousekeepingMessage",
|
printWarningOrError(sif::OutputTypes::OUT_WARNING, "handleHousekeepingMessage",
|
||||||
DATASET_NOT_FOUND);
|
DATASET_NOT_FOUND);
|
||||||
return DATASET_NOT_FOUND;
|
return DATASET_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
if (command == HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT and
|
||||||
|
LocalPoolDataSetAttorney::isDiagnostics(*dataSet)) {
|
||||||
|
result = WRONG_HK_PACKET_TYPE;
|
||||||
|
break;
|
||||||
|
} else if (command == HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT and
|
||||||
|
not LocalPoolDataSetAttorney::isDiagnostics(*dataSet)) {
|
||||||
|
result = WRONG_HK_PACKET_TYPE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
return generateHousekeepingPacket(HousekeepingMessage::getSid(message), dataSet, true);
|
return generateHousekeepingPacket(HousekeepingMessage::getSid(message), dataSet, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -583,7 +618,11 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid,
|
||||||
|
|
||||||
/* Now we set a HK message and send it the HK packet destination. */
|
/* Now we set a HK message and send it the HK packet destination. */
|
||||||
CommandMessage hkMessage;
|
CommandMessage hkMessage;
|
||||||
HousekeepingMessage::setHkReportReply(&hkMessage, sid, storeId);
|
if (LocalPoolDataSetAttorney::isDiagnostics(*dataSet)) {
|
||||||
|
HousekeepingMessage::setHkDiagnosticsReply(&hkMessage, sid, storeId);
|
||||||
|
} else {
|
||||||
|
HousekeepingMessage::setHkReportReply(&hkMessage, sid, storeId);
|
||||||
|
}
|
||||||
|
|
||||||
if (hkQueue == nullptr) {
|
if (hkQueue == nullptr) {
|
||||||
/* Error, no queue available to send packet with. */
|
/* Error, no queue available to send packet with. */
|
||||||
|
@ -658,7 +697,8 @@ void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver& receiver) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::togglePeriodicGeneration(sid_t sid, bool enable) {
|
ReturnValue_t LocalDataPoolManager::togglePeriodicGeneration(sid_t sid, bool enable,
|
||||||
|
bool isDiagnostics) {
|
||||||
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
||||||
if (dataSet == nullptr) {
|
if (dataSet == nullptr) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "togglePeriodicGeneration",
|
printWarningOrError(sif::OutputTypes::OUT_WARNING, "togglePeriodicGeneration",
|
||||||
|
@ -666,6 +706,11 @@ ReturnValue_t LocalDataPoolManager::togglePeriodicGeneration(sid_t sid, bool ena
|
||||||
return DATASET_NOT_FOUND;
|
return DATASET_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((LocalPoolDataSetAttorney::isDiagnostics(*dataSet) and not isDiagnostics) or
|
||||||
|
(not LocalPoolDataSetAttorney::isDiagnostics(*dataSet) and isDiagnostics)) {
|
||||||
|
return WRONG_HK_PACKET_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
if ((LocalPoolDataSetAttorney::getReportingEnabled(*dataSet) and enable) or
|
if ((LocalPoolDataSetAttorney::getReportingEnabled(*dataSet) and enable) or
|
||||||
(not LocalPoolDataSetAttorney::getReportingEnabled(*dataSet) and not enable)) {
|
(not LocalPoolDataSetAttorney::getReportingEnabled(*dataSet) and not enable)) {
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
|
@ -696,7 +741,7 @@ ReturnValue_t LocalDataPoolManager::changeCollectionInterval(sid_t sid,
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid) {
|
ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, bool isDiagnostics) {
|
||||||
/* Get and check dataset first. */
|
/* Get and check dataset first. */
|
||||||
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
||||||
if (dataSet == nullptr) {
|
if (dataSet == nullptr) {
|
||||||
|
@ -705,6 +750,11 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid) {
|
||||||
return DATASET_NOT_FOUND;
|
return DATASET_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool targetIsDiagnostics = LocalPoolDataSetAttorney::isDiagnostics(*dataSet);
|
||||||
|
if ((targetIsDiagnostics and not isDiagnostics) or (not targetIsDiagnostics and isDiagnostics)) {
|
||||||
|
return WRONG_HK_PACKET_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
bool valid = dataSet->isValid();
|
bool valid = dataSet->isValid();
|
||||||
bool reportingEnabled = LocalPoolDataSetAttorney::getReportingEnabled(*dataSet);
|
bool reportingEnabled = LocalPoolDataSetAttorney::getReportingEnabled(*dataSet);
|
||||||
float collectionInterval =
|
float collectionInterval =
|
||||||
|
@ -736,7 +786,11 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid) {
|
||||||
|
|
||||||
// Send structure reporting reply.
|
// Send structure reporting reply.
|
||||||
CommandMessage reply;
|
CommandMessage reply;
|
||||||
HousekeepingMessage::setHkStuctureReportReply(&reply, sid, storeId);
|
if (isDiagnostics) {
|
||||||
|
HousekeepingMessage::setDiagnosticsStuctureReportReply(&reply, sid, storeId);
|
||||||
|
} else {
|
||||||
|
HousekeepingMessage::setHkStuctureReportReply(&reply, sid, storeId);
|
||||||
|
}
|
||||||
|
|
||||||
result = hkQueue->reply(&reply);
|
result = hkQueue->reply(&reply);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
|
|
|
@ -337,8 +337,8 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
||||||
size_t* serializedSize);
|
size_t* serializedSize);
|
||||||
|
|
||||||
void performPeriodicHkGeneration(HkReceiver& hkReceiver);
|
void performPeriodicHkGeneration(HkReceiver& hkReceiver);
|
||||||
ReturnValue_t togglePeriodicGeneration(sid_t sid, bool enable);
|
ReturnValue_t togglePeriodicGeneration(sid_t sid, bool enable, bool isDiagnostics);
|
||||||
ReturnValue_t generateSetStructurePacket(sid_t sid);
|
ReturnValue_t generateSetStructurePacket(sid_t sid, bool isDiagnostics);
|
||||||
|
|
||||||
void handleHkUpdateResetListInsertion(DataType dataType, DataId dataId);
|
void handleHkUpdateResetListInsertion(DataType dataType, DataId dataId);
|
||||||
void handleChangeResetLogic(DataType type, DataId dataId, MarkChangedIF* toReset);
|
void handleChangeResetLogic(DataType type, DataId dataId, MarkChangedIF* toReset);
|
||||||
|
|
|
@ -239,6 +239,10 @@ ReturnValue_t LocalPoolDataSetBase::serialize(uint8_t **buffer, size_t *size, si
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LocalPoolDataSetBase::setDiagnostic(bool isDiagnostics) { this->diagnostic = isDiagnostics; }
|
||||||
|
|
||||||
|
bool LocalPoolDataSetBase::isDiagnostics() const { return diagnostic; }
|
||||||
|
|
||||||
void LocalPoolDataSetBase::setReportingEnabled(bool reportingEnabled) {
|
void LocalPoolDataSetBase::setReportingEnabled(bool reportingEnabled) {
|
||||||
this->reportingEnabled = reportingEnabled;
|
this->reportingEnabled = reportingEnabled;
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,6 +182,10 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
|
||||||
//! This mutex is used if the data is created by one object only.
|
//! This mutex is used if the data is created by one object only.
|
||||||
MutexIF* mutexIfSingleDataCreator = nullptr;
|
MutexIF* mutexIfSingleDataCreator = nullptr;
|
||||||
|
|
||||||
|
bool diagnostic = false;
|
||||||
|
void setDiagnostic(bool diagnostics);
|
||||||
|
bool isDiagnostics() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used for periodic generation.
|
* Used for periodic generation.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -87,9 +87,9 @@ class LocalPoolVariable : public LocalPoolObjectBase {
|
||||||
|
|
||||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||||
SerializeIF::Endianness streamEndianness) const override;
|
SerializeIF::Endianness streamEndianness) const override;
|
||||||
size_t getSerializedSize() const override;
|
virtual size_t getSerializedSize() const override;
|
||||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||||
SerializeIF::Endianness streamEndianness) override;
|
SerializeIF::Endianness streamEndianness) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This is a call to read the array's values
|
* @brief This is a call to read the array's values
|
||||||
|
|
|
@ -98,11 +98,11 @@ class LocalPoolVector : public LocalPoolObjectBase {
|
||||||
T& operator[](size_t i);
|
T& operator[](size_t i);
|
||||||
const T& operator[](size_t i) const;
|
const T& operator[](size_t i) const;
|
||||||
|
|
||||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, const size_t maxSize,
|
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, const size_t maxSize,
|
||||||
SerializeIF::Endianness streamEndiannes) const override;
|
SerializeIF::Endianness streamEndiannes) const override;
|
||||||
size_t getSerializedSize() const override;
|
virtual size_t getSerializedSize() const override;
|
||||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||||
SerializeIF::Endianness streamEndianness) override;
|
SerializeIF::Endianness streamEndianness) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This is a call to read the array's values
|
* @brief This is a call to read the array's values
|
||||||
|
|
|
@ -98,6 +98,11 @@ class ProvidesDataPoolSubscriptionIF {
|
||||||
virtual ReturnValue_t subscribeForRegularUpdatePacket(subdp::RegularHkUpdateParams params) = 0;
|
virtual ReturnValue_t subscribeForRegularUpdatePacket(subdp::RegularHkUpdateParams params) = 0;
|
||||||
virtual ReturnValue_t subscribeForDiagUpdatePacket(subdp::DiagnosticsHkUpdateParams params) = 0;
|
virtual ReturnValue_t subscribeForDiagUpdatePacket(subdp::DiagnosticsHkUpdateParams params) = 0;
|
||||||
|
|
||||||
|
// virtual ReturnValue_t
|
||||||
|
// subscribeForUpdatePacket(sid_t sid, bool reportingEnabled, bool isDiagnostics) {
|
||||||
|
// return subscribeForUpdatePacket(sid, reportingEnabled, isDiagnostics, objects::NO_OBJECT);
|
||||||
|
// }
|
||||||
|
|
||||||
[[deprecated(
|
[[deprecated(
|
||||||
"Please use the new API which takes all arguments as one wrapper "
|
"Please use the new API which takes all arguments as one wrapper "
|
||||||
"struct")]] virtual ReturnValue_t
|
"struct")]] virtual ReturnValue_t
|
||||||
|
|
|
@ -5,6 +5,12 @@
|
||||||
|
|
||||||
class LocalPoolDataSetAttorney {
|
class LocalPoolDataSetAttorney {
|
||||||
private:
|
private:
|
||||||
|
static void setDiagnostic(LocalPoolDataSetBase& set, bool diagnostics) {
|
||||||
|
set.setDiagnostic(diagnostics);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isDiagnostics(LocalPoolDataSetBase& set) { return set.isDiagnostics(); }
|
||||||
|
|
||||||
static void initializePeriodicHelper(LocalPoolDataSetBase& set, float collectionInterval,
|
static void initializePeriodicHelper(LocalPoolDataSetBase& set, float collectionInterval,
|
||||||
uint32_t minimumPeriodicIntervalMs) {
|
uint32_t minimumPeriodicIntervalMs) {
|
||||||
set.initializePeriodicHelper(collectionInterval, minimumPeriodicIntervalMs);
|
set.initializePeriodicHelper(collectionInterval, minimumPeriodicIntervalMs);
|
||||||
|
|
|
@ -7,5 +7,4 @@ target_sources(
|
||||||
DeviceHandlerFailureIsolation.cpp
|
DeviceHandlerFailureIsolation.cpp
|
||||||
DeviceHandlerMessage.cpp
|
DeviceHandlerMessage.cpp
|
||||||
DeviceTmReportingWrapper.cpp
|
DeviceTmReportingWrapper.cpp
|
||||||
FreshDeviceHandlerBase.cpp
|
|
||||||
HealthDevice.cpp)
|
HealthDevice.cpp)
|
||||||
|
|
|
@ -26,11 +26,6 @@ ReturnValue_t DeviceHandlerFailureIsolation::eventReceived(EventMessage* event)
|
||||||
if (isFdirInActionOrAreWeFaulty(event)) {
|
if (isFdirInActionOrAreWeFaulty(event)) {
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
// As mentioned in the function documentation, no FDIR reaction are performed when the device
|
|
||||||
// is in external control.
|
|
||||||
if (owner->getHealth() == HasHealthIF::EXTERNAL_CONTROL) {
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
ReturnValue_t result = returnvalue::FAILED;
|
ReturnValue_t result = returnvalue::FAILED;
|
||||||
switch (event->getEvent()) {
|
switch (event->getEvent()) {
|
||||||
case HasModesIF::MODE_TRANSITION_FAILED:
|
case HasModesIF::MODE_TRANSITION_FAILED:
|
||||||
|
@ -191,6 +186,15 @@ void DeviceHandlerFailureIsolation::setFdirState(FDIRState state) {
|
||||||
fdirState = state;
|
fdirState = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeviceHandlerFailureIsolation::triggerEvent(Event event, uint32_t parameter1,
|
||||||
|
uint32_t parameter2) {
|
||||||
|
// Do not throw error events if fdirState != none.
|
||||||
|
// This will still forward MODE and HEALTH INFO events in any case.
|
||||||
|
if (fdirState == NONE || event::getSeverity(event) == severity::INFO) {
|
||||||
|
FailureIsolationBase::triggerEvent(event, parameter1, parameter2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool DeviceHandlerFailureIsolation::isFdirActionInProgress() { return (fdirState != NONE); }
|
bool DeviceHandlerFailureIsolation::isFdirActionInProgress() { return (fdirState != NONE); }
|
||||||
|
|
||||||
void DeviceHandlerFailureIsolation::startRecovery(Event reason) {
|
void DeviceHandlerFailureIsolation::startRecovery(Event reason) {
|
||||||
|
|
|
@ -17,6 +17,7 @@ class DeviceHandlerFailureIsolation : public FailureIsolationBase {
|
||||||
uint8_t eventQueueDepth = 10);
|
uint8_t eventQueueDepth = 10);
|
||||||
~DeviceHandlerFailureIsolation();
|
~DeviceHandlerFailureIsolation();
|
||||||
ReturnValue_t initialize();
|
ReturnValue_t initialize();
|
||||||
|
void triggerEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0);
|
||||||
bool isFdirActionInProgress();
|
bool isFdirActionInProgress();
|
||||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||||
ParameterWrapper* parameterWrapper,
|
ParameterWrapper* parameterWrapper,
|
||||||
|
@ -40,19 +41,6 @@ class DeviceHandlerFailureIsolation : public FailureIsolationBase {
|
||||||
static const uint32_t DEFAULT_MAX_MISSED_REPLY_COUNT = 5;
|
static const uint32_t DEFAULT_MAX_MISSED_REPLY_COUNT = 5;
|
||||||
static const uint32_t DEFAULT_MISSED_REPLY_TIME_MS = 10000;
|
static const uint32_t DEFAULT_MISSED_REPLY_TIME_MS = 10000;
|
||||||
|
|
||||||
/**
|
|
||||||
* This is the default implementation of the eventReceived function.
|
|
||||||
*
|
|
||||||
* It will perform recoveries or failures on a pre-defined set of events. If the user wants
|
|
||||||
* to add handling for custom events, this function should be overriden.
|
|
||||||
*
|
|
||||||
* It should be noted that the default implementation will not perform FDIR reactions if the
|
|
||||||
* handler is faulty or in external control by default. If the user commands the device
|
|
||||||
* manually, this might be related to debugging to testing the device in a low-level way. FDIR
|
|
||||||
* reactions might get in the way of this process by restarting the device or putting it in
|
|
||||||
* the faulty state. If the user still requires FDIR handling in the EXTERNAL_CONTROL case,
|
|
||||||
* this function should be overriden.
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t eventReceived(EventMessage* event);
|
virtual ReturnValue_t eventReceived(EventMessage* event);
|
||||||
virtual void eventConfirmed(EventMessage* event);
|
virtual void eventConfirmed(EventMessage* event);
|
||||||
void wasParentsFault(EventMessage* event);
|
void wasParentsFault(EventMessage* event);
|
||||||
|
|
|
@ -85,7 +85,6 @@ class DeviceHandlerIF {
|
||||||
static const ReturnValue_t NO_REPLY_EXPECTED = MAKE_RETURN_CODE(0xA8);
|
static const ReturnValue_t NO_REPLY_EXPECTED = MAKE_RETURN_CODE(0xA8);
|
||||||
static const ReturnValue_t NON_OP_TEMPERATURE = MAKE_RETURN_CODE(0xA9);
|
static const ReturnValue_t NON_OP_TEMPERATURE = MAKE_RETURN_CODE(0xA9);
|
||||||
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xAA);
|
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xAA);
|
||||||
static const ReturnValue_t NON_OP_STATE_OF_CHARGE = MAKE_RETURN_CODE(0xAB);
|
|
||||||
|
|
||||||
// Standard codes used in scanForReply
|
// Standard codes used in scanForReply
|
||||||
static const ReturnValue_t CHECKSUM_ERROR = MAKE_RETURN_CODE(0xB0);
|
static const ReturnValue_t CHECKSUM_ERROR = MAKE_RETURN_CODE(0xB0);
|
||||||
|
|
|
@ -1,203 +0,0 @@
|
||||||
#include "FreshDeviceHandlerBase.h"
|
|
||||||
|
|
||||||
#include "fsfw/devicehandlers/DeviceHandlerFailureIsolation.h"
|
|
||||||
#include "fsfw/ipc/QueueFactory.h"
|
|
||||||
#include "fsfw/subsystem/helper.h"
|
|
||||||
|
|
||||||
FreshDeviceHandlerBase::FreshDeviceHandlerBase(DhbConfig config)
|
|
||||||
: SystemObject(config.objectId),
|
|
||||||
actionHelper(this, nullptr),
|
|
||||||
modeHelper(this),
|
|
||||||
healthHelper(this, getObjectId()),
|
|
||||||
paramHelper(this),
|
|
||||||
poolManager(this, nullptr),
|
|
||||||
fdirInstance(config.fdirInstance),
|
|
||||||
defaultFdirParent(config.defaultFdirParent) {
|
|
||||||
auto mqArgs = MqArgs(config.objectId, static_cast<void*>(this));
|
|
||||||
messageQueue = QueueFactory::instance()->createMessageQueue(
|
|
||||||
config.msgQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
|
||||||
FreshDeviceHandlerBase::~FreshDeviceHandlerBase() {
|
|
||||||
QueueFactory::instance()->deleteMessageQueue(messageQueue);
|
|
||||||
if (not hasCustomFdir) {
|
|
||||||
delete fdirInstance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] object_id_t FreshDeviceHandlerBase::getObjectId() const {
|
|
||||||
return SystemObject::getObjectId();
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t FreshDeviceHandlerBase::performOperation(uint8_t opCode) {
|
|
||||||
performDeviceOperationPreQueueHandling(opCode);
|
|
||||||
handleQueue();
|
|
||||||
fdirInstance->checkForFailures();
|
|
||||||
performDeviceOperation(opCode);
|
|
||||||
poolManager.performHkOperation();
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t FreshDeviceHandlerBase::performDeviceOperationPreQueueHandling(uint8_t opCode) {
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FreshDeviceHandlerBase::startTransition(Mode_t mode_, Submode_t submode_) {
|
|
||||||
triggerEvent(CHANGING_MODE, mode_, submode_);
|
|
||||||
// Complete mode transition immediately by default.
|
|
||||||
setMode(mode_, submode_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FreshDeviceHandlerBase::setMode(Mode_t newMode, Submode_t newSubmode) {
|
|
||||||
mode = newMode;
|
|
||||||
submode = newSubmode;
|
|
||||||
modeHelper.modeChanged(mode, submode);
|
|
||||||
modeChanged(mode, submode);
|
|
||||||
announceMode(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FreshDeviceHandlerBase::setMode(Mode_t newMode) { setMode(newMode, submode); }
|
|
||||||
|
|
||||||
void FreshDeviceHandlerBase::getMode(Mode_t* mode_, Submode_t* submode_) {
|
|
||||||
*mode_ = this->mode;
|
|
||||||
*submode_ = this->submode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FreshDeviceHandlerBase::announceMode(bool recursive) {
|
|
||||||
triggerEvent(MODE_INFO, mode, submode);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FreshDeviceHandlerBase::modeChanged(Mode_t mode_, Submode_t submode_) {}
|
|
||||||
|
|
||||||
[[nodiscard]] MessageQueueId_t FreshDeviceHandlerBase::getCommandQueue() const {
|
|
||||||
return messageQueue->getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t FreshDeviceHandlerBase::handleQueue() {
|
|
||||||
CommandMessage command;
|
|
||||||
ReturnValue_t result;
|
|
||||||
for (result = messageQueue->receiveMessage(&command); result == returnvalue::OK;
|
|
||||||
result = messageQueue->receiveMessage(&command)) {
|
|
||||||
result = actionHelper.handleActionMessage(&command);
|
|
||||||
if (result == returnvalue::OK) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = modeHelper.handleModeCommand(&command);
|
|
||||||
if (result == returnvalue::OK) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = healthHelper.handleHealthCommand(&command);
|
|
||||||
if (result == returnvalue::OK) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = paramHelper.handleParameterMessage(&command);
|
|
||||||
if (result == returnvalue::OK) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = poolManager.handleHousekeepingMessage(&command);
|
|
||||||
if (result == returnvalue::OK) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = handleCommandMessage(&command);
|
|
||||||
if (result == returnvalue::OK) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
command.setToUnknownCommand();
|
|
||||||
messageQueue->reply(&command);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
HasHealthIF::HealthState FreshDeviceHandlerBase::getHealth() { return healthHelper.getHealth(); }
|
|
||||||
|
|
||||||
const HasHealthIF* FreshDeviceHandlerBase::getOptHealthIF() const { return this; }
|
|
||||||
|
|
||||||
const HasModesIF& FreshDeviceHandlerBase::getModeIF() const { return *this; }
|
|
||||||
|
|
||||||
ModeTreeChildIF& FreshDeviceHandlerBase::getModeTreeChildIF() { return *this; }
|
|
||||||
|
|
||||||
ReturnValue_t FreshDeviceHandlerBase::connectModeTreeParent(HasModeTreeChildrenIF& parent) {
|
|
||||||
return modetree::connectModeTreeParent(parent, *this, &healthHelper, modeHelper);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Executable Overrides.
|
|
||||||
void FreshDeviceHandlerBase::setTaskIF(PeriodicTaskIF* task_) { executingTask = task_; }
|
|
||||||
|
|
||||||
// Pool Manager overrides.
|
|
||||||
LocalDataPoolManager* FreshDeviceHandlerBase::getHkManagerHandle() { return &poolManager; }
|
|
||||||
|
|
||||||
[[nodiscard]] uint32_t FreshDeviceHandlerBase::getPeriodicOperationFrequency() const {
|
|
||||||
return this->executingTask->getPeriodMs();
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t FreshDeviceHandlerBase::initializeAfterTaskCreation() {
|
|
||||||
return poolManager.initializeAfterTaskCreation();
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t FreshDeviceHandlerBase::setHealth(HasHealthIF::HealthState health) {
|
|
||||||
// Assembly should handle commanding to OFF.
|
|
||||||
healthHelper.setHealth(health);
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FreshDeviceHandlerBase::triggerEvent(Event event, uint32_t parameter1, uint32_t parameter2) {
|
|
||||||
fdirInstance->triggerEvent(event, parameter1, parameter2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FreshDeviceHandlerBase::forwardEvent(Event event, uint32_t parameter1,
|
|
||||||
uint32_t parameter2) const {
|
|
||||||
fdirInstance->triggerEvent(event, parameter1, parameter2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FreshDeviceHandlerBase::setToExternalControl() { setHealth(HealthState::EXTERNAL_CONTROL); }
|
|
||||||
|
|
||||||
// System Object overrides.
|
|
||||||
ReturnValue_t FreshDeviceHandlerBase::initialize() {
|
|
||||||
ReturnValue_t result = modeHelper.initialize();
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = healthHelper.initialize();
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = actionHelper.initialize(messageQueue);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = paramHelper.initialize();
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = poolManager.initialize(messageQueue);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
if (fdirInstance == nullptr) {
|
|
||||||
hasCustomFdir = false;
|
|
||||||
fdirInstance = new DeviceHandlerFailureIsolation(getObjectId(), defaultFdirParent);
|
|
||||||
}
|
|
||||||
|
|
||||||
result = fdirInstance->initialize();
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return SystemObject::initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t FreshDeviceHandlerBase::getParameter(uint8_t domainId, uint8_t uniqueId,
|
|
||||||
ParameterWrapper* parameterWrapper,
|
|
||||||
const ParameterWrapper* newValues,
|
|
||||||
uint16_t startAtIndex) {
|
|
||||||
ReturnValue_t result =
|
|
||||||
fdirInstance->getParameter(domainId, uniqueId, parameterWrapper, newValues, startAtIndex);
|
|
||||||
if (result != INVALID_DOMAIN_ID) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return INVALID_DOMAIN_ID;
|
|
||||||
}
|
|
|
@ -1,167 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "fsfw/action.h"
|
|
||||||
#include "fsfw/datapoollocal/HasLocalDataPoolIF.h"
|
|
||||||
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
|
|
||||||
#include "fsfw/devicehandlers/DeviceHandlerIF.h"
|
|
||||||
#include "fsfw/fdir/FailureIsolationBase.h"
|
|
||||||
#include "fsfw/health/HasHealthIF.h"
|
|
||||||
#include "fsfw/health/HealthHelper.h"
|
|
||||||
#include "fsfw/modes/HasModesIF.h"
|
|
||||||
#include "fsfw/objectmanager.h"
|
|
||||||
#include "fsfw/parameters/ParameterHelper.h"
|
|
||||||
#include "fsfw/parameters/ReceivesParameterMessagesIF.h"
|
|
||||||
#include "fsfw/retval.h"
|
|
||||||
#include "fsfw/subsystem/ModeTreeChildIF.h"
|
|
||||||
#include "fsfw/subsystem/ModeTreeConnectionIF.h"
|
|
||||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
|
||||||
#include "fsfw/tasks/PeriodicTaskIF.h"
|
|
||||||
|
|
||||||
struct DhbConfig {
|
|
||||||
explicit DhbConfig(object_id_t objectId) : objectId(objectId) {}
|
|
||||||
object_id_t objectId;
|
|
||||||
FailureIsolationBase* fdirInstance = nullptr;
|
|
||||||
object_id_t defaultFdirParent = objects::NO_OBJECT;
|
|
||||||
uint32_t msgQueueDepth = 10;
|
|
||||||
};
|
|
||||||
|
|
||||||
class FreshDeviceHandlerBase : public SystemObject,
|
|
||||||
public DeviceHandlerIF,
|
|
||||||
public HasModesIF,
|
|
||||||
public HasHealthIF,
|
|
||||||
public ExecutableObjectIF,
|
|
||||||
public ModeTreeChildIF,
|
|
||||||
public ModeTreeConnectionIF,
|
|
||||||
public HasActionsIF,
|
|
||||||
public ReceivesParameterMessagesIF,
|
|
||||||
public HasLocalDataPoolIF {
|
|
||||||
public:
|
|
||||||
explicit FreshDeviceHandlerBase(DhbConfig config);
|
|
||||||
~FreshDeviceHandlerBase() override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Periodic helper executed function, implemented by child class.
|
|
||||||
*/
|
|
||||||
virtual void performDeviceOperation(uint8_t opCode) = 0;
|
|
||||||
|
|
||||||
[[nodiscard]] object_id_t getObjectId() const override;
|
|
||||||
|
|
||||||
[[nodiscard]] MessageQueueId_t getCommandQueue() const override;
|
|
||||||
|
|
||||||
HasHealthIF::HealthState getHealth() override;
|
|
||||||
|
|
||||||
// Mode Tree Overrides.
|
|
||||||
[[nodiscard]] const HasHealthIF* getOptHealthIF() const override;
|
|
||||||
[[nodiscard]] const HasModesIF& getModeIF() const override;
|
|
||||||
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override;
|
|
||||||
ModeTreeChildIF& getModeTreeChildIF() override;
|
|
||||||
|
|
||||||
[[nodiscard]] uint32_t getPeriodicOperationFrequency() const override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Pool Manager overrides.
|
|
||||||
LocalDataPoolManager* getHkManagerHandle() override;
|
|
||||||
ActionHelper actionHelper;
|
|
||||||
ModeHelper modeHelper;
|
|
||||||
HealthHelper healthHelper;
|
|
||||||
ParameterHelper paramHelper;
|
|
||||||
LocalDataPoolManager poolManager;
|
|
||||||
|
|
||||||
bool hasCustomFdir = false;
|
|
||||||
FailureIsolationBase* fdirInstance;
|
|
||||||
object_id_t defaultFdirParent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pointer to the task which executes this component,
|
|
||||||
* is invalid before setTaskIF was called.
|
|
||||||
*/
|
|
||||||
PeriodicTaskIF* executingTask = nullptr;
|
|
||||||
|
|
||||||
Mode_t mode = HasModesIF::MODE_UNDEFINED;
|
|
||||||
Submode_t submode = 0;
|
|
||||||
|
|
||||||
MessageQueueIF* messageQueue;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The default queue handler will process all messages for the interfaces implemented
|
|
||||||
* by this class. If there are special requirements, for example that action commands are
|
|
||||||
* received on a different queue, the user can override this function for those special
|
|
||||||
* requirements.
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t handleQueue();
|
|
||||||
|
|
||||||
// Mode Helpers.
|
|
||||||
virtual void modeChanged(Mode_t mode, Submode_t submode);
|
|
||||||
/**
|
|
||||||
* The default implementation sets the new mode immediately. If this is not applicable for
|
|
||||||
* certain modes, the user should provide a custom implementation, which performs roughly
|
|
||||||
* the same functionality of this function, when all the steps have been taken to reach the
|
|
||||||
* new mode.
|
|
||||||
*/
|
|
||||||
void startTransition(Mode_t mode, Submode_t submode) override;
|
|
||||||
virtual void setMode(Mode_t newMode, Submode_t newSubmode);
|
|
||||||
virtual void setMode(Mode_t newMode);
|
|
||||||
void getMode(Mode_t* mode, Submode_t* submode) override;
|
|
||||||
void setToExternalControl() override;
|
|
||||||
void announceMode(bool recursive) override;
|
|
||||||
// System Object overrides.
|
|
||||||
ReturnValue_t initialize() override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implemented by child class. Handle all command messages which are
|
|
||||||
* not health, mode, action or housekeeping messages.
|
|
||||||
* @param message
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t handleCommandMessage(CommandMessage* message) = 0;
|
|
||||||
|
|
||||||
// HK manager abstract functions.
|
|
||||||
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override = 0;
|
|
||||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
|
||||||
LocalDataPoolManager& poolManager) override = 0;
|
|
||||||
|
|
||||||
// Mode abstract functions
|
|
||||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
|
||||||
uint32_t* msToReachTheMode) override = 0;
|
|
||||||
// Health Overrides.
|
|
||||||
ReturnValue_t setHealth(HealthState health) override;
|
|
||||||
// Action override. Forward to user.
|
|
||||||
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
|
||||||
const uint8_t* data, size_t size) override = 0;
|
|
||||||
// Executable overrides.
|
|
||||||
virtual ReturnValue_t performOperation(uint8_t opCode) override;
|
|
||||||
ReturnValue_t initializeAfterTaskCreation() override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This calls the FDIR instance event trigger function.
|
|
||||||
* @param event
|
|
||||||
* @param parameter1
|
|
||||||
* @param parameter2
|
|
||||||
*/
|
|
||||||
void triggerEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0) override;
|
|
||||||
/**
|
|
||||||
* This calls the FDIR instance event forward function.
|
|
||||||
* @param event
|
|
||||||
* @param parameter1
|
|
||||||
* @param parameter2
|
|
||||||
*/
|
|
||||||
void forwardEvent(Event event, uint32_t parameter1, uint32_t parameter2) const override;
|
|
||||||
/**
|
|
||||||
* This implementation handles the FDIR parameters. The user can override this to handle
|
|
||||||
* custom parameters.
|
|
||||||
* @param domainId
|
|
||||||
* @param uniqueId
|
|
||||||
* @param parameterWrapper
|
|
||||||
* @param newValues
|
|
||||||
* @param startAtIndex
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, ParameterWrapper* parameterWrapper,
|
|
||||||
const ParameterWrapper* newValues, uint16_t startAtIndex) override;
|
|
||||||
|
|
||||||
virtual ReturnValue_t performDeviceOperationPreQueueHandling(uint8_t opCode);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Executable Overrides.
|
|
||||||
void setTaskIF(PeriodicTaskIF* task) override;
|
|
||||||
};
|
|
|
@ -206,9 +206,9 @@ void EventManager::printUtility(sif::OutputTypes printType, EventMessage* messag
|
||||||
sif::printDebug("Event Manager: Reporter ID 0x%08x reported event with ID %d\n",
|
sif::printDebug("Event Manager: Reporter ID 0x%08x reported event with ID %d\n",
|
||||||
message->getReporter(), message->getEventId());
|
message->getReporter(), message->getEventId());
|
||||||
}
|
}
|
||||||
sif::printDebug("%s | P1 Hex: 0x%x | P1 Dec: %d | P2 Hex: 0x%x | P2 Dec: %d\n",
|
sif::printDebug("P1 Hex: 0x%x | P1 Dec: %d | P2 Hex: 0x%x | P2 Dec: %d\n",
|
||||||
translateEvents(message->getEvent()), message->getParameter1(),
|
message->getParameter1(), message->getParameter1(), message->getParameter2(),
|
||||||
message->getParameter1(), message->getParameter2(), message->getParameter2());
|
message->getParameter2());
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 0 */
|
#endif /* FSFW_CPP_OSTREAM_ENABLED == 0 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ extern const char* translateEvents(Event event);
|
||||||
|
|
||||||
class EventManager : public EventManagerIF, public ExecutableObjectIF, public SystemObject {
|
class EventManager : public EventManagerIF, public ExecutableObjectIF, public SystemObject {
|
||||||
public:
|
public:
|
||||||
|
static const uint16_t DEFAULT_MAX_EVENTS_PER_CYCLE = 80;
|
||||||
|
|
||||||
EventManager(object_id_t setObjectId, uint32_t eventQueueDepth);
|
EventManager(object_id_t setObjectId, uint32_t eventQueueDepth);
|
||||||
virtual ~EventManager();
|
virtual ~EventManager();
|
||||||
|
|
||||||
|
|
|
@ -148,16 +148,25 @@ void FailureIsolationBase::doConfirmFault(EventMessage* event) {
|
||||||
ReturnValue_t FailureIsolationBase::confirmFault(EventMessage* event) { return YOUR_FAULT; }
|
ReturnValue_t FailureIsolationBase::confirmFault(EventMessage* event) { return YOUR_FAULT; }
|
||||||
|
|
||||||
void FailureIsolationBase::triggerEvent(Event event, uint32_t parameter1, uint32_t parameter2) {
|
void FailureIsolationBase::triggerEvent(Event event, uint32_t parameter1, uint32_t parameter2) {
|
||||||
// By default, we trigger all events and also call the handler function to handle FDIR reactions
|
// With this mechanism, all events are disabled for a certain device.
|
||||||
// which might occur due to these events. This makes all events visible. If the handling of
|
// That's not so good for visibility.
|
||||||
// FDIR reaction should be disabled, this should be done through dedicated logic inside the
|
if (isFdirDisabledForSeverity(event::getSeverity(event))) {
|
||||||
// eventReceived function.
|
return;
|
||||||
|
}
|
||||||
EventMessage message(event, ownerId, parameter1, parameter2);
|
EventMessage message(event, ownerId, parameter1, parameter2);
|
||||||
EventManagerIF::triggerEvent(&message, eventQueue->getId());
|
EventManagerIF::triggerEvent(&message, eventQueue->getId());
|
||||||
eventReceived(&message);
|
eventReceived(&message);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FailureIsolationBase::isFdirDisabledForSeverity(EventSeverity_t severity) { return false; }
|
bool FailureIsolationBase::isFdirDisabledForSeverity(EventSeverity_t severity) {
|
||||||
|
if ((owner != NULL) && (severity != severity::INFO)) {
|
||||||
|
if (owner->getHealth() == HasHealthIF::EXTERNAL_CONTROL) {
|
||||||
|
// External control disables handling of fault messages.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void FailureIsolationBase::throwFdirEvent(Event event, uint32_t parameter1, uint32_t parameter2) {
|
void FailureIsolationBase::throwFdirEvent(Event event, uint32_t parameter1, uint32_t parameter2) {
|
||||||
EventMessage message(event, ownerId, parameter1, parameter2);
|
EventMessage message(event, ownerId, parameter1, parameter2);
|
||||||
|
|
|
@ -44,13 +44,13 @@ class FailureIsolationBase : public ConfirmsFailuresIF, public HasParametersIF {
|
||||||
virtual void wasParentsFault(EventMessage* event);
|
virtual void wasParentsFault(EventMessage* event);
|
||||||
virtual ReturnValue_t confirmFault(EventMessage* event);
|
virtual ReturnValue_t confirmFault(EventMessage* event);
|
||||||
virtual void decrementFaultCounters() = 0;
|
virtual void decrementFaultCounters() = 0;
|
||||||
virtual bool isFdirDisabledForSeverity(EventSeverity_t severity);
|
|
||||||
ReturnValue_t sendConfirmationRequest(EventMessage* event,
|
ReturnValue_t sendConfirmationRequest(EventMessage* event,
|
||||||
MessageQueueId_t destination = MessageQueueIF::NO_QUEUE);
|
MessageQueueId_t destination = MessageQueueIF::NO_QUEUE);
|
||||||
void throwFdirEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0);
|
void throwFdirEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void doConfirmFault(EventMessage* event);
|
void doConfirmFault(EventMessage* event);
|
||||||
|
bool isFdirDisabledForSeverity(EventSeverity_t severity);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FRAMEWORK_FDIR */
|
#endif /* FRAMEWORK_FDIR_FAILUREISOLATIONBASE_H_ */
|
||||||
|
|
|
@ -17,7 +17,7 @@ struct FilesystemParams {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FileOpParams {
|
struct FileOpParams {
|
||||||
FileOpParams(const char* path, size_t opSize) : fsParams(path), size(opSize) {}
|
FileOpParams(const char* path, size_t size) : fsParams(path), size(size) {}
|
||||||
|
|
||||||
[[nodiscard]] const char* path() const { return fsParams.path; }
|
[[nodiscard]] const char* path() const { return fsParams.path; }
|
||||||
|
|
||||||
|
@ -80,8 +80,6 @@ class HasFileSystemIF {
|
||||||
|
|
||||||
virtual bool isDirectory(const char* path) = 0;
|
virtual bool isDirectory(const char* path) = 0;
|
||||||
|
|
||||||
virtual ReturnValue_t getFileSize(FilesystemParams params, uint64_t& fileSize) = 0;
|
|
||||||
|
|
||||||
virtual bool fileExists(FilesystemParams params) = 0;
|
virtual bool fileExists(FilesystemParams params) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -44,13 +44,13 @@ class Type : public SerializeIF {
|
||||||
|
|
||||||
static ActualType_t getActualType(uint8_t ptc, uint8_t pfc);
|
static ActualType_t getActualType(uint8_t ptc, uint8_t pfc);
|
||||||
|
|
||||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||||
Endianness streamEndianness) const override;
|
Endianness streamEndianness) const override;
|
||||||
|
|
||||||
size_t getSerializedSize() const override;
|
virtual size_t getSerializedSize() const override;
|
||||||
|
|
||||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||||
Endianness streamEndianness) override;
|
Endianness streamEndianness) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ActualType_t actualType;
|
ActualType_t actualType;
|
||||||
|
|
|
@ -58,7 +58,7 @@ void arrayprinter::printHex(const uint8_t *data, size_t size, size_t maxCharPerL
|
||||||
#else
|
#else
|
||||||
// General format: 0x01, 0x02, 0x03 so it is number of chars times 6
|
// General format: 0x01, 0x02, 0x03 so it is number of chars times 6
|
||||||
// plus line break plus small safety margin.
|
// plus line break plus small safety margin.
|
||||||
char printBuffer[(size + 1) * 7 + 1] = {};
|
char printBuffer[2048] = {};
|
||||||
size_t currentPos = 0;
|
size_t currentPos = 0;
|
||||||
for (size_t i = 0; i < size; i++) {
|
for (size_t i = 0; i < size; i++) {
|
||||||
// To avoid buffer overflows.
|
// To avoid buffer overflows.
|
||||||
|
@ -101,7 +101,7 @@ void arrayprinter::printDec(const uint8_t *data, size_t size, size_t maxCharPerL
|
||||||
// General format: 32,243,-12 so it is number of chars times 4
|
// General format: 32,243,-12 so it is number of chars times 4
|
||||||
// plus line break plus small safety margin.
|
// plus line break plus small safety margin.
|
||||||
uint16_t expectedLines = ceil((double)size / maxCharPerLine);
|
uint16_t expectedLines = ceil((double)size / maxCharPerLine);
|
||||||
char printBuffer[size * 4 + 1 + expectedLines] = {};
|
char printBuffer[2048] = {};
|
||||||
size_t currentPos = 0;
|
size_t currentPos = 0;
|
||||||
for (size_t i = 0; i < size; i++) {
|
for (size_t i = 0; i < size; i++) {
|
||||||
// To avoid buffer overflows.
|
// To avoid buffer overflows.
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
#ifndef MATRIXOPERATIONS_H_
|
#ifndef MATRIXOPERATIONS_H_
|
||||||
#define MATRIXOPERATIONS_H_
|
#define MATRIXOPERATIONS_H_
|
||||||
|
|
||||||
#include <fsfw/retval.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstring>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
template <typename T1, typename T2 = T1, typename T3 = T2>
|
template <typename T1, typename T2 = T1, typename T3 = T2>
|
||||||
class MatrixOperations {
|
class MatrixOperations {
|
||||||
|
@ -98,139 +95,6 @@ class MatrixOperations {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isFinite(const T1 *inputMatrix, uint8_t rows, uint8_t cols) {
|
|
||||||
for (uint8_t col = 0; col < cols; col++) {
|
|
||||||
for (uint8_t row = 0; row < rows; row++) {
|
|
||||||
if (not std::isfinite(inputMatrix[row * cols + cols])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void writeSubmatrix(T1 *mainMatrix, T1 *subMatrix, uint8_t subRows, uint8_t subCols,
|
|
||||||
uint8_t mainRows, uint8_t mainCols, uint8_t startRow,
|
|
||||||
uint8_t startCol) {
|
|
||||||
if ((startRow + subRows > mainRows) or (startCol + subCols > mainCols)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (uint8_t row = 0; row < subRows; row++) {
|
|
||||||
for (uint8_t col = 0; col < subCols; col++) {
|
|
||||||
mainMatrix[(startRow + row) * mainCols + (startCol + col)] = subMatrix[row * subCols + col];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static ReturnValue_t inverseMatrix(const T1 *inputMatrix, T1 *inverse, uint8_t size) {
|
|
||||||
// Stopwatch stopwatch;
|
|
||||||
T1 matrix[size][size], identity[size][size];
|
|
||||||
// reformat array to matrix
|
|
||||||
for (uint8_t row = 0; row < size; row++) {
|
|
||||||
for (uint8_t col = 0; col < size; col++) {
|
|
||||||
matrix[row][col] = inputMatrix[row * size + col];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// init identity matrix
|
|
||||||
std::memset(identity, 0.0, sizeof(identity));
|
|
||||||
for (uint8_t diag = 0; diag < size; diag++) {
|
|
||||||
identity[diag][diag] = 1;
|
|
||||||
}
|
|
||||||
// gauss-jordan algo
|
|
||||||
// sort matrix such as no diag entry shall be 0
|
|
||||||
for (uint8_t row = 0; row < size; row++) {
|
|
||||||
if (matrix[row][row] == 0.0) {
|
|
||||||
bool swaped = false;
|
|
||||||
uint8_t rowIndex = 0;
|
|
||||||
while ((rowIndex < size) && !swaped) {
|
|
||||||
if ((matrix[rowIndex][row] != 0.0) && (matrix[row][rowIndex] != 0.0)) {
|
|
||||||
for (uint8_t colIndex = 0; colIndex < size; colIndex++) {
|
|
||||||
std::swap(matrix[row][colIndex], matrix[rowIndex][colIndex]);
|
|
||||||
std::swap(identity[row][colIndex], identity[rowIndex][colIndex]);
|
|
||||||
}
|
|
||||||
swaped = true;
|
|
||||||
}
|
|
||||||
rowIndex++;
|
|
||||||
}
|
|
||||||
if (!swaped) {
|
|
||||||
return returnvalue::FAILED; // matrix not invertible
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int row = 0; row < size; row++) {
|
|
||||||
if (matrix[row][row] == 0.0) {
|
|
||||||
uint8_t rowIndex;
|
|
||||||
if (row == 0) {
|
|
||||||
rowIndex = size - 1;
|
|
||||||
} else {
|
|
||||||
rowIndex = row - 1;
|
|
||||||
}
|
|
||||||
for (uint8_t colIndex = 0; colIndex < size; colIndex++) {
|
|
||||||
std::swap(matrix[row][colIndex], matrix[rowIndex][colIndex]);
|
|
||||||
std::swap(identity[row][colIndex], identity[rowIndex][colIndex]);
|
|
||||||
}
|
|
||||||
row--;
|
|
||||||
if (row < 0) {
|
|
||||||
return returnvalue::FAILED; // Matrix is not invertible
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// remove non diag elements in matrix (jordan)
|
|
||||||
for (int row = 0; row < size; row++) {
|
|
||||||
for (int rowIndex = 0; rowIndex < size; rowIndex++) {
|
|
||||||
if (row != rowIndex) {
|
|
||||||
double ratio = matrix[rowIndex][row] / matrix[row][row];
|
|
||||||
for (int colIndex = 0; colIndex < size; colIndex++) {
|
|
||||||
matrix[rowIndex][colIndex] -= ratio * matrix[row][colIndex];
|
|
||||||
identity[rowIndex][colIndex] -= ratio * identity[row][colIndex];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// normalize rows in matrix (gauss)
|
|
||||||
for (int row = 0; row < size; row++) {
|
|
||||||
for (int col = 0; col < size; col++) {
|
|
||||||
identity[row][col] = identity[row][col] / matrix[row][row];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::memcpy(inverse, identity, sizeof(identity));
|
|
||||||
return returnvalue::OK; // successful inversion
|
|
||||||
}
|
|
||||||
|
|
||||||
static void inverseMatrixDimThree(const T1 *matrix, T1 *output) {
|
|
||||||
int i, j;
|
|
||||||
double determinant = 0;
|
|
||||||
double mat[3][3] = {{matrix[0], matrix[1], matrix[2]},
|
|
||||||
{matrix[3], matrix[4], matrix[5]},
|
|
||||||
{matrix[6], matrix[7], matrix[8]}};
|
|
||||||
|
|
||||||
for (i = 0; i < 3; i++) {
|
|
||||||
determinant = determinant + (mat[0][i] * (mat[1][(i + 1) % 3] * mat[2][(i + 2) % 3] -
|
|
||||||
mat[1][(i + 2) % 3] * mat[2][(i + 1) % 3]));
|
|
||||||
}
|
|
||||||
for (i = 0; i < 3; i++) {
|
|
||||||
for (j = 0; j < 3; j++) {
|
|
||||||
output[i * 3 + j] = ((mat[(j + 1) % 3][(i + 1) % 3] * mat[(j + 2) % 3][(i + 2) % 3]) -
|
|
||||||
(mat[(j + 1) % 3][(i + 2) % 3] * mat[(j + 2) % 3][(i + 1) % 3])) /
|
|
||||||
determinant;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void skewMatrix(const T1 *vector, T2 *result) {
|
|
||||||
// Input Dimension [3], Output [3][3]
|
|
||||||
result[0] = 0;
|
|
||||||
result[1] = -vector[2];
|
|
||||||
result[2] = vector[1];
|
|
||||||
result[3] = vector[2];
|
|
||||||
result[4] = 0;
|
|
||||||
result[5] = -vector[0];
|
|
||||||
result[6] = -vector[1];
|
|
||||||
result[7] = vector[0];
|
|
||||||
result[8] = 0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MATRIXOPERATIONS_H_ */
|
#endif /* MATRIXOPERATIONS_H_ */
|
||||||
|
|
|
@ -39,48 +39,6 @@ void QuaternionOperations::inverse(const double* quaternion, double* inverseQuat
|
||||||
VectorOperations<double>::mulScalar(inverseQuaternion, -1, inverseQuaternion, 3);
|
VectorOperations<double>::mulScalar(inverseQuaternion, -1, inverseQuaternion, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuaternionOperations::slerp(const double q1[4], const double q2[4], const double weight,
|
|
||||||
double q[4]) {
|
|
||||||
double q1s[4] = {0, 0, 0, 0}, q2I[4] = {0, 0, 0, 0}, qD[4] = {0, 0, 0, 0}, left[4] = {0, 0, 0, 0},
|
|
||||||
right[4] = {0, 0, 0, 0}, angle = 0;
|
|
||||||
|
|
||||||
// we need to be able to invert this quaternion
|
|
||||||
std::memcpy(q1s, q1, 4 * sizeof(double));
|
|
||||||
// calculate angle between orientations
|
|
||||||
inverse(q2, q2I);
|
|
||||||
multiply(q1s, q2I, qD);
|
|
||||||
angle = std::acos(qD[3]);
|
|
||||||
|
|
||||||
if (std::cos(angle) < 0.0) {
|
|
||||||
// we need to invert one quaternion
|
|
||||||
VectorOperations<double>::mulScalar(q1s, -1, q1s, 4);
|
|
||||||
multiply(q1s, q2I, qD);
|
|
||||||
angle = std::acos(qD[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (std::sin(angle) == 0.0) {
|
|
||||||
// nothing to calculate here
|
|
||||||
std::memcpy(q, q1s, 4 * sizeof(double));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
VectorOperations<double>::mulScalar(q1s, std::sin((1 - weight) * angle) / std::sin(angle), left,
|
|
||||||
4);
|
|
||||||
VectorOperations<double>::mulScalar(q2, std::sin(weight * angle) / std::sin(angle), right, 4);
|
|
||||||
VectorOperations<double>::add(left, right, q, 4);
|
|
||||||
|
|
||||||
normalize(q);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QuaternionOperations::preventSignJump(double qNew[4], const double qOld[4]) {
|
|
||||||
double qDiff[4] = {0, 0, 0, 0}, qSum[4] = {0, 0, 0, 0};
|
|
||||||
VectorOperations<double>::subtract(qOld, qNew, qDiff, 4);
|
|
||||||
VectorOperations<double>::add(qOld, qNew, qSum, 4);
|
|
||||||
if (VectorOperations<double>::norm(qDiff, 4) > VectorOperations<double>::norm(qSum, 4)) {
|
|
||||||
VectorOperations<double>::mulScalar(qNew, -1, qNew, 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QuaternionOperations::QuaternionOperations() {}
|
QuaternionOperations::QuaternionOperations() {}
|
||||||
|
|
||||||
void QuaternionOperations::normalize(const double* quaternion, double* unitQuaternion) {
|
void QuaternionOperations::normalize(const double* quaternion, double* unitQuaternion) {
|
||||||
|
@ -162,25 +120,3 @@ double QuaternionOperations::getAngle(const double* quaternion, bool abs) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuaternionOperations::rotationFromQuaternions(const double qNew[4], const double qOld[4],
|
|
||||||
const double timeDelta, double rotRate[3]) {
|
|
||||||
double qOldInv[4] = {0, 0, 0, 0};
|
|
||||||
double qDelta[4] = {0, 0, 0, 0};
|
|
||||||
|
|
||||||
inverse(qOld, qOldInv);
|
|
||||||
multiply(qNew, qOldInv, qDelta);
|
|
||||||
if (VectorOperations<double>::norm(qDelta, 4) != 0.0) {
|
|
||||||
normalize(qDelta);
|
|
||||||
}
|
|
||||||
if (VectorOperations<double>::norm(qDelta, 3) == 0.0) {
|
|
||||||
rotRate[0] = 0.0;
|
|
||||||
rotRate[1] = 0.0;
|
|
||||||
rotRate[2] = 0.0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
double rotVec[3] = {0, 0, 0};
|
|
||||||
double angle = getAngle(qDelta);
|
|
||||||
VectorOperations<double>::normalize(qDelta, rotVec, 3);
|
|
||||||
VectorOperations<double>::mulScalar(rotVec, angle / timeDelta, rotRate, 3);
|
|
||||||
}
|
|
||||||
|
|
|
@ -23,13 +23,6 @@ class QuaternionOperations {
|
||||||
|
|
||||||
static void inverse(const double *quaternion, double *inverseQuaternion);
|
static void inverse(const double *quaternion, double *inverseQuaternion);
|
||||||
|
|
||||||
static void slerp(const double q1[4], const double q2[4], const double weight, double q[4]);
|
|
||||||
|
|
||||||
static void rotationFromQuaternions(const double qNew[4], const double qOld[4],
|
|
||||||
const double timeDelta, double rotRate[3]);
|
|
||||||
|
|
||||||
static void preventSignJump(double qNew[4], const double qOld[4]);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns angle in ]-Pi;Pi] or [0;Pi] if abs == true
|
* returns angle in ]-Pi;Pi] or [0;Pi] if abs == true
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -99,15 +99,6 @@ class VectorOperations {
|
||||||
|
|
||||||
static void copy(const T *in, T *out, uint8_t size) { mulScalar(in, 1, out, size); }
|
static void copy(const T *in, T *out, uint8_t size) { mulScalar(in, 1, out, size); }
|
||||||
|
|
||||||
static bool isFinite(const T *inputVector, uint8_t size) {
|
|
||||||
for (uint8_t i = 0; i < size; i++) {
|
|
||||||
if (not std::isfinite(inputVector[i])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VectorOperations();
|
VectorOperations();
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,6 +14,14 @@ void HousekeepingMessage::setHkReportReply(CommandMessage *message, sid_t sid,
|
||||||
message->setParameter3(storeId.raw);
|
message->setParameter3(storeId.raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HousekeepingMessage::setHkDiagnosticsReply(CommandMessage *message, sid_t sid,
|
||||||
|
store_address_t storeId) {
|
||||||
|
message->setCommand(DIAGNOSTICS_REPORT);
|
||||||
|
message->setMessageSize(HK_MESSAGE_SIZE);
|
||||||
|
setSid(message, sid);
|
||||||
|
message->setParameter3(storeId.raw);
|
||||||
|
}
|
||||||
|
|
||||||
sid_t HousekeepingMessage::getHkDataReply(const CommandMessage *message,
|
sid_t HousekeepingMessage::getHkDataReply(const CommandMessage *message,
|
||||||
store_address_t *storeIdToSet) {
|
store_address_t *storeIdToSet) {
|
||||||
if (storeIdToSet != nullptr) {
|
if (storeIdToSet != nullptr) {
|
||||||
|
@ -23,32 +31,55 @@ sid_t HousekeepingMessage::getHkDataReply(const CommandMessage *message,
|
||||||
}
|
}
|
||||||
|
|
||||||
void HousekeepingMessage::setToggleReportingCommand(CommandMessage *message, sid_t sid,
|
void HousekeepingMessage::setToggleReportingCommand(CommandMessage *message, sid_t sid,
|
||||||
bool enableReporting) {
|
bool enableReporting, bool isDiagnostics) {
|
||||||
if (enableReporting) {
|
if (isDiagnostics) {
|
||||||
message->setCommand(ENABLE_PERIODIC_HK_REPORT_GENERATION);
|
if (enableReporting) {
|
||||||
|
message->setCommand(ENABLE_PERIODIC_DIAGNOSTICS_GENERATION);
|
||||||
|
} else {
|
||||||
|
message->setCommand(DISABLE_PERIODIC_DIAGNOSTICS_GENERATION);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
message->setCommand(DISABLE_PERIODIC_HK_REPORT_GENERATION);
|
if (enableReporting) {
|
||||||
|
message->setCommand(ENABLE_PERIODIC_HK_REPORT_GENERATION);
|
||||||
|
} else {
|
||||||
|
message->setCommand(DISABLE_PERIODIC_HK_REPORT_GENERATION);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setSid(message, sid);
|
setSid(message, sid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HousekeepingMessage::setStructureReportingCommand(CommandMessage *command, sid_t sid) {
|
void HousekeepingMessage::setStructureReportingCommand(CommandMessage *command, sid_t sid,
|
||||||
command->setCommand(REPORT_HK_REPORT_STRUCTURES);
|
bool isDiagnostics) {
|
||||||
|
if (isDiagnostics) {
|
||||||
|
command->setCommand(REPORT_DIAGNOSTICS_REPORT_STRUCTURES);
|
||||||
|
} else {
|
||||||
|
command->setCommand(REPORT_HK_REPORT_STRUCTURES);
|
||||||
|
}
|
||||||
|
|
||||||
setSid(command, sid);
|
setSid(command, sid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HousekeepingMessage::setOneShotReportCommand(CommandMessage *command, sid_t sid) {
|
void HousekeepingMessage::setOneShotReportCommand(CommandMessage *command, sid_t sid,
|
||||||
command->setCommand(GENERATE_ONE_PARAMETER_REPORT);
|
bool isDiagnostics) {
|
||||||
|
if (isDiagnostics) {
|
||||||
|
command->setCommand(GENERATE_ONE_DIAGNOSTICS_REPORT);
|
||||||
|
} else {
|
||||||
|
command->setCommand(GENERATE_ONE_PARAMETER_REPORT);
|
||||||
|
}
|
||||||
|
|
||||||
setSid(command, sid);
|
setSid(command, sid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HousekeepingMessage::setCollectionIntervalModificationCommand(CommandMessage *command,
|
void HousekeepingMessage::setCollectionIntervalModificationCommand(CommandMessage *command,
|
||||||
sid_t sid,
|
sid_t sid,
|
||||||
float collectionInterval) {
|
float collectionInterval,
|
||||||
command->setCommand(MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL);
|
bool isDiagnostics) {
|
||||||
|
if (isDiagnostics) {
|
||||||
|
command->setCommand(MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL);
|
||||||
|
} else {
|
||||||
|
command->setCommand(MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Raw storage of the float in the message. Do not use setParameter3, does
|
/* Raw storage of the float in the message. Do not use setParameter3, does
|
||||||
implicit conversion to integer type! */
|
implicit conversion to integer type! */
|
||||||
|
@ -107,11 +138,19 @@ void HousekeepingMessage::setHkStuctureReportReply(CommandMessage *reply, sid_t
|
||||||
reply->setParameter3(storeId.raw);
|
reply->setParameter3(storeId.raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HousekeepingMessage::setDiagnosticsStuctureReportReply(CommandMessage *reply, sid_t sid,
|
||||||
|
store_address_t storeId) {
|
||||||
|
reply->setCommand(DIAGNOSTICS_DEFINITION_REPORT);
|
||||||
|
setSid(reply, sid);
|
||||||
|
reply->setParameter3(storeId.raw);
|
||||||
|
}
|
||||||
|
|
||||||
void HousekeepingMessage::clear(CommandMessage *message) {
|
void HousekeepingMessage::clear(CommandMessage *message) {
|
||||||
switch (message->getCommand()) {
|
switch (message->getCommand()) {
|
||||||
case (HK_REPORT):
|
case (HK_REPORT):
|
||||||
case (DIAGNOSTICS_REPORT):
|
case (DIAGNOSTICS_REPORT):
|
||||||
case (HK_DEFINITIONS_REPORT):
|
case (HK_DEFINITIONS_REPORT):
|
||||||
|
case (DIAGNOSTICS_DEFINITION_REPORT):
|
||||||
case (UPDATE_SNAPSHOT_SET):
|
case (UPDATE_SNAPSHOT_SET):
|
||||||
case (UPDATE_SNAPSHOT_VARIABLE): {
|
case (UPDATE_SNAPSHOT_VARIABLE): {
|
||||||
store_address_t storeId;
|
store_address_t storeId;
|
||||||
|
|
|
@ -30,16 +30,23 @@ class HousekeepingMessage {
|
||||||
static constexpr Command_t ENABLE_PERIODIC_HK_REPORT_GENERATION = MAKE_COMMAND_ID(5);
|
static constexpr Command_t ENABLE_PERIODIC_HK_REPORT_GENERATION = MAKE_COMMAND_ID(5);
|
||||||
static constexpr Command_t DISABLE_PERIODIC_HK_REPORT_GENERATION = MAKE_COMMAND_ID(6);
|
static constexpr Command_t DISABLE_PERIODIC_HK_REPORT_GENERATION = MAKE_COMMAND_ID(6);
|
||||||
|
|
||||||
|
static constexpr Command_t ENABLE_PERIODIC_DIAGNOSTICS_GENERATION = MAKE_COMMAND_ID(7);
|
||||||
|
static constexpr Command_t DISABLE_PERIODIC_DIAGNOSTICS_GENERATION = MAKE_COMMAND_ID(8);
|
||||||
|
|
||||||
static constexpr Command_t REPORT_HK_REPORT_STRUCTURES = MAKE_COMMAND_ID(9);
|
static constexpr Command_t REPORT_HK_REPORT_STRUCTURES = MAKE_COMMAND_ID(9);
|
||||||
|
static constexpr Command_t REPORT_DIAGNOSTICS_REPORT_STRUCTURES = MAKE_COMMAND_ID(11);
|
||||||
|
|
||||||
static constexpr Command_t HK_DEFINITIONS_REPORT = MAKE_COMMAND_ID(10);
|
static constexpr Command_t HK_DEFINITIONS_REPORT = MAKE_COMMAND_ID(10);
|
||||||
|
static constexpr Command_t DIAGNOSTICS_DEFINITION_REPORT = MAKE_COMMAND_ID(12);
|
||||||
|
|
||||||
static constexpr Command_t HK_REPORT = MAKE_COMMAND_ID(25);
|
static constexpr Command_t HK_REPORT = MAKE_COMMAND_ID(25);
|
||||||
static constexpr Command_t DIAGNOSTICS_REPORT = MAKE_COMMAND_ID(26);
|
static constexpr Command_t DIAGNOSTICS_REPORT = MAKE_COMMAND_ID(26);
|
||||||
|
|
||||||
static constexpr Command_t GENERATE_ONE_PARAMETER_REPORT = MAKE_COMMAND_ID(27);
|
static constexpr Command_t GENERATE_ONE_PARAMETER_REPORT = MAKE_COMMAND_ID(27);
|
||||||
|
static constexpr Command_t GENERATE_ONE_DIAGNOSTICS_REPORT = MAKE_COMMAND_ID(28);
|
||||||
|
|
||||||
static constexpr Command_t MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL = MAKE_COMMAND_ID(31);
|
static constexpr Command_t MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL = MAKE_COMMAND_ID(31);
|
||||||
|
static constexpr Command_t MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL = MAKE_COMMAND_ID(32);
|
||||||
|
|
||||||
static constexpr Command_t HK_REQUEST_SUCCESS = MAKE_COMMAND_ID(128);
|
static constexpr Command_t HK_REQUEST_SUCCESS = MAKE_COMMAND_ID(128);
|
||||||
static constexpr Command_t HK_REQUEST_FAILURE = MAKE_COMMAND_ID(129);
|
static constexpr Command_t HK_REQUEST_FAILURE = MAKE_COMMAND_ID(129);
|
||||||
|
@ -57,18 +64,23 @@ class HousekeepingMessage {
|
||||||
|
|
||||||
/* Housekeeping Interface Messages */
|
/* Housekeeping Interface Messages */
|
||||||
|
|
||||||
static void setToggleReportingCommand(CommandMessage* command, sid_t sid, bool enableReporting);
|
static void setToggleReportingCommand(CommandMessage* command, sid_t sid, bool enableReporting,
|
||||||
static void setStructureReportingCommand(CommandMessage* command, sid_t sid);
|
bool isDiagnostics);
|
||||||
static void setOneShotReportCommand(CommandMessage* command, sid_t sid);
|
static void setStructureReportingCommand(CommandMessage* command, sid_t sid, bool isDiagnostics);
|
||||||
|
static void setOneShotReportCommand(CommandMessage* command, sid_t sid, bool isDiagnostics);
|
||||||
static void setCollectionIntervalModificationCommand(CommandMessage* command, sid_t sid,
|
static void setCollectionIntervalModificationCommand(CommandMessage* command, sid_t sid,
|
||||||
float collectionInterval);
|
float collectionInterval,
|
||||||
|
bool isDiagnostics);
|
||||||
|
|
||||||
static void setHkReportReply(CommandMessage* reply, sid_t sid, store_address_t storeId);
|
static void setHkReportReply(CommandMessage* reply, sid_t sid, store_address_t storeId);
|
||||||
|
static void setHkDiagnosticsReply(CommandMessage* reply, sid_t sid, store_address_t storeId);
|
||||||
|
|
||||||
static void setHkRequestSuccessReply(CommandMessage* reply, sid_t sid);
|
static void setHkRequestSuccessReply(CommandMessage* reply, sid_t sid);
|
||||||
static void setHkRequestFailureReply(CommandMessage* reply, sid_t sid, ReturnValue_t error);
|
static void setHkRequestFailureReply(CommandMessage* reply, sid_t sid, ReturnValue_t error);
|
||||||
|
|
||||||
static void setHkStuctureReportReply(CommandMessage* reply, sid_t sid, store_address_t storeId);
|
static void setHkStuctureReportReply(CommandMessage* reply, sid_t sid, store_address_t storeId);
|
||||||
|
static void setDiagnosticsStuctureReportReply(CommandMessage* reply, sid_t sid,
|
||||||
|
store_address_t storeId);
|
||||||
|
|
||||||
static sid_t getHkRequestFailureReply(const CommandMessage* reply, ReturnValue_t* error);
|
static sid_t getHkRequestFailureReply(const CommandMessage* reply, ReturnValue_t* error);
|
||||||
|
|
||||||
|
|
|
@ -54,8 +54,8 @@ class HousekeepingSnapshot : public SerializeIF {
|
||||||
HousekeepingSnapshot(uint8_t* timeStamp, size_t timeStampSize, LocalPoolObjectBase* dataSetPtr)
|
HousekeepingSnapshot(uint8_t* timeStamp, size_t timeStampSize, LocalPoolObjectBase* dataSetPtr)
|
||||||
: timeStamp(timeStamp), timeStampSize(timeStampSize), updateData(dataSetPtr){};
|
: timeStamp(timeStamp), timeStampSize(timeStampSize), updateData(dataSetPtr){};
|
||||||
|
|
||||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||||
Endianness streamEndianness) const {
|
Endianness streamEndianness) const {
|
||||||
if (timeStamp != nullptr) {
|
if (timeStamp != nullptr) {
|
||||||
/* Endianness will always be MACHINE, so we can simply use memcpy
|
/* Endianness will always be MACHINE, so we can simply use memcpy
|
||||||
here. */
|
here. */
|
||||||
|
@ -70,15 +70,15 @@ class HousekeepingSnapshot : public SerializeIF {
|
||||||
return updateData->serialize(buffer, size, maxSize, streamEndianness);
|
return updateData->serialize(buffer, size, maxSize, streamEndianness);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t getSerializedSize() const {
|
virtual size_t getSerializedSize() const {
|
||||||
if (updateData == nullptr) {
|
if (updateData == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return timeStampSize + updateData->getSerializedSize();
|
return timeStampSize + updateData->getSerializedSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||||
SerializeIF::Endianness streamEndianness) override {
|
SerializeIF::Endianness streamEndianness) override {
|
||||||
if (*size < timeStampSize) {
|
if (*size < timeStampSize) {
|
||||||
return SerializeIF::STREAM_TOO_SHORT;
|
return SerializeIF::STREAM_TOO_SHORT;
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user