Compare commits
46 Commits
meier/debu
...
0af5d37b35
Author | SHA1 | Date | |
---|---|---|---|
0af5d37b35
|
|||
0fc5744719 | |||
a1b6e2ff89
|
|||
8c87dafd5d
|
|||
5ff161b70a
|
|||
9a1e82de2a | |||
e9b4fc9825 | |||
0660457c92
|
|||
7c9b9e4cd8
|
|||
3b0ee7ca31
|
|||
fb2e480705 | |||
b8ae646060 | |||
f307a86d9a
|
|||
8b21dd276d | |||
e00da212cd | |||
a229748aa4 | |||
e6e3753324 | |||
94bd1ba2ab | |||
e12a8cfa29 | |||
efbcddc2e5 | |||
31d4b85523 | |||
aff6bb673b
|
|||
f8e3777c43
|
|||
0e2fa8dc83
|
|||
0cfe559b93
|
|||
c5159fb645
|
|||
203c0bac5c
|
|||
6b70614762 | |||
43ea29cb84 | |||
27c8a97d45 | |||
47b21caf5f | |||
2673070204 | |||
518a07d05b | |||
516357d855 | |||
ac28b7e00d | |||
0d4a862c1a | |||
b2576d3422 | |||
bccaf4a9ea | |||
7d4e77843b | |||
cd2cd61ba5 | |||
90f3f8ef1f | |||
9894935e99 | |||
a3a6c0720c | |||
d5a52eadbb | |||
b5e7179af1 | |||
5879eb7f7b |
@ -4,4 +4,5 @@ IndentWidth: 2
|
|||||||
---
|
---
|
||||||
Language: Cpp
|
Language: Cpp
|
||||||
ColumnLimit: 100
|
ColumnLimit: 100
|
||||||
|
ReflowComments: true
|
||||||
---
|
---
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -2,7 +2,7 @@
|
|||||||
.idea/*
|
.idea/*
|
||||||
!/.idea/runConfigurations
|
!/.idea/runConfigurations
|
||||||
!/.idea/cmake.xml
|
!/.idea/cmake.xml
|
||||||
!/.idea/codeStyles
|
# !/.idea/codeStyles
|
||||||
|
|
||||||
# Eclipse
|
# Eclipse
|
||||||
.cproject
|
.cproject
|
||||||
|
14
.idea/codeStyles/Project.xml
generated
14
.idea/codeStyles/Project.xml
generated
@ -1,14 +0,0 @@
|
|||||||
<component name="ProjectCodeStyleConfiguration">
|
|
||||||
<code_scheme name="Project" version="173">
|
|
||||||
<clangFormatSettings>
|
|
||||||
<option name="ENABLED" value="true" />
|
|
||||||
</clangFormatSettings>
|
|
||||||
<codeStyleSettings language="CMake">
|
|
||||||
<indentOptions>
|
|
||||||
<option name="INDENT_SIZE" value="2" />
|
|
||||||
<option name="CONTINUATION_INDENT_SIZE" value="0" />
|
|
||||||
<option name="TAB_SIZE" value="2" />
|
|
||||||
</indentOptions>
|
|
||||||
</codeStyleSettings>
|
|
||||||
</code_scheme>
|
|
||||||
</component>
|
|
5
.idea/codeStyles/codeStyleConfig.xml
generated
5
.idea/codeStyles/codeStyleConfig.xml
generated
@ -1,5 +0,0 @@
|
|||||||
<component name="ProjectCodeStyleConfiguration">
|
|
||||||
<state>
|
|
||||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
|
||||||
</state>
|
|
||||||
</component>
|
|
@ -29,9 +29,12 @@ 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.
|
- 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
|
||||||
@ -42,6 +45,8 @@ 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
|
## Added
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ option(FSFW_ADD_SGP4_PROPAGATOR "Add SGP4 propagator code" OFF)
|
|||||||
set(FSFW_TEST_TGT fsfw-tests)
|
set(FSFW_TEST_TGT fsfw-tests)
|
||||||
set(FSFW_DUMMY_TGT fsfw-dummy)
|
set(FSFW_DUMMY_TGT fsfw-dummy)
|
||||||
|
|
||||||
add_library(${LIB_FSFW_NAME})
|
add_library(${LIB_FSFW_NAME} src/fsfw/cfdp/handler/PduPacketIF.h)
|
||||||
|
|
||||||
if(IPO_SUPPORTED AND FSFW_ENABLE_IPO)
|
if(IPO_SUPPORTED AND FSFW_ENABLE_IPO)
|
||||||
set_property(TARGET ${LIB_FSFW_NAME} PROPERTY INTERPROCEDURAL_OPTIMIZATION
|
set_property(TARGET ${LIB_FSFW_NAME} PROPERTY INTERPROCEDURAL_OPTIMIZATION
|
||||||
@ -175,7 +175,10 @@ if(FSFW_BUILD_TESTS)
|
|||||||
configure_file(unittests/testcfg/TestsConfig.h.in tests/TestsConfig.h)
|
configure_file(unittests/testcfg/TestsConfig.h.in tests/TestsConfig.h)
|
||||||
|
|
||||||
project(${FSFW_TEST_TGT} CXX C)
|
project(${FSFW_TEST_TGT} CXX C)
|
||||||
add_executable(${FSFW_TEST_TGT})
|
add_executable(
|
||||||
|
${FSFW_TEST_TGT}
|
||||||
|
unittests/cfdp/PduSenderMock.cpp unittests/cfdp/PduSenderMock.h
|
||||||
|
unittests/cfdp/handler/OwnedPduPacket.h)
|
||||||
if(IPO_SUPPORTED AND FSFW_ENABLE_IPO)
|
if(IPO_SUPPORTED AND FSFW_ENABLE_IPO)
|
||||||
set_property(TARGET ${FSFW_TEST_TGT} PROPERTY INTERPROCEDURAL_OPTIMIZATION
|
set_property(TARGET ${FSFW_TEST_TGT} PROPERTY INTERPROCEDURAL_OPTIMIZATION
|
||||||
TRUE)
|
TRUE)
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "fsfw/cfdp/pdu/PduHeaderReader.h"
|
#include "fsfw/cfdp/pdu/HeaderReader.h"
|
||||||
#include "fsfw/returnvalues/returnvalue.h"
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
#include "fsfw/tcdistribution/CfdpPacketChecker.h"
|
#include "fsfw/tcdistribution/CfdpPacketChecker.h"
|
||||||
#include "fsfw/tcdistribution/TcDistributorBase.h"
|
#include "fsfw/tcdistribution/TcDistributorBase.h"
|
||||||
|
@ -38,6 +38,7 @@ static constexpr ReturnValue_t FILESTORE_REQUIRES_SECOND_FILE =
|
|||||||
static constexpr ReturnValue_t FILESTORE_RESPONSE_CANT_PARSE_FS_MESSAGE =
|
static constexpr ReturnValue_t FILESTORE_RESPONSE_CANT_PARSE_FS_MESSAGE =
|
||||||
returnvalue::makeCode(CFDP_CLASS_ID, 9);
|
returnvalue::makeCode(CFDP_CLASS_ID, 9);
|
||||||
static constexpr ReturnValue_t INVALID_PDU_FORMAT = returnvalue::makeCode(CFDP_CLASS_ID, 10);
|
static constexpr ReturnValue_t INVALID_PDU_FORMAT = returnvalue::makeCode(CFDP_CLASS_ID, 10);
|
||||||
|
static constexpr ReturnValue_t PDU_CHECKSUM_FAILURE = returnvalue::makeCode(CFDP_CLASS_ID, 11);
|
||||||
|
|
||||||
//! Checksum types according to the SANA Checksum Types registry
|
//! Checksum types according to the SANA Checksum Types registry
|
||||||
//! https://sanaregistry.org/r/checksum_identifiers/
|
//! https://sanaregistry.org/r/checksum_identifiers/
|
||||||
|
@ -8,14 +8,18 @@
|
|||||||
#include "fsfw/cfdp/pdu/EofPduReader.h"
|
#include "fsfw/cfdp/pdu/EofPduReader.h"
|
||||||
#include "fsfw/cfdp/pdu/FileDataReader.h"
|
#include "fsfw/cfdp/pdu/FileDataReader.h"
|
||||||
#include "fsfw/cfdp/pdu/FinishedPduCreator.h"
|
#include "fsfw/cfdp/pdu/FinishedPduCreator.h"
|
||||||
#include "fsfw/cfdp/pdu/PduHeaderReader.h"
|
#include "fsfw/cfdp/pdu/HeaderReader.h"
|
||||||
#include "fsfw/objectmanager.h"
|
#include "fsfw/objectmanager.h"
|
||||||
#include "fsfw/tmtcservices/TmTcMessage.h"
|
#include "fsfw/tmtcservices/TmTcMessage.h"
|
||||||
|
|
||||||
using namespace returnvalue;
|
using namespace returnvalue;
|
||||||
|
|
||||||
cfdp::DestHandler::DestHandler(DestHandlerParams params, FsfwParams fsfwParams)
|
cfdp::DestHandler::DestHandler(PduSenderIF& pduSender, size_t pduBufSize, DestHandlerParams params,
|
||||||
: tlvVec(params.maxTlvsInOnePdu),
|
FsfwParams fsfwParams)
|
||||||
|
|
||||||
|
: pduBuf(pduBufSize),
|
||||||
|
pduSender(pduSender),
|
||||||
|
tlvVec(params.maxTlvsInOnePdu),
|
||||||
msgToUserVec(params.maxTlvsInOnePdu),
|
msgToUserVec(params.maxTlvsInOnePdu),
|
||||||
transactionParams(params.maxFilenameLen),
|
transactionParams(params.maxFilenameLen),
|
||||||
destParams(std::move(params)),
|
destParams(std::move(params)),
|
||||||
@ -23,69 +27,55 @@ cfdp::DestHandler::DestHandler(DestHandlerParams params, FsfwParams fsfwParams)
|
|||||||
transactionParams.pduConf.direction = cfdp::Direction::TOWARDS_SENDER;
|
transactionParams.pduConf.direction = cfdp::Direction::TOWARDS_SENDER;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cfdp::DestHandler::FsmResult& cfdp::DestHandler::stateMachine() {
|
const cfdp::DestHandler::FsmResult& cfdp::DestHandler::stateMachineNoPacket() {
|
||||||
|
return stateMachine(std::nullopt);
|
||||||
|
}
|
||||||
|
const cfdp::DestHandler::FsmResult& cfdp::DestHandler::stateMachine(
|
||||||
|
const std::optional<std::reference_wrapper<PduPacketIF>> optPduPacket) {
|
||||||
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();
|
if (!optPduPacket.has_value()) {
|
||||||
infoIter != destParams.packetListRef.end();) {
|
return fsmRes;
|
||||||
if (infoIter->pduType == PduType::FILE_DIRECTIVE and
|
|
||||||
infoIter->directiveType == FileDirective::METADATA) {
|
|
||||||
result = handleMetadataPdu(*infoIter);
|
|
||||||
checkAndHandleError(result, errorIdx);
|
|
||||||
// Store data was deleted in PDU handler because a store guard is used
|
|
||||||
destParams.packetListRef.erase(infoIter++);
|
|
||||||
} else {
|
|
||||||
infoIter++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (fsmRes.step == TransactionStep::IDLE) {
|
PduPacketIF& pduPacket = *optPduPacket;
|
||||||
// To decrease the already high complexity of the software, all packets arriving before
|
if (pduPacket.getPduType() == FILE_DATA or
|
||||||
// a metadata PDU are deleted.
|
(pduPacket.getPduType() == FILE_DIRECTIVE and *pduPacket.getFileDirective() != METADATA)) {
|
||||||
for (auto infoIter = destParams.packetListRef.begin();
|
fsmRes.result = DEST_NON_METADATA_PDU_AS_FIRST_PDU;
|
||||||
infoIter != destParams.packetListRef.end();) {
|
return fsmRes;
|
||||||
fsfwParams.tcStore->deleteData(infoIter->storeId);
|
|
||||||
infoIter++;
|
|
||||||
}
|
|
||||||
destParams.packetListRef.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fsmRes.step != TransactionStep::IDLE) {
|
|
||||||
fsmRes.callStatus = CallStatus::CALL_AGAIN;
|
|
||||||
}
|
}
|
||||||
|
result = handleMetadataPdu(pduPacket);
|
||||||
|
checkAndHandleError(result, errorIdx);
|
||||||
return updateFsmRes(errorIdx);
|
return updateFsmRes(errorIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fsmRes.state == CfdpState::BUSY_CLASS_1_NACKED) {
|
if (fsmRes.state == CfdpState::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();
|
if (!optPduPacket.has_value()) {
|
||||||
infoIter != destParams.packetListRef.end();) {
|
return fsmRes;
|
||||||
if (infoIter->pduType == PduType::FILE_DATA) {
|
}
|
||||||
result = handleFileDataPdu(*infoIter);
|
PduPacketIF& pduPacket = *optPduPacket;
|
||||||
checkAndHandleError(result, errorIdx);
|
if (pduPacket.getPduType() == FILE_DATA) {
|
||||||
// Store data was deleted in PDU handler because a store guard is used
|
result = handleFileDataPdu(pduPacket);
|
||||||
destParams.packetListRef.erase(infoIter++);
|
checkAndHandleError(result, errorIdx);
|
||||||
} else if (infoIter->pduType == PduType::FILE_DIRECTIVE and
|
|
||||||
infoIter->directiveType == FileDirective::EOF_DIRECTIVE) {
|
} else if (pduPacket.getPduType() == FILE_DIRECTIVE and
|
||||||
// TODO: Support for check timer missing
|
*pduPacket.getFileDirective() == EOF_DIRECTIVE) {
|
||||||
result = handleEofPdu(*infoIter);
|
// TODO: Support for check timer missing
|
||||||
checkAndHandleError(result, errorIdx);
|
result = handleEofPdu(pduPacket);
|
||||||
// Store data was deleted in PDU handler because a store guard is used
|
checkAndHandleError(result, errorIdx);
|
||||||
destParams.packetListRef.erase(infoIter++);
|
|
||||||
} else {
|
|
||||||
infoIter++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fsmRes.step == TransactionStep::TRANSFER_COMPLETION) {
|
}
|
||||||
result = handleTransferCompletion();
|
if (fsmRes.step == TransactionStep::TRANSFER_COMPLETION) {
|
||||||
checkAndHandleError(result, errorIdx);
|
result = handleTransferCompletion();
|
||||||
}
|
checkAndHandleError(result, errorIdx);
|
||||||
if (fsmRes.step == TransactionStep::SENDING_FINISHED_PDU) {
|
}
|
||||||
result = sendFinishedPdu();
|
if (fsmRes.step == TransactionStep::SENDING_FINISHED_PDU) {
|
||||||
checkAndHandleError(result, errorIdx);
|
result = sendFinishedPdu();
|
||||||
finish();
|
checkAndHandleError(result, errorIdx);
|
||||||
}
|
finish();
|
||||||
return updateFsmRes(errorIdx);
|
return updateFsmRes(errorIdx);
|
||||||
}
|
}
|
||||||
if (fsmRes.state == CfdpState::BUSY_CLASS_2_ACKED) {
|
if (fsmRes.state == CfdpState::BUSY_CLASS_2_ACKED) {
|
||||||
@ -97,75 +87,37 @@ const cfdp::DestHandler::FsmResult& cfdp::DestHandler::stateMachine() {
|
|||||||
return updateFsmRes(errorIdx);
|
return updateFsmRes(errorIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t cfdp::DestHandler::passPacket(PacketInfo packet) {
|
ReturnValue_t cfdp::DestHandler::handleMetadataPdu(const PduPacketIF& pduPacket) {
|
||||||
if (destParams.packetListRef.full()) {
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
destParams.packetListRef.push_back(packet);
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t cfdp::DestHandler::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::DestHandler::handleMetadataPdu(const PacketInfo& info) {
|
|
||||||
// Process metadata PDU
|
// Process metadata PDU
|
||||||
auto constAccessorPair = fsfwParams.tcStore->getData(info.storeId);
|
|
||||||
if (constAccessorPair.first != OK) {
|
|
||||||
// TODO: This is not a CFDP error. Event and/or warning?
|
|
||||||
return constAccessorPair.first;
|
|
||||||
}
|
|
||||||
cfdp::StringLv sourceFileName;
|
cfdp::StringLv sourceFileName;
|
||||||
cfdp::StringLv destFileName;
|
cfdp::StringLv destFileName;
|
||||||
|
|
||||||
MetadataGenericInfo metadataInfo(transactionParams.fileSize);
|
MetadataGenericInfo metadataInfo(transactionParams.fileSize);
|
||||||
MetadataPduReader reader(constAccessorPair.second.data(), constAccessorPair.second.size(),
|
size_t pduSize = 0;
|
||||||
metadataInfo, tlvVec.data(), tlvVec.size());
|
auto rawPdu = pduPacket.getRawPduData(pduSize);
|
||||||
|
MetadataPduReader reader(rawPdu, pduSize, metadataInfo, tlvVec.data(), tlvVec.size());
|
||||||
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
|
||||||
// is translated into a warning and/or event by an upper layer
|
// is translated into a warning and/or event by an upper layer
|
||||||
if (result != OK) {
|
if (result != OK) {
|
||||||
return handleMetadataParseError(result, constAccessorPair.second.data(),
|
return handleMetadataParseError(result, rawPdu, pduSize);
|
||||||
constAccessorPair.second.size());
|
|
||||||
}
|
}
|
||||||
return startTransaction(reader);
|
return startTransaction(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t cfdp::DestHandler::handleFileDataPdu(const cfdp::PacketInfo& info) {
|
ReturnValue_t cfdp::DestHandler::handleFileDataPdu(const PduPacketIF& info) {
|
||||||
|
size_t pduSize = 0;
|
||||||
|
const auto rawPdu = info.getRawPduData(pduSize);
|
||||||
// Process file data PDU
|
// Process file data PDU
|
||||||
auto constAccessorPair = fsfwParams.tcStore->getData(info.storeId);
|
|
||||||
if (constAccessorPair.first != OK) {
|
|
||||||
// TODO: This is not a CFDP error. Event and/or warning?
|
|
||||||
return constAccessorPair.first;
|
|
||||||
}
|
|
||||||
FileDataInfo fdInfo;
|
FileDataInfo fdInfo;
|
||||||
FileDataReader reader(constAccessorPair.second.data(), constAccessorPair.second.size(), fdInfo);
|
FileDataReader reader(rawPdu, pduSize, fdInfo);
|
||||||
ReturnValue_t result = reader.parseData();
|
ReturnValue_t result = reader.parseData();
|
||||||
if (result != OK) {
|
if (result != OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
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.offset = fdInfo.getOffset().value();
|
|
||||||
if (destParams.cfg.indicCfg.fileSegmentRecvIndicRequired) {
|
if (destParams.cfg.indicCfg.fileSegmentRecvIndicRequired) {
|
||||||
FileSegmentRecvdParams segParams;
|
FileSegmentRecvdParams segParams;
|
||||||
segParams.offset = fdInfo.getOffset().value();
|
segParams.offset = fdInfo.getOffset().value();
|
||||||
@ -177,7 +129,9 @@ ReturnValue_t cfdp::DestHandler::handleFileDataPdu(const cfdp::PacketInfo& info)
|
|||||||
segParams.segmentMetadata = {segMetadata, segmentMetadatLen};
|
segParams.segmentMetadata = {segMetadata, segmentMetadatLen};
|
||||||
destParams.user.fileSegmentRecvdIndication(segParams);
|
destParams.user.fileSegmentRecvdIndication(segParams);
|
||||||
}
|
}
|
||||||
result = destParams.user.vfs.writeToFile(fileOpParams, fileData);
|
sif::printDebug("Writing %d bytes at offset %d\n", fileSegmentLen, fdInfo.getOffset().value());
|
||||||
|
result = destParams.user.vfs.writeToFile(transactionParams.destName.data(),
|
||||||
|
fdInfo.getOffset().value(), fileData, fileSegmentLen);
|
||||||
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
|
||||||
@ -191,25 +145,21 @@ ReturnValue_t cfdp::DestHandler::handleFileDataPdu(const cfdp::PacketInfo& info)
|
|||||||
static_cast<uint8_t>(fsmRes.step), result);
|
static_cast<uint8_t>(fsmRes.step), result);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
} else {
|
|
||||||
transactionParams.deliveryStatus = FileDeliveryStatus::RETAINED_IN_FILESTORE;
|
|
||||||
transactionParams.vfsErrorCount = 0;
|
|
||||||
}
|
}
|
||||||
|
transactionParams.deliveryStatus = FileDeliveryStatus::RETAINED_IN_FILESTORE;
|
||||||
|
transactionParams.vfsErrorCount = 0;
|
||||||
if (fdInfo.getOffset().value() + fileSegmentLen > transactionParams.progress) {
|
if (fdInfo.getOffset().value() + fileSegmentLen > transactionParams.progress) {
|
||||||
transactionParams.progress = fdInfo.getOffset().value() + fileSegmentLen;
|
transactionParams.progress = fdInfo.getOffset().value() + fileSegmentLen;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t cfdp::DestHandler::handleEofPdu(const cfdp::PacketInfo& info) {
|
ReturnValue_t cfdp::DestHandler::handleEofPdu(const cfdp::PduPacketIF& info) {
|
||||||
|
size_t pduSize = 0;
|
||||||
|
const auto rawPdu = info.getRawPduData(pduSize);
|
||||||
// Process EOF PDU
|
// Process EOF PDU
|
||||||
auto constAccessorPair = fsfwParams.tcStore->getData(info.storeId);
|
|
||||||
if (constAccessorPair.first != OK) {
|
|
||||||
// TODO: This is not a CFDP error. Event and/or warning?
|
|
||||||
return constAccessorPair.first;
|
|
||||||
}
|
|
||||||
EofInfo eofInfo(nullptr);
|
EofInfo eofInfo(nullptr);
|
||||||
EofPduReader reader(constAccessorPair.second.data(), constAccessorPair.second.size(), eofInfo);
|
EofPduReader reader(rawPdu, pduSize, eofInfo);
|
||||||
ReturnValue_t result = reader.parseData();
|
ReturnValue_t result = reader.parseData();
|
||||||
if (result != OK) {
|
if (result != OK) {
|
||||||
return result;
|
return result;
|
||||||
@ -244,6 +194,7 @@ ReturnValue_t cfdp::DestHandler::handleMetadataParseError(ReturnValue_t result,
|
|||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "Parsing Metadata PDU failed with code " << result << std::endl;
|
sif::warning << "Parsing Metadata PDU failed with code " << result << std::endl;
|
||||||
#else
|
#else
|
||||||
|
sif::printWarning("cfdp::DestHandler: parsing metadata PDU failed with code %04x\n", result);
|
||||||
#endif
|
#endif
|
||||||
PduHeaderReader headerReader(rawData, maxSize);
|
PduHeaderReader headerReader(rawData, maxSize);
|
||||||
result = headerReader.parseData();
|
result = headerReader.parseData();
|
||||||
@ -307,24 +258,26 @@ ReturnValue_t cfdp::DestHandler::startTransaction(const MetadataPduReader& reade
|
|||||||
// 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;
|
transactionParams.metadataOnly = false;
|
||||||
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())) {
|
bool isDirectory = false;
|
||||||
|
|
||||||
|
result = destParams.user.vfs.isDirectory(transactionParams.destName.data(), isDirectory);
|
||||||
|
if (result == returnvalue::OK && isDirectory) {
|
||||||
result = tryBuildingAbsoluteDestName(destNameSize);
|
result = tryBuildingAbsoluteDestName(destNameSize);
|
||||||
if (result != OK) {
|
if (result != OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (destParams.user.vfs.fileExists(fparams)) {
|
if (destParams.user.vfs.fileExists(transactionParams.destName.data())) {
|
||||||
result = destParams.user.vfs.truncateFile(fparams);
|
result = destParams.user.vfs.truncateFile(transactionParams.destName.data());
|
||||||
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 = destParams.user.vfs.createFile(transactionParams.destName.data());
|
||||||
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;
|
||||||
@ -359,6 +312,7 @@ ReturnValue_t cfdp::DestHandler::startTransaction(const MetadataPduReader& reade
|
|||||||
transactionParams.checksumType = info.getChecksumType();
|
transactionParams.checksumType = info.getChecksumType();
|
||||||
transactionParams.closureRequested = info.isClosureRequested();
|
transactionParams.closureRequested = info.isClosureRequested();
|
||||||
reader.fillConfig(transactionParams.pduConf);
|
reader.fillConfig(transactionParams.pduConf);
|
||||||
|
transactionParams.pduConf.crcFlag = transactionParams.remoteCfg->crcOnTransmission;
|
||||||
transactionParams.pduConf.direction = Direction::TOWARDS_SENDER;
|
transactionParams.pduConf.direction = Direction::TOWARDS_SENDER;
|
||||||
transactionParams.transactionId.entityId = transactionParams.pduConf.sourceId;
|
transactionParams.transactionId.entityId = transactionParams.pduConf.sourceId;
|
||||||
transactionParams.transactionId.seqNum = transactionParams.pduConf.seqNum;
|
transactionParams.transactionId.seqNum = transactionParams.pduConf.seqNum;
|
||||||
@ -368,10 +322,10 @@ ReturnValue_t cfdp::DestHandler::startTransaction(const MetadataPduReader& reade
|
|||||||
params.destFileName = transactionParams.destName.data();
|
params.destFileName = transactionParams.destName.data();
|
||||||
params.sourceFileName = transactionParams.sourceName.data();
|
params.sourceFileName = transactionParams.sourceName.data();
|
||||||
params.numberOfMsgsToUser = 0;
|
params.numberOfMsgsToUser = 0;
|
||||||
for (const auto& opt : tlvVec) {
|
for (uint32_t tlvIdx = 0; tlvIdx < reader.getNumberOfParsedOptions(); tlvIdx++) {
|
||||||
if (opt.getType() == TlvType::MSG_TO_USER) {
|
if (tlvVec[tlvIdx].getType() == TlvType::MSG_TO_USER) {
|
||||||
msgToUserVec[params.numberOfMsgsToUser] =
|
msgToUserVec[params.numberOfMsgsToUser] =
|
||||||
MessageToUserTlv(opt.getValue(), opt.getLengthField());
|
MessageToUserTlv(tlvVec[tlvIdx].getValue(), tlvVec[tlvIdx].getLengthField());
|
||||||
params.numberOfMsgsToUser++;
|
params.numberOfMsgsToUser++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -411,10 +365,9 @@ 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
|
// A path may only have a maximum of 256 characters in CFDP, so this buffer should be sufficient
|
||||||
// for all use-cases.
|
// for all use-cases.
|
||||||
char baseNameBuf[512]{};
|
char baseNameBuf[512]{};
|
||||||
FilesystemParams fparamsSrc(transactionParams.sourceName.data());
|
|
||||||
size_t baseNameLen = 0;
|
size_t baseNameLen = 0;
|
||||||
ReturnValue_t result = destParams.user.vfs.getBaseFilename(fparamsSrc, baseNameBuf,
|
const ReturnValue_t result = destParams.user.vfs.getBaseFilename(
|
||||||
sizeof(baseNameBuf), baseNameLen);
|
transactionParams.sourceName.data(), 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;
|
||||||
@ -442,7 +395,6 @@ void cfdp::DestHandler::fileErrorHandler(Event event, ReturnValue_t result,
|
|||||||
|
|
||||||
void cfdp::DestHandler::finish() {
|
void cfdp::DestHandler::finish() {
|
||||||
transactionParams.reset();
|
transactionParams.reset();
|
||||||
destParams.packetListRef.clear();
|
|
||||||
fsmRes.state = CfdpState::IDLE;
|
fsmRes.state = CfdpState::IDLE;
|
||||||
fsmRes.step = TransactionStep::IDLE;
|
fsmRes.step = TransactionStep::IDLE;
|
||||||
}
|
}
|
||||||
@ -451,26 +403,26 @@ ReturnValue_t cfdp::DestHandler::checksumVerification() {
|
|||||||
std::array<uint8_t, 1024> buf{};
|
std::array<uint8_t, 1024> buf{};
|
||||||
etl::crc32 crcCalc;
|
etl::crc32 crcCalc;
|
||||||
uint64_t currentOffset = 0;
|
uint64_t currentOffset = 0;
|
||||||
FileOpParams params(transactionParams.destName.data(), transactionParams.fileSize.value());
|
|
||||||
while (currentOffset < transactionParams.fileSize.value()) {
|
while (currentOffset < transactionParams.fileSize.value()) {
|
||||||
uint64_t readLen;
|
uint64_t lenToRead;
|
||||||
if (currentOffset + buf.size() > transactionParams.fileSize.value()) {
|
if (currentOffset + buf.size() > transactionParams.fileSize.value()) {
|
||||||
readLen = transactionParams.fileSize.value() - currentOffset;
|
lenToRead = transactionParams.fileSize.value() - currentOffset;
|
||||||
} else {
|
} else {
|
||||||
readLen = buf.size();
|
lenToRead = buf.size();
|
||||||
}
|
}
|
||||||
if (readLen > 0) {
|
if (lenToRead > 0) {
|
||||||
params.offset = currentOffset;
|
size_t readLen = 0;
|
||||||
params.size = readLen;
|
const auto result =
|
||||||
auto result = destParams.user.vfs.readFromFile(params, buf.data(), buf.size());
|
destParams.user.vfs.readFromFile(transactionParams.destName.data(), currentOffset,
|
||||||
|
lenToRead, buf.data(), readLen, 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
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
crcCalc.add(buf.begin(), buf.begin() + readLen);
|
crcCalc.add(buf.begin(), buf.begin() + lenToRead);
|
||||||
}
|
}
|
||||||
currentOffset += readLen;
|
currentOffset += lenToRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t value = crcCalc.value();
|
uint32_t value = crcCalc.value();
|
||||||
@ -502,19 +454,11 @@ ReturnValue_t cfdp::DestHandler::sendFinishedPdu() {
|
|||||||
FinishedInfo info(transactionParams.conditionCode, transactionParams.deliveryCode,
|
FinishedInfo info(transactionParams.conditionCode, transactionParams.deliveryCode,
|
||||||
transactionParams.deliveryStatus);
|
transactionParams.deliveryStatus);
|
||||||
FinishPduCreator finishedPdu(transactionParams.pduConf, info);
|
FinishPduCreator finishedPdu(transactionParams.pduConf, info);
|
||||||
store_address_t storeId;
|
|
||||||
uint8_t* dataPtr = nullptr;
|
|
||||||
ReturnValue_t result =
|
|
||||||
fsfwParams.tmStore->getFreeElement(&storeId, finishedPdu.getSerializedSize(), &dataPtr);
|
|
||||||
if (result != OK) {
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::warning << "cfdp::DestHandler:sendFinishedPdu: Getting store slot failed" << std::endl;
|
|
||||||
#endif
|
|
||||||
fsfwParams.eventReporter->forwardEvent(events::STORE_ERROR, result, 0);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
size_t serLen = 0;
|
size_t serLen = 0;
|
||||||
result = finishedPdu.serialize(dataPtr, serLen, finishedPdu.getSerializedSize());
|
ReturnValue_t result =
|
||||||
|
finishedPdu.serialize(pduBuf.data(), serLen, finishedPdu.getSerializedSize());
|
||||||
|
checkAndHandleError(result, fsmRes.errors);
|
||||||
if (result != OK) {
|
if (result != OK) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "cfdp::DestHandler::sendFinishedPdu: Serializing Finished PDU failed"
|
sif::warning << "cfdp::DestHandler::sendFinishedPdu: Serializing Finished PDU failed"
|
||||||
@ -523,13 +467,12 @@ ReturnValue_t cfdp::DestHandler::sendFinishedPdu() {
|
|||||||
fsfwParams.eventReporter->forwardEvent(events::SERIALIZATION_ERROR, result, 0);
|
fsfwParams.eventReporter->forwardEvent(events::SERIALIZATION_ERROR, result, 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
TmTcMessage msg(storeId);
|
pduSender.sendPdu(PduType::FILE_DIRECTIVE, FileDirective::FINISH, pduBuf.data(), serLen);
|
||||||
result = fsfwParams.msgQueue->sendMessage(fsfwParams.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);
|
fsfwParams.eventReporter->forwardEvent(events::PDU_SEND_ERROR, result, 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
fsmRes.packetsSent++;
|
fsmRes.packetsSent++;
|
||||||
@ -560,15 +503,10 @@ void cfdp::DestHandler::checkAndHandleError(ReturnValue_t result, uint8_t& error
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cfdp::DestHandler::setMsgQueue(MessageQueueIF& queue) { fsfwParams.msgQueue = &queue; }
|
|
||||||
|
|
||||||
void cfdp::DestHandler::setEventReporter(EventReportingProxyIF& reporter) {
|
void cfdp::DestHandler::setEventReporter(EventReportingProxyIF& reporter) {
|
||||||
fsfwParams.eventReporter = &reporter;
|
fsfwParams.eventReporter = &reporter;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cfdp::DestHandlerParams& cfdp::DestHandler::getDestHandlerParams() const {
|
const cfdp::DestHandlerParams& cfdp::DestHandler::getDestHandlerParams() const {
|
||||||
return destParams;
|
return destParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
StorageManagerIF* cfdp::DestHandler::getTmStore() const { return fsfwParams.tmStore; }
|
|
||||||
StorageManagerIF* cfdp::DestHandler::getTcStore() const { return fsfwParams.tcStore; }
|
|
@ -11,13 +11,13 @@
|
|||||||
#include "RemoteConfigTableIF.h"
|
#include "RemoteConfigTableIF.h"
|
||||||
#include "UserBase.h"
|
#include "UserBase.h"
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
#include "fsfw/cfdp/handler/PduPacketIF.h"
|
||||||
|
#include "fsfw/cfdp/handler/PduSenderIF.h"
|
||||||
#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/cfdp/tlv/MessageToUserTlv.h"
|
||||||
#include "fsfw/container/DynamicFIFO.h"
|
|
||||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||||
#include "fsfw/storagemanager/storeAddress.h"
|
|
||||||
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
|
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
|
||||||
|
|
||||||
namespace cfdp {
|
namespace cfdp {
|
||||||
@ -28,30 +28,34 @@ using LostSegmentsListBase = etl::iset<etl::pair<uint64_t, uint64_t>>;
|
|||||||
|
|
||||||
struct DestHandlerParams {
|
struct DestHandlerParams {
|
||||||
DestHandlerParams(LocalEntityCfg cfg, UserBase& user, RemoteConfigTableIF& remoteCfgTable,
|
DestHandlerParams(LocalEntityCfg cfg, UserBase& user, RemoteConfigTableIF& remoteCfgTable,
|
||||||
PacketInfoListBase& packetList,
|
// 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
|
||||||
// TODO: Actually, we can provide a better abstraction via interface, which
|
// allows using something like a bounded map. This simplifies
|
||||||
// allows using something like a bounded map. This simplifies
|
// the implementation significantly.
|
||||||
// the implementation significantly.
|
|
||||||
LostSegmentsListBase& lostSegmentsContainer)
|
LostSegmentsListBase& lostSegmentsContainer)
|
||||||
: cfg(std::move(cfg)),
|
: cfg(std::move(cfg)),
|
||||||
user(user),
|
user(user),
|
||||||
remoteCfgTable(remoteCfgTable),
|
remoteCfgTable(remoteCfgTable),
|
||||||
packetListRef(packetList),
|
|
||||||
lostSegmentsContainer(lostSegmentsContainer) {}
|
lostSegmentsContainer(lostSegmentsContainer) {}
|
||||||
|
|
||||||
LocalEntityCfg cfg;
|
LocalEntityCfg cfg;
|
||||||
UserBase& user;
|
UserBase& user;
|
||||||
RemoteConfigTableIF& remoteCfgTable;
|
RemoteConfigTableIF& remoteCfgTable;
|
||||||
|
|
||||||
PacketInfoListBase& packetListRef;
|
|
||||||
LostSegmentsListBase& lostSegmentsContainer;
|
LostSegmentsListBase& lostSegmentsContainer;
|
||||||
uint8_t maxTlvsInOnePdu = 20;
|
uint8_t maxTlvsInOnePdu = 20;
|
||||||
size_t maxFilenameLen = 255;
|
size_t maxFilenameLen = 255;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PacketInfo {
|
||||||
|
const uint8_t* rawPdu = nullptr;
|
||||||
|
size_t pduSize = 0;
|
||||||
|
PduType pduType = PduType::FILE_DATA;
|
||||||
|
std::optional<FileDirective> directiveType = FileDirective::INVALID_DIRECTIVE;
|
||||||
|
};
|
||||||
|
|
||||||
class DestHandler {
|
class DestHandler {
|
||||||
public:
|
public:
|
||||||
enum class TransactionStep : uint8_t {
|
enum class TransactionStep : uint8_t {
|
||||||
@ -64,17 +68,14 @@ class DestHandler {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct FsmResult {
|
struct FsmResult {
|
||||||
public:
|
uint32_t packetsSent = 0;
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
CallStatus callStatus = CallStatus::CALL_AFTER_DELAY;
|
|
||||||
TransactionStep step = TransactionStep::IDLE;
|
TransactionStep step = TransactionStep::IDLE;
|
||||||
CfdpState state = CfdpState::IDLE;
|
CfdpState state = CfdpState::IDLE;
|
||||||
uint32_t packetsSent = 0;
|
|
||||||
uint8_t errors = 0;
|
uint8_t errors = 0;
|
||||||
std::array<ReturnValue_t, 3> errorCodes = {};
|
std::array<ReturnValue_t, 3> errorCodes = {};
|
||||||
void resetOfIteration() {
|
void resetOfIteration() {
|
||||||
result = returnvalue::OK;
|
result = returnvalue::OK;
|
||||||
callStatus = CallStatus::CALL_AFTER_DELAY;
|
|
||||||
packetsSent = 0;
|
packetsSent = 0;
|
||||||
errors = 0;
|
errors = 0;
|
||||||
errorCodes.fill(returnvalue::OK);
|
errorCodes.fill(returnvalue::OK);
|
||||||
@ -85,28 +86,30 @@ class DestHandler {
|
|||||||
*/
|
*/
|
||||||
ReturnValue_t PARTIAL_SUCCESS = returnvalue::makeCode(0, 2);
|
ReturnValue_t PARTIAL_SUCCESS = returnvalue::makeCode(0, 2);
|
||||||
ReturnValue_t FAILURE = returnvalue::makeCode(0, 3);
|
ReturnValue_t FAILURE = returnvalue::makeCode(0, 3);
|
||||||
explicit DestHandler(DestHandlerParams handlerParams, FsfwParams fsfwParams);
|
|
||||||
|
explicit DestHandler(PduSenderIF& pduSender, size_t pduBufSize, DestHandlerParams handlerParams,
|
||||||
|
FsfwParams fsfwParams);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* This is the core function to drive the destination handler. It is also used to insert
|
||||||
|
* packets into the destination handler.
|
||||||
*
|
*
|
||||||
* @return
|
* The state machine should either be called if packets with the appropriate destination ID
|
||||||
* - @c returnvalue::OK State machine OK for this execution cycle
|
* are received and periodically to perform all CFDP related tasks, for example
|
||||||
* - @c CALL_FSM_AGAIN State machine should be called again.
|
* checking for timeouts or missed file segments.
|
||||||
|
*
|
||||||
|
* The function returns the number of sent PDU packets on success.
|
||||||
*/
|
*/
|
||||||
const FsmResult& stateMachine();
|
const FsmResult& stateMachine(std::optional<std::reference_wrapper<PduPacketIF>> optPduPacket);
|
||||||
void setMsgQueue(MessageQueueIF& queue);
|
|
||||||
|
const FsmResult& stateMachineNoPacket();
|
||||||
|
|
||||||
void setEventReporter(EventReportingProxyIF& reporter);
|
void setEventReporter(EventReportingProxyIF& reporter);
|
||||||
|
|
||||||
ReturnValue_t passPacket(PacketInfo packet);
|
|
||||||
|
|
||||||
ReturnValue_t initialize();
|
|
||||||
|
|
||||||
[[nodiscard]] CfdpState getCfdpState() const;
|
[[nodiscard]] CfdpState 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;
|
||||||
[[nodiscard]] StorageManagerIF* getTcStore() const;
|
|
||||||
[[nodiscard]] StorageManagerIF* getTmStore() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct TransactionParams {
|
struct TransactionParams {
|
||||||
@ -149,6 +152,8 @@ class DestHandler {
|
|||||||
RemoteEntityCfg* remoteCfg = nullptr;
|
RemoteEntityCfg* remoteCfg = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::vector<uint8_t> pduBuf;
|
||||||
|
PduSenderIF& pduSender;
|
||||||
std::vector<cfdp::Tlv> tlvVec;
|
std::vector<cfdp::Tlv> tlvVec;
|
||||||
std::vector<MessageToUserTlv> msgToUserVec;
|
std::vector<MessageToUserTlv> msgToUserVec;
|
||||||
TransactionParams transactionParams;
|
TransactionParams transactionParams;
|
||||||
@ -157,9 +162,9 @@ class DestHandler {
|
|||||||
FsmResult fsmRes;
|
FsmResult fsmRes;
|
||||||
|
|
||||||
ReturnValue_t startTransaction(const MetadataPduReader& reader);
|
ReturnValue_t startTransaction(const MetadataPduReader& reader);
|
||||||
ReturnValue_t handleMetadataPdu(const PacketInfo& info);
|
ReturnValue_t handleMetadataPdu(const PduPacketIF& pduPacket);
|
||||||
ReturnValue_t handleFileDataPdu(const PacketInfo& info);
|
ReturnValue_t handleFileDataPdu(const PduPacketIF& info);
|
||||||
ReturnValue_t handleEofPdu(const PacketInfo& info);
|
ReturnValue_t handleEofPdu(const PduPacketIF& info);
|
||||||
ReturnValue_t handleMetadataParseError(ReturnValue_t result, const uint8_t* rawData,
|
ReturnValue_t handleMetadataParseError(ReturnValue_t result, const uint8_t* rawData,
|
||||||
size_t maxSize);
|
size_t maxSize);
|
||||||
ReturnValue_t handleTransferCompletion();
|
ReturnValue_t handleTransferCompletion();
|
||||||
|
18
src/fsfw/cfdp/handler/PduPacketIF.h
Normal file
18
src/fsfw/cfdp/handler/PduPacketIF.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include "fsfw/cfdp/definitions.h"
|
||||||
|
|
||||||
|
namespace cfdp {
|
||||||
|
|
||||||
|
class PduPacketIF {
|
||||||
|
public:
|
||||||
|
virtual ~PduPacketIF() = default;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual cfdp::PduType getPduType() const = 0;
|
||||||
|
[[nodiscard]] virtual std::optional<cfdp::FileDirective> getFileDirective() const = 0;
|
||||||
|
[[nodiscard]] virtual const uint8_t* getRawPduData(size_t& pduLen) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace cfdp
|
17
src/fsfw/cfdp/handler/PduSenderIF.h
Normal file
17
src/fsfw/cfdp/handler/PduSenderIF.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include "fsfw/cfdp/definitions.h"
|
||||||
|
|
||||||
|
namespace cfdp {
|
||||||
|
class PduSenderIF {
|
||||||
|
public:
|
||||||
|
virtual ~PduSenderIF() = default;
|
||||||
|
|
||||||
|
virtual ReturnValue_t sendPdu(cfdp::PduType pduType,
|
||||||
|
std::optional<cfdp::FileDirective> fileDirective,
|
||||||
|
const uint8_t* pdu, size_t pduSize) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace cfdp
|
@ -14,7 +14,7 @@ cfdp::ReservedMessageParser::ReservedMessageParser(StorageManagerIF& ipcStore,
|
|||||||
: msgQueue(msgQueue), ipcStore(ipcStore), userDestination(userDestination) {}
|
: msgQueue(msgQueue), ipcStore(ipcStore), userDestination(userDestination) {}
|
||||||
|
|
||||||
ReturnValue_t cfdp::ReservedMessageParser::parse(const MessageToUserTlv* msgsToUserArray,
|
ReturnValue_t cfdp::ReservedMessageParser::parse(const MessageToUserTlv* msgsToUserArray,
|
||||||
size_t numMsgToUser) {
|
size_t numMsgToUser) const {
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
cfdp::StringLv sourceFileName;
|
cfdp::StringLv sourceFileName;
|
||||||
cfdp::StringLv destFileName;
|
cfdp::StringLv destFileName;
|
||||||
@ -23,31 +23,28 @@ ReturnValue_t cfdp::ReservedMessageParser::parse(const MessageToUserTlv* msgsToU
|
|||||||
size_t deserSize = 0;
|
size_t deserSize = 0;
|
||||||
bool needToSendPutRequest = false;
|
bool needToSendPutRequest = false;
|
||||||
for (size_t idx = 0; idx < numMsgToUser; idx++) {
|
for (size_t idx = 0; idx < numMsgToUser; idx++) {
|
||||||
if (&msgsToUserArray[idx] == nullptr) {
|
uint8_t messageType = 0;
|
||||||
|
if (not msgsToUserArray[idx].isReservedCfdpMessage(messageType, ¤tPtr, deserSize)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
uint8_t messageType = 0;
|
if (messageType == static_cast<uint8_t>(ProxyOpMessageType::PUT_REQUEST)) {
|
||||||
if (msgsToUserArray[idx].isReservedCfdpMessage(messageType, ¤tPtr, deserSize)) {
|
EntityId entityIdLv;
|
||||||
if (messageType == static_cast<uint8_t>(ProxyOpMessageType::PUT_REQUEST)) {
|
result = entityIdLv.deSerializeFromLv(¤tPtr, &deserSize);
|
||||||
EntityId entityIdLv;
|
if (result != returnvalue::OK) {
|
||||||
result = entityIdLv.deSerializeFromLv(¤tPtr, &deserSize);
|
return result;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
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) {
|
if (needToSendPutRequest) {
|
||||||
@ -71,4 +68,4 @@ ReturnValue_t cfdp::ReservedMessageParser::parse(const MessageToUserTlv* msgsToU
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
@ -16,7 +16,7 @@ class ReservedMessageParser {
|
|||||||
ReservedMessageParser(StorageManagerIF& ipcStore, MessageQueueIF& msgQueue,
|
ReservedMessageParser(StorageManagerIF& ipcStore, MessageQueueIF& msgQueue,
|
||||||
MessageQueueId_t userDestination);
|
MessageQueueId_t userDestination);
|
||||||
|
|
||||||
ReturnValue_t parse(const MessageToUserTlv* msgsToUserArray, size_t numMsgsToUser);
|
ReturnValue_t parse(const MessageToUserTlv* msgsToUserArray, size_t numMsgsToUser) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MessageQueueIF& msgQueue;
|
MessageQueueIF& msgQueue;
|
||||||
|
@ -16,8 +16,12 @@
|
|||||||
|
|
||||||
using namespace returnvalue;
|
using namespace returnvalue;
|
||||||
|
|
||||||
cfdp::SourceHandler::SourceHandler(SourceHandlerParams params, FsfwParams fsfwParams)
|
cfdp::SourceHandler::SourceHandler(PduSenderIF& pduSender, size_t pduBufferSize,
|
||||||
: sourceParams(std::move(params)), fsfwParams(fsfwParams) {
|
SourceHandlerParams params, FsfwParams fsfwParams)
|
||||||
|
: pduSender(pduSender),
|
||||||
|
pduBuf(pduBufferSize),
|
||||||
|
sourceParams(std::move(params)),
|
||||||
|
fsfwParams(fsfwParams) {
|
||||||
// The entity ID portion of the transaction ID will always remain fixed.
|
// The entity ID portion of the transaction ID will always remain fixed.
|
||||||
transactionParams.id.entityId = sourceParams.cfg.localId;
|
transactionParams.id.entityId = sourceParams.cfg.localId;
|
||||||
transactionParams.pduConf.sourceId = sourceParams.cfg.localId;
|
transactionParams.pduConf.sourceId = sourceParams.cfg.localId;
|
||||||
@ -61,14 +65,14 @@ cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() {
|
|||||||
if (result != OK) {
|
if (result != OK) {
|
||||||
addError(result);
|
addError(result);
|
||||||
}
|
}
|
||||||
fsmResult.callStatus = CallStatus::CALL_AGAIN;
|
// fsmResult.callStatus = CallStatus::CALL_AGAIN;
|
||||||
return fsmResult;
|
return fsmResult;
|
||||||
}
|
}
|
||||||
if (step == TransactionStep::SENDING_FILE_DATA) {
|
if (step == TransactionStep::SENDING_FILE_DATA) {
|
||||||
bool noFdPdu = false;
|
bool noFdPdu = false;
|
||||||
result = prepareAndSendNextFileDataPdu(noFdPdu);
|
result = prepareAndSendNextFileDataPdu(noFdPdu);
|
||||||
if (result == OK and !noFdPdu) {
|
if (result == OK and !noFdPdu) {
|
||||||
fsmResult.callStatus = CallStatus::CALL_AGAIN;
|
// fsmResult.callStatus = CallStatus::CALL_AGAIN;
|
||||||
return fsmResult;
|
return fsmResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,10 +86,10 @@ cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() {
|
|||||||
}
|
}
|
||||||
if (transactionParams.closureRequested) {
|
if (transactionParams.closureRequested) {
|
||||||
step = TransactionStep::WAIT_FOR_FINISH;
|
step = TransactionStep::WAIT_FOR_FINISH;
|
||||||
fsmResult.callStatus = CallStatus::CALL_AFTER_DELAY;
|
// fsmResult.callStatus = CallStatus::CALL_AFTER_DELAY;
|
||||||
} else {
|
} else {
|
||||||
step = TransactionStep::NOTICE_OF_COMPLETION;
|
step = TransactionStep::NOTICE_OF_COMPLETION;
|
||||||
fsmResult.callStatus = CallStatus::CALL_AGAIN;
|
// fsmResult.callStatus = CallStatus::CALL_AGAIN;
|
||||||
}
|
}
|
||||||
return fsmResult;
|
return fsmResult;
|
||||||
}
|
}
|
||||||
@ -104,7 +108,7 @@ cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() {
|
|||||||
const cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::stateMachine() {
|
const cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::stateMachine() {
|
||||||
fsmResult.packetsSent = 0;
|
fsmResult.packetsSent = 0;
|
||||||
fsmResult.errors = 0;
|
fsmResult.errors = 0;
|
||||||
fsmResult.callStatus = CallStatus::DONE;
|
// fsmResult.callStatus = CallStatus::DONE;
|
||||||
if (state == cfdp::CfdpState::IDLE) {
|
if (state == cfdp::CfdpState::IDLE) {
|
||||||
return fsmResult;
|
return fsmResult;
|
||||||
}
|
}
|
||||||
@ -123,25 +127,25 @@ ReturnValue_t cfdp::SourceHandler::checksumGeneration() {
|
|||||||
std::array<uint8_t, 1024> buf{};
|
std::array<uint8_t, 1024> buf{};
|
||||||
etl::crc32 crcCalc;
|
etl::crc32 crcCalc;
|
||||||
uint64_t currentOffset = 0;
|
uint64_t currentOffset = 0;
|
||||||
FileOpParams params(transactionParams.sourceName.data(), transactionParams.fileSize.value());
|
|
||||||
while (currentOffset < transactionParams.fileSize.value()) {
|
while (currentOffset < transactionParams.fileSize.value()) {
|
||||||
uint64_t readLen;
|
uint64_t lenToRead;
|
||||||
if (currentOffset + buf.size() > transactionParams.fileSize.value()) {
|
if (currentOffset + buf.size() > transactionParams.fileSize.value()) {
|
||||||
readLen = transactionParams.fileSize.value() - currentOffset;
|
lenToRead = transactionParams.fileSize.value() - currentOffset;
|
||||||
} else {
|
} else {
|
||||||
readLen = buf.size();
|
lenToRead = buf.size();
|
||||||
}
|
}
|
||||||
if (readLen > 0) {
|
if (lenToRead > 0) {
|
||||||
params.offset = currentOffset;
|
size_t readLen = 0;
|
||||||
params.size = readLen;
|
auto result =
|
||||||
auto result = sourceParams.user.vfs.readFromFile(params, buf.data(), buf.size());
|
sourceParams.user.vfs.readFromFile(transactionParams.sourceName.data(), currentOffset,
|
||||||
|
lenToRead, buf.data(), readLen, buf.size());
|
||||||
if (result != OK) {
|
if (result != OK) {
|
||||||
addError(result);
|
addError(result);
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
crcCalc.add(buf.begin(), buf.begin() + readLen);
|
crcCalc.add(buf.begin(), buf.begin() + lenToRead);
|
||||||
}
|
}
|
||||||
currentOffset += readLen;
|
currentOffset += lenToRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
transactionParams.crc = crcCalc.value();
|
transactionParams.crc = crcCalc.value();
|
||||||
@ -169,8 +173,7 @@ ReturnValue_t cfdp::SourceHandler::transactionStart(PutRequest& putRequest, Remo
|
|||||||
// operation is safe.
|
// operation is safe.
|
||||||
transactionParams.sourceName[transactionParams.sourceNameSize] = '\0';
|
transactionParams.sourceName[transactionParams.sourceNameSize] = '\0';
|
||||||
transactionParams.destName[transactionParams.destNameSize] = '\0';
|
transactionParams.destName[transactionParams.destNameSize] = '\0';
|
||||||
FilesystemParams params(transactionParams.sourceName.data());
|
if (!sourceParams.user.vfs.fileExists(transactionParams.sourceName.data())) {
|
||||||
if (!sourceParams.user.vfs.fileExists(params)) {
|
|
||||||
return FILE_DOES_NOT_EXIST;
|
return FILE_DOES_NOT_EXIST;
|
||||||
}
|
}
|
||||||
if (cfg.maxFileSegmentLen > fileBuf.size() or cfg.maxFileSegmentLen == 0) {
|
if (cfg.maxFileSegmentLen > fileBuf.size() or cfg.maxFileSegmentLen == 0) {
|
||||||
@ -206,7 +209,7 @@ ReturnValue_t cfdp::SourceHandler::transactionStart(PutRequest& putRequest, Remo
|
|||||||
}
|
}
|
||||||
step = TransactionStep::IDLE;
|
step = TransactionStep::IDLE;
|
||||||
uint64_t fileSize = 0;
|
uint64_t fileSize = 0;
|
||||||
sourceParams.user.vfs.getFileSize(params, fileSize);
|
sourceParams.user.vfs.getFileSize(transactionParams.sourceName.data(), fileSize);
|
||||||
transactionParams.pduConf.largeFile = false;
|
transactionParams.pduConf.largeFile = false;
|
||||||
if (fileSize > UINT32_MAX) {
|
if (fileSize > UINT32_MAX) {
|
||||||
transactionParams.pduConf.largeFile = true;
|
transactionParams.pduConf.largeFile = true;
|
||||||
@ -230,7 +233,8 @@ ReturnValue_t cfdp::SourceHandler::prepareAndSendMetadataPdu() {
|
|||||||
transactionParams.fileSize);
|
transactionParams.fileSize);
|
||||||
auto metadataPdu =
|
auto metadataPdu =
|
||||||
MetadataPduCreator(transactionParams.pduConf, metadataInfo, sourceName, destName, nullptr, 0);
|
MetadataPduCreator(transactionParams.pduConf, metadataInfo, sourceName, destName, nullptr, 0);
|
||||||
ReturnValue_t result = sendGenericPdu(metadataPdu);
|
ReturnValue_t result =
|
||||||
|
sendGenericPdu(PduType::FILE_DIRECTIVE, FileDirective::METADATA, metadataPdu);
|
||||||
if (result != OK) {
|
if (result != OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -241,7 +245,7 @@ ReturnValue_t cfdp::SourceHandler::prepareAndSendMetadataPdu() {
|
|||||||
|
|
||||||
ReturnValue_t cfdp::SourceHandler::prepareAndSendNextFileDataPdu(bool& noFileDataPdu) {
|
ReturnValue_t cfdp::SourceHandler::prepareAndSendNextFileDataPdu(bool& noFileDataPdu) {
|
||||||
cfdp::Fss offset(transactionParams.progress);
|
cfdp::Fss offset(transactionParams.progress);
|
||||||
uint64_t readLen;
|
uint64_t lenToRead;
|
||||||
uint64_t fileSize = transactionParams.fileSize.value();
|
uint64_t fileSize = transactionParams.fileSize.value();
|
||||||
noFileDataPdu = false;
|
noFileDataPdu = false;
|
||||||
if (fileSize == 0) {
|
if (fileSize == 0) {
|
||||||
@ -251,29 +255,31 @@ ReturnValue_t cfdp::SourceHandler::prepareAndSendNextFileDataPdu(bool& noFileDat
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
if (fileSize < transactionParams.remoteCfg.maxFileSegmentLen) {
|
if (fileSize < transactionParams.remoteCfg.maxFileSegmentLen) {
|
||||||
readLen = transactionParams.fileSize.value();
|
lenToRead = transactionParams.fileSize.value();
|
||||||
} else {
|
} else {
|
||||||
if (transactionParams.progress + transactionParams.remoteCfg.maxFileSegmentLen > fileSize) {
|
if (transactionParams.progress + transactionParams.remoteCfg.maxFileSegmentLen > fileSize) {
|
||||||
readLen = fileSize - transactionParams.progress;
|
lenToRead = fileSize - transactionParams.progress;
|
||||||
} else {
|
} else {
|
||||||
readLen = transactionParams.remoteCfg.maxFileSegmentLen;
|
lenToRead = transactionParams.remoteCfg.maxFileSegmentLen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FileOpParams fileParams(transactionParams.sourceName.data(), readLen);
|
FileOpParams fileParams(transactionParams.sourceName.data(), lenToRead);
|
||||||
fileParams.offset = transactionParams.progress;
|
fileParams.offset = transactionParams.progress;
|
||||||
ReturnValue_t result =
|
size_t readLen = 0;
|
||||||
sourceParams.user.vfs.readFromFile(fileParams, fileBuf.data(), fileBuf.size());
|
ReturnValue_t result = sourceParams.user.vfs.readFromFile(
|
||||||
|
transactionParams.sourceName.data(), transactionParams.progress, lenToRead, fileBuf.data(),
|
||||||
|
readLen, fileBuf.size());
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
addError(result);
|
addError(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
auto fileDataInfo = FileDataInfo(offset, fileBuf.data(), readLen);
|
auto fileDataInfo = FileDataInfo(offset, fileBuf.data(), lenToRead);
|
||||||
auto fileDataPdu = FileDataCreator(transactionParams.pduConf, fileDataInfo);
|
auto fileDataPdu = FileDataCreator(transactionParams.pduConf, fileDataInfo);
|
||||||
result = sendGenericPdu(fileDataPdu);
|
result = sendGenericPdu(PduType::FILE_DATA, std::nullopt, fileDataPdu);
|
||||||
if (result != OK) {
|
if (result != OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
transactionParams.progress += readLen;
|
transactionParams.progress += lenToRead;
|
||||||
if (transactionParams.progress >= fileSize) {
|
if (transactionParams.progress >= fileSize) {
|
||||||
// Advance FSM after all file data PDUs were sent.
|
// Advance FSM after all file data PDUs were sent.
|
||||||
step = TransactionStep::SENDING_EOF;
|
step = TransactionStep::SENDING_EOF;
|
||||||
@ -285,72 +291,44 @@ ReturnValue_t cfdp::SourceHandler::prepareAndSendEofPdu() {
|
|||||||
auto eofInfo =
|
auto eofInfo =
|
||||||
EofInfo(ConditionCode::NO_ERROR, transactionParams.crc, transactionParams.fileSize);
|
EofInfo(ConditionCode::NO_ERROR, transactionParams.crc, transactionParams.fileSize);
|
||||||
auto eofPdu = EofPduCreator(transactionParams.pduConf, eofInfo);
|
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 =
|
ReturnValue_t result =
|
||||||
fsfwParams.tmStore->getFreeElement(&storeId, pdu.getSerializedSize(), &dataPtr);
|
sendGenericPdu(PduType::FILE_DIRECTIVE, FileDirective::EOF_DIRECTIVE, eofPdu);
|
||||||
if (result != OK) {
|
if (result != OK) {
|
||||||
addError(result);
|
|
||||||
fsmResult.callStatus = CallStatus::CALL_AFTER_DELAY;
|
|
||||||
if (result == StorageManagerIF::DATA_STORAGE_FULL) {
|
|
||||||
return TM_STORE_FULL;
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t cfdp::SourceHandler::initialize() { return OK; }
|
||||||
|
|
||||||
|
ReturnValue_t cfdp::SourceHandler::sendGenericPdu(PduType pduType,
|
||||||
|
std::optional<FileDirective> fileDirective,
|
||||||
|
const SerializeIF& pdu) {
|
||||||
|
store_address_t storeId;
|
||||||
|
if (pdu.getSerializedSize() > pduBuf.size()) {
|
||||||
|
addError(PDU_BUFFER_TOO_SMALL);
|
||||||
|
return PDU_BUFFER_TOO_SMALL;
|
||||||
|
}
|
||||||
size_t serializedLen = 0;
|
size_t serializedLen = 0;
|
||||||
result = pdu.serializeBe(dataPtr, serializedLen, pdu.getSerializedSize());
|
ReturnValue_t result = pdu.serializeBe(pduBuf.data(), serializedLen, pdu.getSerializedSize());
|
||||||
if (result != OK) {
|
if (result != OK) {
|
||||||
addError(result);
|
addError(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
TmTcMessage tmMsg(storeId);
|
pduSender.sendPdu(pduType, fileDirective, pduBuf.data(), serializedLen);
|
||||||
result =
|
fsmResult.packetsSent += 1;
|
||||||
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t cfdp::SourceHandler::noticeOfCompletion() {
|
ReturnValue_t cfdp::SourceHandler::noticeOfCompletion() {
|
||||||
if (sourceParams.cfg.indicCfg.transactionFinishedIndicRequired) {
|
if (sourceParams.cfg.indicCfg.transactionFinishedIndicRequired) {
|
||||||
|
// TODO: This could still be improved by caching the Finished PDU parameters.
|
||||||
|
FileDeliveryStatus deliveryStatus = FileDeliveryStatus::FILE_STATUS_UNREPORTED;
|
||||||
|
if (transactionParams.closureRequested) {
|
||||||
|
deliveryStatus = FileDeliveryStatus::RETAINED_IN_FILESTORE;
|
||||||
|
}
|
||||||
cfdp::TransactionFinishedParams params(transactionParams.id, ConditionCode::NO_ERROR,
|
cfdp::TransactionFinishedParams params(transactionParams.id, ConditionCode::NO_ERROR,
|
||||||
FileDeliveryCode::DATA_COMPLETE,
|
FileDeliveryCode::DATA_COMPLETE, deliveryStatus);
|
||||||
FileDeliveryStatus::RETAINED_IN_FILESTORE);
|
|
||||||
sourceParams.user.transactionFinishedIndication(params);
|
sourceParams.user.transactionFinishedIndication(params);
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
@ -359,7 +337,7 @@ ReturnValue_t cfdp::SourceHandler::noticeOfCompletion() {
|
|||||||
ReturnValue_t cfdp::SourceHandler::reset() {
|
ReturnValue_t cfdp::SourceHandler::reset() {
|
||||||
step = TransactionStep::IDLE;
|
step = TransactionStep::IDLE;
|
||||||
state = cfdp::CfdpState::IDLE;
|
state = cfdp::CfdpState::IDLE;
|
||||||
fsmResult.callStatus = CallStatus::DONE;
|
// fsmResult.callStatus = CallStatus::DONE;
|
||||||
transactionParams.reset();
|
transactionParams.reset();
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "PduSenderIF.h"
|
||||||
#include "UserBase.h"
|
#include "UserBase.h"
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
#include "fsfw/cfdp/Fss.h"
|
#include "fsfw/cfdp/Fss.h"
|
||||||
@ -40,14 +41,15 @@ class SourceHandler {
|
|||||||
struct FsmResult {
|
struct FsmResult {
|
||||||
public:
|
public:
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
CallStatus callStatus = CallStatus::CALL_AFTER_DELAY;
|
|
||||||
CfdpState state = CfdpState::IDLE;
|
|
||||||
uint32_t packetsSent = 0;
|
uint32_t packetsSent = 0;
|
||||||
|
// CallStatus callStatus = CallStatus::CALL_AFTER_DELAY;
|
||||||
|
CfdpState state = CfdpState::IDLE;
|
||||||
uint8_t errors = 0;
|
uint8_t errors = 0;
|
||||||
std::array<ReturnValue_t, 3> errorCodes = {};
|
std::array<ReturnValue_t, 3> errorCodes = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
SourceHandler(SourceHandlerParams params, FsfwParams fsfwParams);
|
SourceHandler(PduSenderIF& pduSender, size_t pduBufferSize, SourceHandlerParams params,
|
||||||
|
FsfwParams fsfwParams);
|
||||||
|
|
||||||
[[nodiscard]] CfdpState getState() const;
|
[[nodiscard]] CfdpState getState() const;
|
||||||
[[nodiscard]] TransactionStep getStep() const;
|
[[nodiscard]] TransactionStep getStep() const;
|
||||||
@ -86,6 +88,8 @@ class SourceHandler {
|
|||||||
}
|
}
|
||||||
} transactionParams;
|
} transactionParams;
|
||||||
|
|
||||||
|
PduSenderIF& pduSender;
|
||||||
|
std::vector<uint8_t> pduBuf;
|
||||||
cfdp::CfdpState state = cfdp::CfdpState::IDLE;
|
cfdp::CfdpState state = cfdp::CfdpState::IDLE;
|
||||||
TransactionStep step = TransactionStep::IDLE;
|
TransactionStep step = TransactionStep::IDLE;
|
||||||
std::array<uint8_t, 4096> fileBuf{};
|
std::array<uint8_t, 4096> fileBuf{};
|
||||||
@ -101,7 +105,9 @@ class SourceHandler {
|
|||||||
ReturnValue_t noticeOfCompletion();
|
ReturnValue_t noticeOfCompletion();
|
||||||
ReturnValue_t reset();
|
ReturnValue_t reset();
|
||||||
|
|
||||||
[[nodiscard]] ReturnValue_t sendGenericPdu(const SerializeIF& pdu);
|
[[nodiscard]] ReturnValue_t sendGenericPdu(PduType pduType,
|
||||||
|
std::optional<FileDirective> fileDirective,
|
||||||
|
const SerializeIF& pdu);
|
||||||
void addError(ReturnValue_t error);
|
void addError(ReturnValue_t error);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#ifndef FSFW_CFDP_HANDLER_DEFS_H
|
#pragma once
|
||||||
#define FSFW_CFDP_HANDLER_DEFS_H
|
|
||||||
|
|
||||||
#include <etl/list.h>
|
#include <etl/list.h>
|
||||||
|
|
||||||
@ -8,59 +7,25 @@
|
|||||||
#include "fsfw/tmtcservices/AcceptsTelemetryIF.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 CfdpState { 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;
|
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 {
|
struct FsfwParams {
|
||||||
FsfwParams(AcceptsTelemetryIF& packetDest, MessageQueueIF* msgQueue,
|
FsfwParams(EventReportingProxyIF* eventReporter) : eventReporter(eventReporter) {}
|
||||||
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;
|
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 {
|
||||||
|
static constexpr Event PDU_SEND_ERROR = event::makeEvent(SSID, 1, severity::LOW);
|
||||||
static constexpr Event STORE_ERROR = event::makeEvent(SSID, 0, severity::LOW);
|
|
||||||
static constexpr Event MSG_QUEUE_ERROR = event::makeEvent(SSID, 1, severity::LOW);
|
|
||||||
static constexpr Event SERIALIZATION_ERROR = event::makeEvent(SSID, 2, severity::LOW);
|
static constexpr Event SERIALIZATION_ERROR = event::makeEvent(SSID, 2, severity::LOW);
|
||||||
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.
|
//! [EXPORT] : [COMMENT] CFDP request handling failed. P2: Returncode.
|
||||||
static constexpr Event HANDLING_CFDP_REQUEST_FAILED = event::makeEvent(SSID, 5, severity::LOW);
|
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 SOURCE_TRANSACTION_PENDING = returnvalue::makeCode(CID, 0);
|
||||||
@ -71,6 +36,6 @@ 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 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 TARGET_MSG_QUEUE_FULL = returnvalue::makeCode(CID, 6);
|
||||||
static constexpr ReturnValue_t TM_STORE_FULL = returnvalue::makeCode(CID, 7);
|
static constexpr ReturnValue_t TM_STORE_FULL = returnvalue::makeCode(CID, 7);
|
||||||
|
static constexpr ReturnValue_t DEST_NON_METADATA_PDU_AS_FIRST_PDU = returnvalue::makeCode(CID, 8);
|
||||||
} // namespace cfdp
|
static constexpr ReturnValue_t PDU_BUFFER_TOO_SMALL = returnvalue::makeCode(CID, 9);
|
||||||
#endif // FSFW_CFDP_HANDLER_DEFS_H
|
} // namespace cfdp
|
@ -1,5 +1,7 @@
|
|||||||
#include "AckPduCreator.h"
|
#include "AckPduCreator.h"
|
||||||
|
|
||||||
|
#include "fsfw/globalfunctions/CRC.h"
|
||||||
|
|
||||||
AckPduCreator::AckPduCreator(AckInfo &ackInfo, PduConfig &pduConf)
|
AckPduCreator::AckPduCreator(AckInfo &ackInfo, PduConfig &pduConf)
|
||||||
: FileDirectiveCreator(pduConf, cfdp::FileDirective::ACK, 2), ackInfo(ackInfo) {}
|
: FileDirectiveCreator(pduConf, cfdp::FileDirective::ACK, 2), ackInfo(ackInfo) {}
|
||||||
|
|
||||||
@ -7,6 +9,7 @@ size_t AckPduCreator::getSerializedSize() const { return FileDirectiveCreator::g
|
|||||||
|
|
||||||
ReturnValue_t AckPduCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
ReturnValue_t AckPduCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||||
Endianness streamEndianness) const {
|
Endianness streamEndianness) const {
|
||||||
|
const uint8_t *start = *buffer;
|
||||||
ReturnValue_t result = FileDirectiveCreator::serialize(buffer, size, maxSize, streamEndianness);
|
ReturnValue_t result = FileDirectiveCreator::serialize(buffer, size, maxSize, streamEndianness);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
@ -29,5 +32,10 @@ ReturnValue_t AckPduCreator::serialize(uint8_t **buffer, size_t *size, size_t ma
|
|||||||
**buffer = ackedConditionCode << 4 | transactionStatus;
|
**buffer = ackedConditionCode << 4 | transactionStatus;
|
||||||
*buffer += 1;
|
*buffer += 1;
|
||||||
*size += 1;
|
*size += 1;
|
||||||
|
|
||||||
|
if (getCrcFlag()) {
|
||||||
|
uint16_t crc = CRC::crc16ccitt(start, getWholePduSize() - 2);
|
||||||
|
result = SerializeAdapter::serialize(&crc, buffer, size, maxSize, streamEndianness);
|
||||||
|
}
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "EofPduCreator.h"
|
#include "EofPduCreator.h"
|
||||||
|
|
||||||
#include "fsfw/FSFW.h"
|
#include "fsfw/FSFW.h"
|
||||||
|
#include "fsfw/globalfunctions/CRC.h"
|
||||||
|
|
||||||
EofPduCreator::EofPduCreator(PduConfig &conf, EofInfo &info)
|
EofPduCreator::EofPduCreator(PduConfig &conf, EofInfo &info)
|
||||||
: FileDirectiveCreator(conf, cfdp::FileDirective::EOF_DIRECTIVE, 9), info(info) {
|
: FileDirectiveCreator(conf, cfdp::FileDirective::EOF_DIRECTIVE, 9), info(info) {
|
||||||
@ -11,6 +12,7 @@ size_t EofPduCreator::getSerializedSize() const { return FileDirectiveCreator::g
|
|||||||
|
|
||||||
ReturnValue_t EofPduCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
ReturnValue_t EofPduCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||||
Endianness streamEndianness) const {
|
Endianness streamEndianness) const {
|
||||||
|
const uint8_t *start = *buffer;
|
||||||
ReturnValue_t result = FileDirectiveCreator::serialize(buffer, size, maxSize, streamEndianness);
|
ReturnValue_t result = FileDirectiveCreator::serialize(buffer, size, maxSize, streamEndianness);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
@ -36,5 +38,9 @@ ReturnValue_t EofPduCreator::serialize(uint8_t **buffer, size_t *size, size_t ma
|
|||||||
if (info.getFaultLoc() != nullptr and info.getConditionCode() != cfdp::ConditionCode::NO_ERROR) {
|
if (info.getFaultLoc() != nullptr and info.getConditionCode() != cfdp::ConditionCode::NO_ERROR) {
|
||||||
result = info.getFaultLoc()->serialize(buffer, size, maxSize, streamEndianness);
|
result = info.getFaultLoc()->serialize(buffer, size, maxSize, streamEndianness);
|
||||||
}
|
}
|
||||||
|
if (getCrcFlag()) {
|
||||||
|
uint16_t crc = CRC::crc16ccitt(start, getWholePduSize() - 2);
|
||||||
|
result = SerializeAdapter::serialize(&crc, buffer, size, maxSize, streamEndianness);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "fsfw/globalfunctions/CRC.h"
|
||||||
|
|
||||||
FileDataCreator::FileDataCreator(PduConfig& conf, FileDataInfo& info)
|
FileDataCreator::FileDataCreator(PduConfig& conf, FileDataInfo& info)
|
||||||
: HeaderCreator(conf, cfdp::PduType::FILE_DATA, 0, info.getSegmentMetadataFlag()), info(info) {
|
: HeaderCreator(conf, cfdp::PduType::FILE_DATA, 0, info.getSegmentMetadataFlag()), info(info) {
|
||||||
update();
|
update();
|
||||||
@ -18,6 +20,7 @@ ReturnValue_t FileDataCreator::serialize(uint8_t** buffer, size_t* size, size_t
|
|||||||
if (buffer == nullptr or size == nullptr) {
|
if (buffer == nullptr or size == nullptr) {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
const uint8_t* start = *buffer;
|
||||||
if (*size + getSerializedSize() > maxSize) {
|
if (*size + getSerializedSize() > maxSize) {
|
||||||
return SerializeIF::BUFFER_TOO_SHORT;
|
return SerializeIF::BUFFER_TOO_SHORT;
|
||||||
}
|
}
|
||||||
@ -50,6 +53,11 @@ ReturnValue_t FileDataCreator::serialize(uint8_t** buffer, size_t* size, size_t
|
|||||||
std::memcpy(*buffer, readOnlyPtr, fileSize);
|
std::memcpy(*buffer, readOnlyPtr, fileSize);
|
||||||
*buffer += fileSize;
|
*buffer += fileSize;
|
||||||
*size += fileSize;
|
*size += fileSize;
|
||||||
|
|
||||||
|
if (getCrcFlag()) {
|
||||||
|
uint16_t crc = CRC::crc16ccitt(start, getWholePduSize() - 2);
|
||||||
|
result = SerializeAdapter::serialize(&crc, buffer, size, maxSize, streamEndianness);
|
||||||
|
}
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,9 @@ ReturnValue_t FileDataReader::parseData() {
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
if (not performCrcCheckIfApplicable()) {
|
||||||
|
return cfdp::PDU_CHECKSUM_FAILURE;
|
||||||
|
}
|
||||||
size_t currentIdx = PduHeaderReader::getHeaderSize();
|
size_t currentIdx = PduHeaderReader::getHeaderSize();
|
||||||
const uint8_t* buf = pointers.rawPtr + currentIdx;
|
const uint8_t* buf = pointers.rawPtr + currentIdx;
|
||||||
size_t remSize = PduHeaderReader::getWholePduSize() - currentIdx;
|
size_t remSize = PduHeaderReader::getWholePduSize() - currentIdx;
|
||||||
@ -34,6 +37,9 @@ ReturnValue_t FileDataReader::parseData() {
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
if (getCrcFlag()) {
|
||||||
|
remSize -= 2;
|
||||||
|
}
|
||||||
if (remSize > 0) {
|
if (remSize > 0) {
|
||||||
info.setFileData(buf, remSize);
|
info.setFileData(buf, remSize);
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "../definitions.h"
|
#include "../definitions.h"
|
||||||
#include "FileDataInfo.h"
|
#include "FileDataInfo.h"
|
||||||
#include "PduHeaderReader.h"
|
#include "HeaderReader.h"
|
||||||
|
|
||||||
class FileDataReader : public PduHeaderReader {
|
class FileDataReader : public PduHeaderReader {
|
||||||
public:
|
public:
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include "FileDirectiveReader.h"
|
#include "FileDirectiveReader.h"
|
||||||
|
|
||||||
|
#include "fsfw/globalfunctions/CRC.h"
|
||||||
|
|
||||||
FileDirectiveReader::FileDirectiveReader(const uint8_t *pduBuf, size_t maxSize)
|
FileDirectiveReader::FileDirectiveReader(const uint8_t *pduBuf, size_t maxSize)
|
||||||
: PduHeaderReader(pduBuf, maxSize) {}
|
: PduHeaderReader(pduBuf, maxSize) {}
|
||||||
|
|
||||||
@ -10,6 +12,10 @@ ReturnValue_t FileDirectiveReader::parseData() {
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
if (not performCrcCheckIfApplicable()) {
|
||||||
|
return cfdp::PDU_CHECKSUM_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
if (this->getPduDataFieldLen() < 1) {
|
if (this->getPduDataFieldLen() < 1) {
|
||||||
return cfdp::INVALID_PDU_DATAFIELD_LEN;
|
return cfdp::INVALID_PDU_DATAFIELD_LEN;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define FSFW_SRC_FSFW_CFDP_PDU_FILEDIRECTIVEDESERIALIZER_H_
|
#define FSFW_SRC_FSFW_CFDP_PDU_FILEDIRECTIVEDESERIALIZER_H_
|
||||||
|
|
||||||
#include "../definitions.h"
|
#include "../definitions.h"
|
||||||
#include "fsfw/cfdp/pdu/PduHeaderReader.h"
|
#include "fsfw/cfdp/pdu/HeaderReader.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This class is used to deserialize a PDU file directive header from raw memory.
|
* @brief This class is used to deserialize a PDU file directive header from raw memory.
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include "FinishedPduCreator.h"
|
#include "FinishedPduCreator.h"
|
||||||
|
|
||||||
|
#include "fsfw/globalfunctions/CRC.h"
|
||||||
|
|
||||||
FinishPduCreator::FinishPduCreator(PduConfig &conf, FinishedInfo &finishInfo)
|
FinishPduCreator::FinishPduCreator(PduConfig &conf, FinishedInfo &finishInfo)
|
||||||
: FileDirectiveCreator(conf, cfdp::FileDirective::FINISH, 0), finishInfo(finishInfo) {
|
: FileDirectiveCreator(conf, cfdp::FileDirective::FINISH, 0), finishInfo(finishInfo) {
|
||||||
updateDirectiveFieldLen();
|
updateDirectiveFieldLen();
|
||||||
@ -13,6 +15,7 @@ void FinishPduCreator::updateDirectiveFieldLen() {
|
|||||||
|
|
||||||
ReturnValue_t FinishPduCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
ReturnValue_t FinishPduCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||||
Endianness streamEndianness) const {
|
Endianness streamEndianness) const {
|
||||||
|
const uint8_t *start = *buffer;
|
||||||
ReturnValue_t result = FileDirectiveCreator::serialize(buffer, size, maxSize, streamEndianness);
|
ReturnValue_t result = FileDirectiveCreator::serialize(buffer, size, maxSize, streamEndianness);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
@ -40,5 +43,9 @@ ReturnValue_t FinishPduCreator::serialize(uint8_t **buffer, size_t *size, size_t
|
|||||||
if (finishInfo.getFaultLocation(&entityId) == returnvalue::OK) {
|
if (finishInfo.getFaultLocation(&entityId) == returnvalue::OK) {
|
||||||
result = entityId->serialize(buffer, size, maxSize, streamEndianness);
|
result = entityId->serialize(buffer, size, maxSize, streamEndianness);
|
||||||
}
|
}
|
||||||
|
if (getCrcFlag()) {
|
||||||
|
uint16_t crc = CRC::crc16ccitt(start, getWholePduSize() - 2);
|
||||||
|
result = SerializeAdapter::serialize(&crc, buffer, size, maxSize, streamEndianness);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
|
#include "HeaderReader.h"
|
||||||
|
|
||||||
#include <fsfw/serialize/SerializeAdapter.h>
|
#include <fsfw/serialize/SerializeAdapter.h>
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "PduHeaderReader.h"
|
#include "fsfw/globalfunctions/CRC.h"
|
||||||
|
|
||||||
PduHeaderReader::PduHeaderReader(const uint8_t *pduBuf, size_t maxSize) {
|
PduHeaderReader::PduHeaderReader(const uint8_t *pduBuf, size_t maxSize) {
|
||||||
setReadOnlyData(pduBuf, maxSize);
|
setReadOnlyData(pduBuf, maxSize);
|
||||||
@ -17,28 +19,29 @@ ReturnValue_t PduHeaderReader::parseData() {
|
|||||||
}
|
}
|
||||||
pointers.fixedHeader =
|
pointers.fixedHeader =
|
||||||
reinterpret_cast<PduHeaderFixedStruct *>(const_cast<uint8_t *>(pointers.rawPtr));
|
reinterpret_cast<PduHeaderFixedStruct *>(const_cast<uint8_t *>(pointers.rawPtr));
|
||||||
sourceIdRaw = static_cast<uint8_t *>(&pointers.fixedHeader->variableFieldsStart);
|
sourceIdRaw = &pointers.fixedHeader->variableFieldsStart;
|
||||||
cfdp::WidthInBytes widthEntityIds = getLenEntityIds();
|
cfdp::WidthInBytes widthEntityIds = getLenEntityIds();
|
||||||
cfdp::WidthInBytes widthSeqNum = getLenSeqNum();
|
cfdp::WidthInBytes widthSeqNum = getLenSeqNum();
|
||||||
seqNumRaw = static_cast<uint8_t *>(sourceIdRaw) + static_cast<uint8_t>(widthEntityIds);
|
seqNumRaw = static_cast<uint8_t *>(sourceIdRaw) + static_cast<uint8_t>(widthEntityIds);
|
||||||
destIdRaw = static_cast<uint8_t *>(seqNumRaw) + static_cast<uint8_t>(widthSeqNum);
|
destIdRaw = static_cast<uint8_t *>(seqNumRaw) + static_cast<uint8_t>(widthSeqNum);
|
||||||
if (getWholePduSize() > PduHeaderReader::getHeaderSize()) {
|
if (getWholePduSize() > PduHeaderReader::getHeaderSize()) {
|
||||||
pointers.dataFieldStart = reinterpret_cast<const uint8_t *>(destIdRaw) + widthEntityIds;
|
pointers.dataFieldStart = static_cast<const uint8_t *>(destIdRaw) + widthEntityIds;
|
||||||
} else {
|
} else {
|
||||||
pointers.dataFieldStart = nullptr;
|
pointers.dataFieldStart = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PduHeaderReader::setData(uint8_t *dataPtr, size_t maxSize_, void *args) {
|
ReturnValue_t PduHeaderReader::setData(uint8_t *dataPtr, size_t maxSize, void *args) {
|
||||||
if (dataPtr == nullptr) {
|
if (dataPtr == nullptr) {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
if (maxSize_ < 7) {
|
if (maxSize < 7) {
|
||||||
return SerializeIF::STREAM_TOO_SHORT;
|
return SerializeIF::STREAM_TOO_SHORT;
|
||||||
}
|
}
|
||||||
pointers.rawPtr = dataPtr;
|
pointers.rawPtr = dataPtr;
|
||||||
maxSize = maxSize_;
|
this->maxSize = maxSize;
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,3 +169,12 @@ void PduHeaderReader::fillConfig(PduConfig &cfg) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t *PduHeaderReader::getPduDataField() const { return pointers.dataFieldStart; }
|
const uint8_t *PduHeaderReader::getPduDataField() const { return pointers.dataFieldStart; }
|
||||||
|
|
||||||
|
bool PduHeaderReader::performCrcCheckIfApplicable() const {
|
||||||
|
if (getCrcFlag()) {
|
||||||
|
if (CRC::crc16ccitt(pointers.rawPtr, getWholePduSize()) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -71,6 +71,11 @@ class PduHeaderReader : public RedirectableDataPointerIF, public PduHeaderIF {
|
|||||||
void getDestId(cfdp::EntityId& destId) const override;
|
void getDestId(cfdp::EntityId& destId) const override;
|
||||||
void getTransactionSeqNum(cfdp::TransactionSeqNum& seqNum) const override;
|
void getTransactionSeqNum(cfdp::TransactionSeqNum& seqNum) const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the CRC check on the whole PDU if the CRC flag is set.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] bool performCrcCheckIfApplicable() const;
|
||||||
|
|
||||||
ReturnValue_t deserResult = returnvalue::OK;
|
ReturnValue_t deserResult = returnvalue::OK;
|
||||||
|
|
||||||
[[nodiscard]] size_t getMaxSize() const;
|
[[nodiscard]] size_t getMaxSize() const;
|
@ -1,5 +1,7 @@
|
|||||||
#include "KeepAlivePduCreator.h"
|
#include "KeepAlivePduCreator.h"
|
||||||
|
|
||||||
|
#include "fsfw/globalfunctions/CRC.h"
|
||||||
|
|
||||||
KeepAlivePduCreator::KeepAlivePduCreator(PduConfig &conf, cfdp::Fss &progress)
|
KeepAlivePduCreator::KeepAlivePduCreator(PduConfig &conf, cfdp::Fss &progress)
|
||||||
: FileDirectiveCreator(conf, cfdp::FileDirective::KEEP_ALIVE, 4), progress(progress) {
|
: FileDirectiveCreator(conf, cfdp::FileDirective::KEEP_ALIVE, 4), progress(progress) {
|
||||||
updateDirectiveFieldLen();
|
updateDirectiveFieldLen();
|
||||||
@ -17,9 +19,18 @@ void KeepAlivePduCreator::updateDirectiveFieldLen() {
|
|||||||
|
|
||||||
ReturnValue_t KeepAlivePduCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
ReturnValue_t KeepAlivePduCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||||
Endianness streamEndianness) const {
|
Endianness streamEndianness) const {
|
||||||
|
const uint8_t *start = *buffer;
|
||||||
ReturnValue_t result = FileDirectiveCreator::serialize(buffer, size, maxSize, streamEndianness);
|
ReturnValue_t result = FileDirectiveCreator::serialize(buffer, size, maxSize, streamEndianness);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return progress.serialize(this->getLargeFileFlag(), buffer, size, maxSize, streamEndianness);
|
result = progress.serialize(this->getLargeFileFlag(), buffer, size, maxSize, streamEndianness);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (getCrcFlag()) {
|
||||||
|
uint16_t crc = CRC::crc16ccitt(start, getWholePduSize() - 2);
|
||||||
|
result = SerializeAdapter::serialize(&crc, buffer, size, maxSize, streamEndianness);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include "MetadataPduCreator.h"
|
#include "MetadataPduCreator.h"
|
||||||
|
|
||||||
|
#include "fsfw/globalfunctions/CRC.h"
|
||||||
|
|
||||||
MetadataPduCreator::MetadataPduCreator(PduConfig &conf, MetadataGenericInfo &info,
|
MetadataPduCreator::MetadataPduCreator(PduConfig &conf, MetadataGenericInfo &info,
|
||||||
cfdp::StringLv &srcFileName, cfdp::StringLv &destFileName,
|
cfdp::StringLv &srcFileName, cfdp::StringLv &destFileName,
|
||||||
cfdp::Tlv **optionsArray, size_t optionsLen)
|
cfdp::Tlv **optionsArray, size_t optionsLen)
|
||||||
@ -29,6 +31,7 @@ size_t MetadataPduCreator::getSerializedSize() const {
|
|||||||
|
|
||||||
ReturnValue_t MetadataPduCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
ReturnValue_t MetadataPduCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||||
Endianness streamEndianness) const {
|
Endianness streamEndianness) const {
|
||||||
|
const uint8_t *start = *buffer;
|
||||||
ReturnValue_t result = FileDirectiveCreator::serialize(buffer, size, maxSize, streamEndianness);
|
ReturnValue_t result = FileDirectiveCreator::serialize(buffer, size, maxSize, streamEndianness);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
@ -60,6 +63,11 @@ ReturnValue_t MetadataPduCreator::serialize(uint8_t **buffer, size_t *size, size
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (getCrcFlag()) {
|
||||||
|
uint16_t crc = CRC::crc16ccitt(start, getWholePduSize() - 2);
|
||||||
|
result = SerializeAdapter::serialize(&crc, buffer, size, maxSize, streamEndianness);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
const cfdp::StringLv &MetadataPduCreator::getSourceFileName() const { return srcFileName; }
|
const cfdp::StringLv &MetadataPduCreator::getSourceFileName() const { return srcFileName; }
|
||||||
|
@ -38,6 +38,10 @@ ReturnValue_t MetadataPduReader::parseData() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (getCrcFlag() && remSize == 2) {
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
if (remSize > 0) {
|
if (remSize > 0) {
|
||||||
if (optionArrayMaxSize == 0 or optionArray == nullptr) {
|
if (optionArrayMaxSize == 0 or optionArray == nullptr) {
|
||||||
return cfdp::METADATA_CANT_PARSE_OPTIONS;
|
return cfdp::METADATA_CANT_PARSE_OPTIONS;
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include "NakPduCreator.h"
|
#include "NakPduCreator.h"
|
||||||
|
|
||||||
|
#include "fsfw/globalfunctions/CRC.h"
|
||||||
|
|
||||||
NakPduCreator::NakPduCreator(PduConfig &pduConf, NakInfo &nakInfo)
|
NakPduCreator::NakPduCreator(PduConfig &pduConf, NakInfo &nakInfo)
|
||||||
: FileDirectiveCreator(pduConf, cfdp::FileDirective::NAK, 0), nakInfo(nakInfo) {
|
: FileDirectiveCreator(pduConf, cfdp::FileDirective::NAK, 0), nakInfo(nakInfo) {
|
||||||
updateDirectiveFieldLen();
|
updateDirectiveFieldLen();
|
||||||
@ -13,6 +15,7 @@ size_t NakPduCreator::getSerializedSize() const { return FileDirectiveCreator::g
|
|||||||
|
|
||||||
ReturnValue_t NakPduCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
ReturnValue_t NakPduCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||||
Endianness streamEndianness) const {
|
Endianness streamEndianness) const {
|
||||||
|
const uint8_t *start = *buffer;
|
||||||
ReturnValue_t result = FileDirectiveCreator::serialize(buffer, size, maxSize, streamEndianness);
|
ReturnValue_t result = FileDirectiveCreator::serialize(buffer, size, maxSize, streamEndianness);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
@ -40,5 +43,9 @@ ReturnValue_t NakPduCreator::serialize(uint8_t **buffer, size_t *size, size_t ma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (getCrcFlag()) {
|
||||||
|
uint16_t crc = CRC::crc16ccitt(start, getWholePduSize() - 2);
|
||||||
|
result = SerializeAdapter::serialize(&crc, buffer, size, maxSize, streamEndianness);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include "PromptPduCreator.h"
|
#include "PromptPduCreator.h"
|
||||||
|
|
||||||
|
#include "fsfw/globalfunctions/CRC.h"
|
||||||
|
|
||||||
PromptPduCreator::PromptPduCreator(PduConfig &conf, cfdp::PromptResponseRequired responseRequired)
|
PromptPduCreator::PromptPduCreator(PduConfig &conf, cfdp::PromptResponseRequired responseRequired)
|
||||||
: FileDirectiveCreator(conf, cfdp::FileDirective::PROMPT, 1),
|
: FileDirectiveCreator(conf, cfdp::FileDirective::PROMPT, 1),
|
||||||
responseRequired(responseRequired) {}
|
responseRequired(responseRequired) {}
|
||||||
@ -10,6 +12,7 @@ size_t PromptPduCreator::getSerializedSize() const {
|
|||||||
|
|
||||||
ReturnValue_t PromptPduCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
ReturnValue_t PromptPduCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||||
Endianness streamEndianness) const {
|
Endianness streamEndianness) const {
|
||||||
|
const uint8_t *start = *buffer;
|
||||||
ReturnValue_t result = FileDirectiveCreator::serialize(buffer, size, maxSize, streamEndianness);
|
ReturnValue_t result = FileDirectiveCreator::serialize(buffer, size, maxSize, streamEndianness);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
@ -20,5 +23,10 @@ ReturnValue_t PromptPduCreator::serialize(uint8_t **buffer, size_t *size, size_t
|
|||||||
**buffer = responseRequired << 7;
|
**buffer = responseRequired << 7;
|
||||||
*buffer += 1;
|
*buffer += 1;
|
||||||
*size += 1;
|
*size += 1;
|
||||||
|
|
||||||
|
if (getCrcFlag()) {
|
||||||
|
uint16_t crc = CRC::crc16ccitt(start, getWholePduSize() - 2);
|
||||||
|
result = SerializeAdapter::serialize(&crc, buffer, size, maxSize, streamEndianness);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -66,9 +66,9 @@ static constexpr uint8_t FSR_DENY_DIR_NOT_ALLOWED = 0b0010;
|
|||||||
|
|
||||||
class FilestoreTlvBase : public TlvIF {
|
class FilestoreTlvBase : public TlvIF {
|
||||||
public:
|
public:
|
||||||
explicit FilestoreTlvBase(cfdp::StringLv& firstFileName) : firstFileName(firstFileName){};
|
explicit FilestoreTlvBase(cfdp::StringLv& firstFileName) : firstFileName(firstFileName) {};
|
||||||
FilestoreTlvBase(FilestoreActionCode actionCode, cfdp::StringLv& firstFileName)
|
FilestoreTlvBase(FilestoreActionCode actionCode, cfdp::StringLv& firstFileName)
|
||||||
: actionCode(actionCode), firstFileName(firstFileName){};
|
: actionCode(actionCode), firstFileName(firstFileName) {};
|
||||||
|
|
||||||
ReturnValue_t commonSerialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
ReturnValue_t commonSerialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||||
Endianness streamEndianness, bool isResponse = false,
|
Endianness streamEndianness, bool isResponse = false,
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
class TlvIF : public SerializeIF {
|
class TlvIF : public SerializeIF {
|
||||||
public:
|
public:
|
||||||
virtual ~TlvIF(){};
|
virtual ~TlvIF() {};
|
||||||
|
|
||||||
virtual uint8_t getLengthField() const = 0;
|
virtual uint8_t getLengthField() const = 0;
|
||||||
virtual cfdp::TlvType getType() const = 0;
|
virtual cfdp::TlvType getType() const = 0;
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#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) {
|
||||||
@ -97,7 +99,16 @@ void CoordinateTransformations::ecfToEci(const double* ecfCoordinates, double* e
|
|||||||
|
|
||||||
double CoordinateTransformations::getJuleanCenturiesTT(timeval timeUTC) {
|
double CoordinateTransformations::getJuleanCenturiesTT(timeval timeUTC) {
|
||||||
timeval timeTT;
|
timeval timeTT;
|
||||||
Clock::convertUTCToTT(timeUTC, &timeTT);
|
ReturnValue_t result = 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);
|
||||||
|
|
||||||
@ -207,3 +218,61 @@ 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,6 +23,12 @@ 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,
|
||||||
|
@ -29,7 +29,7 @@ class Jgm3Model {
|
|||||||
lastExecutionTime.tv_sec = 0;
|
lastExecutionTime.tv_sec = 0;
|
||||||
lastExecutionTime.tv_usec = 0;
|
lastExecutionTime.tv_usec = 0;
|
||||||
}
|
}
|
||||||
virtual ~Jgm3Model(){};
|
virtual ~Jgm3Model() {};
|
||||||
|
|
||||||
// double acsNavOrbit(double posECF[3],double velECF[3],timeval gpsTime);
|
// double acsNavOrbit(double posECF[3],double velECF[3],timeval gpsTime);
|
||||||
|
|
||||||
@ -70,10 +70,10 @@ class Jgm3Model {
|
|||||||
W[n][m] = W[n][m] - (((n + m - 1) / (double)(n - m)) *
|
W[n][m] = W[n][m] - (((n + m - 1) / (double)(n - m)) *
|
||||||
(pow(Earth::MEAN_RADIUS, 2) / pow(r, 2)) * W[n - 2][m]);
|
(pow(Earth::MEAN_RADIUS, 2) / pow(r, 2)) * W[n - 2][m]);
|
||||||
} // End of if(n!=(m+1))
|
} // End of if(n!=(m+1))
|
||||||
} // End of if(n==m){
|
} // End of if(n==m){
|
||||||
} // End of if(n==0 and m==0)
|
} // End of if(n==0 and m==0)
|
||||||
} // End of for(uint8_t n=0;n<(DEGREE+1);n++)
|
} // End of for(uint8_t n=0;n<(DEGREE+1);n++)
|
||||||
} // End of for(uint8_t m=0;m<(ORDER+1);m++)
|
} // End of for(uint8_t m=0;m<(ORDER+1);m++)
|
||||||
|
|
||||||
// overwrite accel if not properly initialized
|
// overwrite accel if not properly initialized
|
||||||
accel[0] = 0;
|
accel[0] = 0;
|
||||||
@ -106,7 +106,7 @@ class Jgm3Model {
|
|||||||
accel[1] += partAccel[1];
|
accel[1] += partAccel[1];
|
||||||
accel[2] += partAccel[2];
|
accel[2] += partAccel[2];
|
||||||
} // End of for(uint8_t n=0;n<DEGREE;n++)
|
} // End of for(uint8_t n=0;n<DEGREE;n++)
|
||||||
} // End of uint8_t m=0;m<ORDER;m++
|
} // End of uint8_t m=0;m<ORDER;m++
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeNavOrbit(const double position[3], const double velocity[3], timeval timeUTC) {
|
void initializeNavOrbit(const double position[3], const double velocity[3], timeval timeUTC) {
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
class PoolDataSetIF : virtual public DataSetIF, virtual public ReadCommitIF {
|
class PoolDataSetIF : virtual public DataSetIF, virtual public ReadCommitIF {
|
||||||
public:
|
public:
|
||||||
virtual ~PoolDataSetIF(){};
|
virtual ~PoolDataSetIF() {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Most underlying data structures will have a pool like structure
|
* @brief Most underlying data structures will have a pool like structure
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
class SharedDataSetIF {
|
class SharedDataSetIF {
|
||||||
public:
|
public:
|
||||||
virtual ~SharedDataSetIF(){};
|
virtual ~SharedDataSetIF() {};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual ReturnValue_t lockDataset(MutexIF::TimeoutType timeoutType,
|
virtual ReturnValue_t lockDataset(MutexIF::TimeoutType timeoutType,
|
||||||
|
@ -9,7 +9,7 @@ class MutexIF;
|
|||||||
*/
|
*/
|
||||||
class AccessPoolManagerIF {
|
class AccessPoolManagerIF {
|
||||||
public:
|
public:
|
||||||
virtual ~AccessPoolManagerIF(){};
|
virtual ~AccessPoolManagerIF() {};
|
||||||
|
|
||||||
virtual MutexIF* getLocalPoolMutex() = 0;
|
virtual MutexIF* getLocalPoolMutex() = 0;
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ class HasLocalDataPoolIF {
|
|||||||
friend class HasLocalDpIFUserAttorney;
|
friend class HasLocalDpIFUserAttorney;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~HasLocalDataPoolIF(){};
|
virtual ~HasLocalDataPoolIF() {};
|
||||||
|
|
||||||
static constexpr uint32_t INVALID_LPID = localpool::INVALID_LPID;
|
static constexpr uint32_t INVALID_LPID = localpool::INVALID_LPID;
|
||||||
|
|
||||||
|
@ -257,7 +257,7 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
|||||||
MessageQueueId_t hkDestinationId = MessageQueueIF::NO_QUEUE;
|
MessageQueueId_t hkDestinationId = MessageQueueIF::NO_QUEUE;
|
||||||
|
|
||||||
union DataId {
|
union DataId {
|
||||||
DataId() : sid(){};
|
DataId() : sid() {};
|
||||||
sid_t sid;
|
sid_t sid;
|
||||||
lp_id_t localPoolId;
|
lp_id_t localPoolId;
|
||||||
};
|
};
|
||||||
|
@ -17,8 +17,7 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner, uint32_t
|
|||||||
if (hkOwner == nullptr) {
|
if (hkOwner == nullptr) {
|
||||||
// Configuration error.
|
// Configuration error.
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "LocalPoolDataSetBase::LocalPoolDataSetBase: Owner "
|
sif::error << "LocalPoolDataSetBase::LocalPoolDataSetBase: Owner " << "invalid!" << std::endl;
|
||||||
<< "invalid!" << std::endl;
|
|
||||||
#else
|
#else
|
||||||
sif::printError(
|
sif::printError(
|
||||||
"LocalPoolDataSetBase::LocalPoolDataSetBase: Owner "
|
"LocalPoolDataSetBase::LocalPoolDataSetBase: Owner "
|
||||||
@ -187,8 +186,8 @@ ReturnValue_t LocalPoolDataSetBase::serializeLocalPoolIds(uint8_t **buffer, size
|
|||||||
SerializeAdapter::serialize(¤tPoolId, buffer, size, maxSize, streamEndianness);
|
SerializeAdapter::serialize(¤tPoolId, buffer, size, maxSize, streamEndianness);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "LocalPoolDataSetBase::serializeLocalPoolIds: "
|
sif::warning << "LocalPoolDataSetBase::serializeLocalPoolIds: " << "Serialization error!"
|
||||||
<< "Serialization error!" << std::endl;
|
<< std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printWarning(
|
sif::printWarning(
|
||||||
"LocalPoolDataSetBase::serializeLocalPoolIds: "
|
"LocalPoolDataSetBase::serializeLocalPoolIds: "
|
||||||
|
@ -17,8 +17,8 @@ LocalPoolObjectBase::LocalPoolObjectBase(lp_id_t poolId, HasLocalDataPoolIF* hkO
|
|||||||
}
|
}
|
||||||
if (hkOwner == nullptr) {
|
if (hkOwner == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "LocalPoolVar<T>::LocalPoolVar: The supplied pool "
|
sif::error << "LocalPoolVar<T>::LocalPoolVar: The supplied pool " << "owner is a invalid!"
|
||||||
<< "owner is a invalid!" << std::endl;
|
<< std::endl;
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ class LocalPoolVariable : public LocalPoolObjectBase {
|
|||||||
LocalPoolVariable(gp_id_t globalPoolId, DataSetIF* dataSet = nullptr,
|
LocalPoolVariable(gp_id_t globalPoolId, DataSetIF* dataSet = nullptr,
|
||||||
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
|
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
|
||||||
|
|
||||||
virtual ~LocalPoolVariable(){};
|
virtual ~LocalPoolVariable() {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This is the local copy of the data pool entry.
|
* @brief This is the local copy of the data pool entry.
|
||||||
|
@ -88,7 +88,7 @@ class LocalPoolVector : public LocalPoolObjectBase {
|
|||||||
* @details If commit() was not called, the local value is
|
* @details If commit() was not called, the local value is
|
||||||
* discarded and not written back to the data pool.
|
* discarded and not written back to the data pool.
|
||||||
*/
|
*/
|
||||||
~LocalPoolVector(){};
|
~LocalPoolVector() {};
|
||||||
/**
|
/**
|
||||||
* @brief The operation returns the number of array entries
|
* @brief The operation returns the number of array entries
|
||||||
* in this variable.
|
* in this variable.
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
class MarkChangedIF {
|
class MarkChangedIF {
|
||||||
public:
|
public:
|
||||||
virtual ~MarkChangedIF(){};
|
virtual ~MarkChangedIF() {};
|
||||||
|
|
||||||
virtual bool hasChanged() const = 0;
|
virtual bool hasChanged() const = 0;
|
||||||
virtual void setChanged(bool changed) = 0;
|
virtual void setChanged(bool changed) = 0;
|
||||||
|
@ -28,7 +28,7 @@ using address_t = uint32_t;
|
|||||||
*/
|
*/
|
||||||
class CookieIF {
|
class CookieIF {
|
||||||
public:
|
public:
|
||||||
virtual ~CookieIF(){};
|
virtual ~CookieIF() {};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_DEVICEHANDLER_COOKIE_H_ */
|
#endif /* FSFW_DEVICEHANDLER_COOKIE_H_ */
|
||||||
|
@ -26,6 +26,11 @@ 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:
|
||||||
@ -186,15 +191,6 @@ 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) {
|
||||||
@ -247,8 +243,8 @@ bool DeviceHandlerFailureIsolation::isFdirInActionOrAreWeFaulty(EventMessage* ev
|
|||||||
if (owner == nullptr) {
|
if (owner == nullptr) {
|
||||||
// Configuration error.
|
// Configuration error.
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "DeviceHandlerFailureIsolation::"
|
sif::error << "DeviceHandlerFailureIsolation::" << "isFdirInActionOrAreWeFaulty: Owner not set!"
|
||||||
<< "isFdirInActionOrAreWeFaulty: Owner not set!" << std::endl;
|
<< std::endl;
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@ 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,
|
||||||
@ -41,6 +40,19 @@ 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);
|
||||||
|
@ -31,6 +31,7 @@ FreshDeviceHandlerBase::~FreshDeviceHandlerBase() {
|
|||||||
ReturnValue_t FreshDeviceHandlerBase::performOperation(uint8_t opCode) {
|
ReturnValue_t FreshDeviceHandlerBase::performOperation(uint8_t opCode) {
|
||||||
performDeviceOperationPreQueueHandling(opCode);
|
performDeviceOperationPreQueueHandling(opCode);
|
||||||
handleQueue();
|
handleQueue();
|
||||||
|
fdirInstance->checkForFailures();
|
||||||
performDeviceOperation(opCode);
|
performDeviceOperation(opCode);
|
||||||
poolManager.performHkOperation();
|
poolManager.performHkOperation();
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
|
@ -129,7 +129,7 @@ class FreshDeviceHandlerBase : public SystemObject,
|
|||||||
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
const uint8_t* data, size_t size) override = 0;
|
const uint8_t* data, size_t size) override = 0;
|
||||||
// Executable overrides.
|
// Executable overrides.
|
||||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
virtual ReturnValue_t performOperation(uint8_t opCode) override;
|
||||||
ReturnValue_t initializeAfterTaskCreation() override;
|
ReturnValue_t initializeAfterTaskCreation() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,8 +62,7 @@ ReturnValue_t FailureIsolationBase::initialize() {
|
|||||||
ObjectManager::instance()->get<ConfirmsFailuresIF>(faultTreeParent);
|
ObjectManager::instance()->get<ConfirmsFailuresIF>(faultTreeParent);
|
||||||
if (parentIF == nullptr) {
|
if (parentIF == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "FailureIsolationBase::intialize: Parent object "
|
sif::error << "FailureIsolationBase::intialize: Parent object " << "invalid" << std::endl;
|
||||||
<< "invalid" << std::endl;
|
|
||||||
sif::error << "Make sure it implements ConfirmsFailuresIF" << std::endl;
|
sif::error << "Make sure it implements ConfirmsFailuresIF" << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printError("FailureIsolationBase::intialize: Parent object invalid\n");
|
sif::printError("FailureIsolationBase::intialize: Parent object invalid\n");
|
||||||
@ -148,25 +147,16 @@ 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) {
|
||||||
// With this mechanism, all events are disabled for a certain device.
|
// By default, we trigger all events and also call the handler function to handle FDIR reactions
|
||||||
// That's not so good for visibility.
|
// which might occur due to these events. This makes all events visible. If the handling of
|
||||||
if (isFdirDisabledForSeverity(event::getSeverity(event))) {
|
// FDIR reaction should be disabled, this should be done through dedicated logic inside the
|
||||||
return;
|
// eventReceived function.
|
||||||
}
|
|
||||||
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) {
|
bool FailureIsolationBase::isFdirDisabledForSeverity(EventSeverity_t severity) { return false; }
|
||||||
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_FAILUREISOLATIONBASE_H_ */
|
#endif /* FRAMEWORK_FDIR */
|
||||||
|
@ -58,11 +58,7 @@ class HasFileSystemIF {
|
|||||||
static constexpr ReturnValue_t DIRECTORY_ALREADY_EXISTS = MAKE_RETURN_CODE(22);
|
static constexpr ReturnValue_t DIRECTORY_ALREADY_EXISTS = MAKE_RETURN_CODE(22);
|
||||||
static constexpr ReturnValue_t NOT_A_DIRECTORY = MAKE_RETURN_CODE(23);
|
static constexpr ReturnValue_t NOT_A_DIRECTORY = MAKE_RETURN_CODE(23);
|
||||||
static constexpr ReturnValue_t DIRECTORY_NOT_EMPTY = MAKE_RETURN_CODE(24);
|
static constexpr ReturnValue_t DIRECTORY_NOT_EMPTY = MAKE_RETURN_CODE(24);
|
||||||
|
static constexpr ReturnValue_t ELEMENT_DOES_NOT_EXIST = MAKE_RETURN_CODE(25);
|
||||||
//! [EXPORT] : P1: Sequence number missing
|
|
||||||
static constexpr ReturnValue_t SEQUENCE_PACKET_MISSING_WRITE = MAKE_RETURN_CODE(30);
|
|
||||||
//! [EXPORT] : P1: Sequence number missing
|
|
||||||
static constexpr ReturnValue_t SEQUENCE_PACKET_MISSING_READ = MAKE_RETURN_CODE(31);
|
|
||||||
|
|
||||||
virtual ~HasFileSystemIF() = default;
|
virtual ~HasFileSystemIF() = default;
|
||||||
|
|
||||||
@ -75,21 +71,27 @@ class HasFileSystemIF {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the base filename without the full directory path
|
// Get the base filename without the full directory path
|
||||||
virtual ReturnValue_t getBaseFilename(FilesystemParams params, char* nameBuf, size_t maxLen,
|
virtual ReturnValue_t getBaseFilename(const char* path, char* nameBuf, size_t maxLen,
|
||||||
size_t& baseNameLen) = 0;
|
size_t& baseNameLen) = 0;
|
||||||
|
|
||||||
virtual bool isDirectory(const char* path) = 0;
|
virtual ReturnValue_t isDirectory(const char* path, bool& isDirectory) = 0;
|
||||||
|
|
||||||
virtual bool getFileSize(FilesystemParams params, uint64_t& fileSize) = 0;
|
virtual ReturnValue_t getFileSize(const char* path, uint64_t& fileSize,
|
||||||
|
FileSystemArgsIF* args) = 0;
|
||||||
|
virtual ReturnValue_t getFileSize(const char* path, uint64_t& fileSize) {
|
||||||
|
return getFileSize(path, fileSize, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool fileExists(FilesystemParams params) = 0;
|
virtual bool fileExists(const char* path, FileSystemArgsIF* args) = 0;
|
||||||
|
virtual bool fileExists(const char* path) { return fileExists(path, nullptr); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Truncate a file, deleting its contents and setting its size to 0 accordingly.
|
* Truncate a file, deleting its contents and setting its size to 0 accordingly.
|
||||||
* @param params
|
* @param params
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t truncateFile(FilesystemParams params) = 0;
|
virtual ReturnValue_t truncateFile(const char* path, FileSystemArgsIF* args) = 0;
|
||||||
|
virtual ReturnValue_t truncateFile(const char* path) { return truncateFile(path, nullptr); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Generic function to write to a file.
|
* @brief Generic function to write to a file.
|
||||||
@ -100,32 +102,23 @@ class HasFileSystemIF {
|
|||||||
* @param fileOpInfo General information: File name, size to write, offset, additional arguments
|
* @param fileOpInfo General information: File name, size to write, offset, additional arguments
|
||||||
* @param data The data to write to the file
|
* @param data The data to write to the file
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t writeToFile(FileOpParams params, const uint8_t* data) = 0;
|
virtual ReturnValue_t writeToFile(const char* path, size_t offset, const uint8_t* data,
|
||||||
|
size_t size) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Generic function to read from a file. This variant takes a pointer to a buffer and
|
* @brief Generic function to read from a file. This variant takes a pointer to a buffer and
|
||||||
* performs pointer arithmetic by incrementing the pointer by the read size
|
* performs pointer arithmetic by incrementing the pointer by the read size
|
||||||
* @param fileOpInfo General information: File name, size to write, offset, additional arguments
|
* @param path [in] file path
|
||||||
* @param buffer [in/out] Data will be read into the provided buffer, and the pointer will be
|
* @param offset [in] offset of data to read
|
||||||
* incremented by the read length
|
* @param sizeToRead [in] size of data to read
|
||||||
* @param readSize [out] Will be incremented by the read length
|
* @param buffer [in/out] Data will be read into the provided buffer.
|
||||||
* @param maxSize Maximum size of the provided buffer
|
* @param actuallyRead [out] Will be set to the length actually read.
|
||||||
|
* @param maxSize [in] Maximum size of the provided buffer
|
||||||
* @param args
|
* @param args
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t readFromFile(FileOpParams fileOpInfo, uint8_t** buffer, size_t& readSize,
|
virtual ReturnValue_t readFromFile(const char* path, size_t offset, size_t sizeToRead,
|
||||||
size_t maxSize) = 0;
|
uint8_t* buffer, size_t& actuallyRead, size_t maxSize) = 0;
|
||||||
/**
|
|
||||||
* Variant of the @readFromFile which does not perform pointer arithmetic.
|
|
||||||
* @param fileOpInfo General information: File name, size to write, offset, additional arguments
|
|
||||||
* @param buf
|
|
||||||
* @param maxSize
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t readFromFile(FileOpParams fileOpInfo, uint8_t* buf, size_t maxSize) {
|
|
||||||
size_t dummy = 0;
|
|
||||||
return readFromFile(fileOpInfo, &buf, dummy, maxSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Generic function to create a new file.
|
* @brief Generic function to create a new file.
|
||||||
@ -136,10 +129,8 @@ class HasFileSystemIF {
|
|||||||
* @param args Any other arguments which an implementation might require
|
* @param args Any other arguments which an implementation might require
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t createFile(FilesystemParams params) {
|
virtual ReturnValue_t createFile(const char* path) { return createFile(path, nullptr, 0); }
|
||||||
return createFile(params, nullptr, 0);
|
virtual ReturnValue_t createFile(const char* path, const uint8_t* data, size_t size) = 0;
|
||||||
}
|
|
||||||
virtual ReturnValue_t createFile(FilesystemParams params, const uint8_t* data, size_t size) = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Generic function to delete a file.
|
* @brief Generic function to delete a file.
|
||||||
@ -159,9 +150,13 @@ class HasFileSystemIF {
|
|||||||
* @param args Any other arguments which an implementation might require
|
* @param args Any other arguments which an implementation might require
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t createDirectory(FilesystemParams params, bool createParentDirs) = 0;
|
virtual ReturnValue_t createDirectory(const char* path, bool createParentDirs,
|
||||||
virtual ReturnValue_t createDirectory(FilesystemParams params) {
|
FileSystemArgsIF* args) = 0;
|
||||||
return createDirectory(params, false);
|
virtual ReturnValue_t createDirectory(const char* path, FileSystemArgsIF* args) {
|
||||||
|
return createDirectory(path, false, args);
|
||||||
|
}
|
||||||
|
virtual ReturnValue_t createDirectory(const char* path) {
|
||||||
|
return createDirectory(path, false, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -169,9 +164,10 @@ class HasFileSystemIF {
|
|||||||
* @param repositoryPath
|
* @param repositoryPath
|
||||||
* @param args Any other arguments which an implementation might require
|
* @param args Any other arguments which an implementation might require
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t removeDirectory(FilesystemParams params, bool deleteRecurively) = 0;
|
virtual ReturnValue_t removeDirectory(const char* path, bool deleteRecurively,
|
||||||
virtual ReturnValue_t removeDirectory(FilesystemParams params) {
|
FileSystemArgsIF* args) = 0;
|
||||||
return removeDirectory(params, false);
|
virtual ReturnValue_t removeDirectory(const char* path, FileSystemArgsIF* args) {
|
||||||
|
return removeDirectory(path, false, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ReturnValue_t rename(const char* oldPath, const char* newPath) {
|
virtual ReturnValue_t rename(const char* oldPath, const char* newPath) {
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
#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 {
|
||||||
@ -95,6 +98,139 @@ 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_ */
|
||||||
|
@ -72,6 +72,15 @@ void QuaternionOperations::slerp(const double q1[4], const double q2[4], const d
|
|||||||
normalize(q);
|
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) {
|
||||||
@ -153,3 +162,25 @@ 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);
|
||||||
|
}
|
||||||
|
@ -25,6 +25,11 @@ class QuaternionOperations {
|
|||||||
|
|
||||||
static void slerp(const double q1[4], const double q2[4], const double weight, double q[4]);
|
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,6 +99,15 @@ 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();
|
||||||
};
|
};
|
||||||
|
@ -23,7 +23,7 @@ class HousekeepingSnapshot : public SerializeIF {
|
|||||||
HousekeepingSnapshot(CCSDSTime::CDS_short* cdsShort, LocalPoolDataSetBase* dataSetPtr)
|
HousekeepingSnapshot(CCSDSTime::CDS_short* cdsShort, LocalPoolDataSetBase* dataSetPtr)
|
||||||
: timeStamp(reinterpret_cast<uint8_t*>(cdsShort)),
|
: timeStamp(reinterpret_cast<uint8_t*>(cdsShort)),
|
||||||
timeStampSize(sizeof(CCSDSTime::CDS_short)),
|
timeStampSize(sizeof(CCSDSTime::CDS_short)),
|
||||||
updateData(dataSetPtr){};
|
updateData(dataSetPtr) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update packet constructor for datasets.
|
* Update packet constructor for datasets.
|
||||||
@ -32,7 +32,7 @@ class HousekeepingSnapshot : public SerializeIF {
|
|||||||
* @param dataSetPtr Pointer to the dataset instance to deserialize the data into
|
* @param dataSetPtr Pointer to the dataset instance to deserialize the data into
|
||||||
*/
|
*/
|
||||||
HousekeepingSnapshot(uint8_t* timeStamp, size_t timeStampSize, LocalPoolDataSetBase* dataSetPtr)
|
HousekeepingSnapshot(uint8_t* timeStamp, size_t timeStampSize, LocalPoolDataSetBase* dataSetPtr)
|
||||||
: timeStamp(timeStamp), timeStampSize(timeStampSize), updateData(dataSetPtr){};
|
: timeStamp(timeStamp), timeStampSize(timeStampSize), updateData(dataSetPtr) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update packet constructor for pool variables.
|
* Update packet constructor for pool variables.
|
||||||
@ -43,7 +43,7 @@ class HousekeepingSnapshot : public SerializeIF {
|
|||||||
HousekeepingSnapshot(CCSDSTime::CDS_short* cdsShort, LocalPoolObjectBase* dataSetPtr)
|
HousekeepingSnapshot(CCSDSTime::CDS_short* cdsShort, LocalPoolObjectBase* dataSetPtr)
|
||||||
: timeStamp(reinterpret_cast<uint8_t*>(cdsShort)),
|
: timeStamp(reinterpret_cast<uint8_t*>(cdsShort)),
|
||||||
timeStampSize(sizeof(CCSDSTime::CDS_short)),
|
timeStampSize(sizeof(CCSDSTime::CDS_short)),
|
||||||
updateData(dataSetPtr){};
|
updateData(dataSetPtr) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update packet constructor for pool variables.
|
* Update packet constructor for pool variables.
|
||||||
@ -52,7 +52,7 @@ class HousekeepingSnapshot : public SerializeIF {
|
|||||||
* @param dataSetPtr
|
* @param dataSetPtr
|
||||||
*/
|
*/
|
||||||
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,
|
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||||
Endianness streamEndianness) const {
|
Endianness streamEndianness) const {
|
||||||
|
@ -37,7 +37,7 @@ class CommandMessageIF {
|
|||||||
//! Parameter 1 should contain the error code
|
//! Parameter 1 should contain the error code
|
||||||
static const Command_t REPLY_REJECTED = MAKE_COMMAND_ID(2);
|
static const Command_t REPLY_REJECTED = MAKE_COMMAND_ID(2);
|
||||||
|
|
||||||
virtual ~CommandMessageIF(){};
|
virtual ~CommandMessageIF() {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A command message shall have a uint16_t command ID field.
|
* A command message shall have a uint16_t command ID field.
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include <fsfw/objectmanager/frameworkObjects.h>
|
#include <fsfw/objectmanager/frameworkObjects.h>
|
||||||
|
|
||||||
struct MqArgs {
|
struct MqArgs {
|
||||||
MqArgs(){};
|
MqArgs() {};
|
||||||
MqArgs(object_id_t objectId, void* args = nullptr) : objectId(objectId), args(args) {}
|
MqArgs(object_id_t objectId, void* args = nullptr) : objectId(objectId), args(args) {}
|
||||||
object_id_t objectId = objects::NO_OBJECT;
|
object_id_t objectId = objects::NO_OBJECT;
|
||||||
void* args = nullptr;
|
void* args = nullptr;
|
||||||
|
@ -40,7 +40,7 @@ class ObjectManagerIF {
|
|||||||
/**
|
/**
|
||||||
* @brief This is the empty virtual destructor as requested by C++ interfaces.
|
* @brief This is the empty virtual destructor as requested by C++ interfaces.
|
||||||
*/
|
*/
|
||||||
virtual ~ObjectManagerIF(void){};
|
virtual ~ObjectManagerIF(void) {};
|
||||||
/**
|
/**
|
||||||
* @brief With this call, new objects are inserted to the list.
|
* @brief With this call, new objects are inserted to the list.
|
||||||
* @details The implementation shall return an error code in case the
|
* @details The implementation shall return an error code in case the
|
||||||
|
@ -49,8 +49,8 @@ ReturnValue_t TcpTmTcBridge::handleTm() {
|
|||||||
MutexGuard guard(mutex, timeoutType, mutexTimeoutMs);
|
MutexGuard guard(mutex, timeoutType, mutexTimeoutMs);
|
||||||
TmTcMessage message;
|
TmTcMessage message;
|
||||||
ReturnValue_t status = returnvalue::OK;
|
ReturnValue_t status = returnvalue::OK;
|
||||||
for (ReturnValue_t result = tmTcReceptionQueue->receiveMessage(&message);
|
for (ReturnValue_t result = tmtcReceptionQueue->receiveMessage(&message);
|
||||||
result == returnvalue::OK; result = tmTcReceptionQueue->receiveMessage(&message)) {
|
result == returnvalue::OK; result = tmtcReceptionQueue->receiveMessage(&message)) {
|
||||||
status = storeDownlinkData(&message);
|
status = storeDownlinkData(&message);
|
||||||
if (status != returnvalue::OK) {
|
if (status != returnvalue::OK) {
|
||||||
break;
|
break;
|
||||||
|
@ -321,8 +321,8 @@ ReturnValue_t TcpTmTcServer::handleTcRingBufferData(size_t availableReadData) {
|
|||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
// Possible configuration error, too much data or/and data coming in too fast,
|
// Possible configuration error, too much data or/and data coming in too fast,
|
||||||
// requiring larger buffers
|
// requiring larger buffers
|
||||||
sif::warning << "TcpTmTcServer::handleServerOperation: Ring buffer reached "
|
sif::warning << "TcpTmTcServer::handleServerOperation: Ring buffer reached " << "fill count"
|
||||||
<< "fill count" << std::endl;
|
<< std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printWarning(
|
sif::printWarning(
|
||||||
"TcpTmTcServer::handleServerOperation: Ring buffer reached "
|
"TcpTmTcServer::handleServerOperation: Ring buffer reached "
|
||||||
|
@ -34,7 +34,9 @@ ReturnValue_t Clock::setClock(const timeval* time) {
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
ReturnValue_t Clock::getClock_timeval(timeval* time) { return getClock(time); }
|
||||||
|
|
||||||
|
ReturnValue_t Clock::getClock(timeval* time) {
|
||||||
timeval uptime = getUptime();
|
timeval uptime = getUptime();
|
||||||
|
|
||||||
timeval offset = Timekeeper::instance()->getOffset();
|
timeval offset = Timekeeper::instance()->getOffset();
|
||||||
|
@ -49,8 +49,8 @@ ReturnValue_t Service20ParameterManagement::checkAndAcquireTargetID(object_id_t*
|
|||||||
if (SerializeAdapter::deSerialize(objectIdToSet, &tcData, &tcDataLen,
|
if (SerializeAdapter::deSerialize(objectIdToSet, &tcData, &tcDataLen,
|
||||||
SerializeIF::Endianness::BIG) != returnvalue::OK) {
|
SerializeIF::Endianness::BIG) != returnvalue::OK) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "Service20ParameterManagement::checkAndAcquireTargetID: "
|
sif::error << "Service20ParameterManagement::checkAndAcquireTargetID: " << "Invalid data."
|
||||||
<< "Invalid data." << std::endl;
|
<< std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printError(
|
sif::printError(
|
||||||
"Service20ParameterManagement::"
|
"Service20ParameterManagement::"
|
||||||
|
@ -196,8 +196,8 @@ ReturnValue_t Service3Housekeeping::handleReply(const CommandMessage* reply,
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "Service3Housekeeping::handleReply: Invalid reply with "
|
sif::warning << "Service3Housekeeping::handleReply: Invalid reply with " << "reply command "
|
||||||
<< "reply command " << command << std::endl;
|
<< command << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printWarning(
|
sif::printWarning(
|
||||||
"Service3Housekeeping::handleReply: Invalid reply with "
|
"Service3Housekeeping::handleReply: Invalid reply with "
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "fsfw/events/EventManagerIF.h"
|
|
||||||
#include "fsfw/pus/servicepackets/Service9Packets.h"
|
#include "fsfw/pus/servicepackets/Service9Packets.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
|
#include "fsfw/serialize/SerializeAdapter.h"
|
||||||
#include "fsfw/timemanager/CCSDSTime.h"
|
#include "fsfw/timemanager/CCSDSTime.h"
|
||||||
|
|
||||||
Service9TimeManagement::Service9TimeManagement(PsbParams params) : PusServiceBase(params) {
|
Service9TimeManagement::Service9TimeManagement(PsbParams params) : PusServiceBase(params) {
|
||||||
@ -18,16 +18,53 @@ ReturnValue_t Service9TimeManagement::performService() { return returnvalue::OK;
|
|||||||
ReturnValue_t Service9TimeManagement::handleRequest(uint8_t subservice) {
|
ReturnValue_t Service9TimeManagement::handleRequest(uint8_t subservice) {
|
||||||
switch (subservice) {
|
switch (subservice) {
|
||||||
case Subservice::SET_TIME: {
|
case Subservice::SET_TIME: {
|
||||||
return setTime();
|
reportCurrentTime(CLOCK_DUMP_BEFORE_SETTING_TIME);
|
||||||
|
ReturnValue_t result = setTime();
|
||||||
|
reportCurrentTime(CLOCK_DUMP_AFTER_SETTING_TIME);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
case Subservice::DUMP_TIME: {
|
case Subservice::DUMP_TIME: {
|
||||||
timeval newTime;
|
reportCurrentTime();
|
||||||
Clock::getClock_timeval(&newTime);
|
|
||||||
uint32_t subsecondMs =
|
|
||||||
static_cast<uint32_t>(std::floor(static_cast<double>(newTime.tv_usec) / 1000.0));
|
|
||||||
triggerEvent(CLOCK_DUMP, newTime.tv_sec, subsecondMs);
|
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
case Subservice::RELATIVE_TIMESHIFT: {
|
||||||
|
timeval currentTime;
|
||||||
|
ReturnValue_t result = Clock::getClock(¤tTime);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
reportTime(CLOCK_DUMP_BEFORE_SETTING_TIME, currentTime);
|
||||||
|
|
||||||
|
if (currentPacket.getUserDataLen() != 8) {
|
||||||
|
return AcceptsTelecommandsIF::ILLEGAL_APPLICATION_DATA;
|
||||||
|
}
|
||||||
|
size_t deserLen = 8;
|
||||||
|
int64_t timeshiftNanos = 0;
|
||||||
|
result = SerializeAdapter::deSerialize(×hiftNanos, currentPacket.getUserData(),
|
||||||
|
&deserLen, SerializeIF::Endianness::NETWORK);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
bool positiveShift = true;
|
||||||
|
if (timeshiftNanos < 0) {
|
||||||
|
positiveShift = false;
|
||||||
|
}
|
||||||
|
timeval offset{};
|
||||||
|
offset.tv_sec = std::abs(timeshiftNanos) / NANOS_PER_SECOND;
|
||||||
|
offset.tv_usec = (std::abs(timeshiftNanos) % NANOS_PER_SECOND) / 1000;
|
||||||
|
|
||||||
|
timeval newTime;
|
||||||
|
if (positiveShift) {
|
||||||
|
newTime = currentTime + offset;
|
||||||
|
} else {
|
||||||
|
newTime = currentTime - offset;
|
||||||
|
}
|
||||||
|
result = Clock::setClock(&newTime);
|
||||||
|
if (result == returnvalue::OK) {
|
||||||
|
reportTime(CLOCK_DUMP_AFTER_SETTING_TIME, newTime);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
|
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
|
||||||
}
|
}
|
||||||
@ -43,17 +80,20 @@ ReturnValue_t Service9TimeManagement::setTime() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
timeval time;
|
|
||||||
Clock::getClock_timeval(&time);
|
|
||||||
result = Clock::setClock(&timeToSet);
|
result = Clock::setClock(&timeToSet);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
if (result == returnvalue::OK) {
|
|
||||||
timeval newTime;
|
|
||||||
Clock::getClock_timeval(&newTime);
|
|
||||||
triggerEvent(CLOCK_SET, time.tv_sec, newTime.tv_sec);
|
|
||||||
return returnvalue::OK;
|
|
||||||
} else {
|
|
||||||
triggerEvent(CLOCK_SET_FAILURE, result, 0);
|
triggerEvent(CLOCK_SET_FAILURE, result, 0);
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Service9TimeManagement::reportCurrentTime(Event event) {
|
||||||
|
timeval currentTime{};
|
||||||
|
Clock::getClock(¤tTime);
|
||||||
|
triggerEvent(event, currentTime.tv_sec, currentTime.tv_usec);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Service9TimeManagement::reportTime(Event event, timeval time) {
|
||||||
|
triggerEvent(event, time.tv_sec, time.tv_usec);
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,25 @@
|
|||||||
#ifndef FSFW_PUS_SERVICE9TIMEMANAGEMENT_H_
|
#ifndef FSFW_PUS_SERVICE9TIMEMANAGEMENT_H_
|
||||||
#define FSFW_PUS_SERVICE9TIMEMANAGEMENT_H_
|
#define FSFW_PUS_SERVICE9TIMEMANAGEMENT_H_
|
||||||
|
|
||||||
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
#include "fsfw/tmtcservices/PusServiceBase.h"
|
#include "fsfw/tmtcservices/PusServiceBase.h"
|
||||||
|
|
||||||
class Service9TimeManagement : public PusServiceBase {
|
class Service9TimeManagement : public PusServiceBase {
|
||||||
public:
|
public:
|
||||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_9;
|
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_9;
|
||||||
|
|
||||||
//!< Clock has been set. P1: old timeval seconds. P2: new timeval seconds.
|
static constexpr uint32_t NANOS_PER_SECOND = 1'000'000'000;
|
||||||
|
|
||||||
|
//!< [EXPORT] : [COMMENT] Clock has been set. P1: old timeval seconds. P2: new timeval seconds.
|
||||||
static constexpr Event CLOCK_SET = MAKE_EVENT(0, severity::INFO);
|
static constexpr Event CLOCK_SET = MAKE_EVENT(0, severity::INFO);
|
||||||
//!< Clock dump event. P1: timeval seconds P2: timeval milliseconds.
|
//!< [EXPORT] : [COMMENT] Clock dump event. P1: timeval seconds P2: timeval milliseconds.
|
||||||
static constexpr Event CLOCK_DUMP = MAKE_EVENT(1, severity::INFO);
|
static constexpr Event CLOCK_DUMP_LEGACY = MAKE_EVENT(1, severity::INFO);
|
||||||
//!< Clock could not be set. P1: Returncode.
|
//!< [EXPORT] : [COMMENT] Clock could not be set. P1: Returncode.
|
||||||
static constexpr Event CLOCK_SET_FAILURE = MAKE_EVENT(2, severity::LOW);
|
static constexpr Event CLOCK_SET_FAILURE = MAKE_EVENT(2, severity::LOW);
|
||||||
|
//!< [EXPORT] : [COMMENT] Clock dump event. P1: timeval seconds P2: timeval microseconds.
|
||||||
|
static constexpr Event CLOCK_DUMP = MAKE_EVENT(3, severity::INFO);
|
||||||
|
static constexpr Event CLOCK_DUMP_BEFORE_SETTING_TIME = MAKE_EVENT(4, severity::INFO);
|
||||||
|
static constexpr Event CLOCK_DUMP_AFTER_SETTING_TIME = MAKE_EVENT(5, severity::INFO);
|
||||||
|
|
||||||
static constexpr uint8_t CLASS_ID = CLASS_ID::PUS_SERVICE_9;
|
static constexpr uint8_t CLASS_ID = CLASS_ID::PUS_SERVICE_9;
|
||||||
|
|
||||||
@ -30,12 +37,16 @@ class Service9TimeManagement : public PusServiceBase {
|
|||||||
*/
|
*/
|
||||||
ReturnValue_t handleRequest(uint8_t subservice) override;
|
ReturnValue_t handleRequest(uint8_t subservice) override;
|
||||||
|
|
||||||
|
void reportCurrentTime(Event eventType = CLOCK_DUMP);
|
||||||
|
void reportTime(Event event, timeval time);
|
||||||
|
|
||||||
virtual ReturnValue_t setTime();
|
virtual ReturnValue_t setTime();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum Subservice {
|
enum Subservice {
|
||||||
SET_TIME = 128, //!< [EXPORT] : [COMMAND] Time command in ASCII, CUC or CDS format
|
SET_TIME = 128, //!< [EXPORT] : [COMMAND] Time command in ASCII, CUC or CDS format
|
||||||
DUMP_TIME = 129,
|
DUMP_TIME = 129,
|
||||||
|
RELATIVE_TIMESHIFT = 130,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
class RMAPChannelIF {
|
class RMAPChannelIF {
|
||||||
public:
|
public:
|
||||||
virtual ~RMAPChannelIF(){};
|
virtual ~RMAPChannelIF() {};
|
||||||
/**
|
/**
|
||||||
* Reset an RMAP channel
|
* Reset an RMAP channel
|
||||||
*
|
*
|
||||||
|
@ -12,8 +12,7 @@ LocalPool::LocalPool(object_id_t setObjectId, const LocalPoolConfig& poolConfig,
|
|||||||
spillsToHigherPools(spillsToHigherPools) {
|
spillsToHigherPools(spillsToHigherPools) {
|
||||||
if (NUMBER_OF_SUBPOOLS == 0) {
|
if (NUMBER_OF_SUBPOOLS == 0) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "LocalPool::LocalPool: Passed pool configuration is "
|
sif::error << "LocalPool::LocalPool: Passed pool configuration is " << " invalid!" << std::endl;
|
||||||
<< " invalid!" << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
max_subpools_t index = 0;
|
max_subpools_t index = 0;
|
||||||
|
@ -38,10 +38,9 @@ ReturnValue_t Subsystem::checkSequence(HybridIterator<ModeListEntry> iter,
|
|||||||
if (!existsModeTable(iter->getTableId())) {
|
if (!existsModeTable(iter->getTableId())) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
using namespace std;
|
using namespace std;
|
||||||
sif::warning << "Subsystem::checkSequence: "
|
sif::warning << "Subsystem::checkSequence: " << "Object " << setfill('0') << hex << "0x"
|
||||||
<< "Object " << setfill('0') << hex << "0x" << setw(8) << getObjectId()
|
<< setw(8) << getObjectId() << setw(0) << ": Mode table for mode ID " << "0x"
|
||||||
<< setw(0) << ": Mode table for mode ID "
|
<< setw(8) << iter->getTableId() << " does not exist" << dec << endl;
|
||||||
<< "0x" << setw(8) << iter->getTableId() << " does not exist" << dec << endl;
|
|
||||||
#endif
|
#endif
|
||||||
return TABLE_DOES_NOT_EXIST;
|
return TABLE_DOES_NOT_EXIST;
|
||||||
} else {
|
} else {
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
struct TableSequenceBase {
|
struct TableSequenceBase {
|
||||||
public:
|
public:
|
||||||
TableSequenceBase(Mode_t mode, ArrayList<ModeListEntry> *table) : mode(mode), table(table){};
|
TableSequenceBase(Mode_t mode, ArrayList<ModeListEntry> *table) : mode(mode), table(table) {};
|
||||||
Mode_t mode;
|
Mode_t mode;
|
||||||
ArrayList<ModeListEntry> *table;
|
ArrayList<ModeListEntry> *table;
|
||||||
bool inStore = false;
|
bool inStore = false;
|
||||||
@ -21,7 +21,7 @@ struct TableSequenceBase {
|
|||||||
|
|
||||||
struct TableEntry : public TableSequenceBase {
|
struct TableEntry : public TableSequenceBase {
|
||||||
public:
|
public:
|
||||||
TableEntry(Mode_t mode, ArrayList<ModeListEntry> *table) : TableSequenceBase(mode, table){};
|
TableEntry(Mode_t mode, ArrayList<ModeListEntry> *table) : TableSequenceBase(mode, table) {};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SequenceEntry : public TableSequenceBase {
|
struct SequenceEntry : public TableSequenceBase {
|
||||||
|
@ -34,7 +34,7 @@ class ExecutableObjectIF {
|
|||||||
* a reference to the executing task
|
* a reference to the executing task
|
||||||
* @param task_ Pointer to the taskIF of this task
|
* @param task_ Pointer to the taskIF of this task
|
||||||
*/
|
*/
|
||||||
virtual void setTaskIF(PeriodicTaskIF* task_){};
|
virtual void setTaskIF(PeriodicTaskIF* task_) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function should be called after the object was assigned to a
|
* This function should be called after the object was assigned to a
|
||||||
|
@ -101,8 +101,7 @@ ReturnValue_t FixedSlotSequence::checkSequence() const {
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
// Continue for now but print error output.
|
// Continue for now but print error output.
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "FixedSlotSequence::checkSequence:"
|
sif::error << "FixedSlotSequence::checkSequence:" << " Custom check failed!" << std::endl;
|
||||||
<< " Custom check failed!" << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ class SemaphoreIF {
|
|||||||
BLOCKING //!< Block indefinitely until the mutex becomes available.
|
BLOCKING //!< Block indefinitely until the mutex becomes available.
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual ~SemaphoreIF(){};
|
virtual ~SemaphoreIF() {};
|
||||||
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::SEMAPHORE_IF;
|
static const uint8_t INTERFACE_ID = CLASS_ID::SEMAPHORE_IF;
|
||||||
//! Semaphore timeout
|
//! Semaphore timeout
|
||||||
|
@ -8,8 +8,8 @@
|
|||||||
|
|
||||||
#define PUS_DISTRIBUTOR_DEBUGGING 0
|
#define PUS_DISTRIBUTOR_DEBUGGING 0
|
||||||
|
|
||||||
PusDistributor::PusDistributor(uint16_t setApid, object_id_t setObjectId,
|
PusDistributor::PusDistributor(uint16_t setApid, object_id_t setObjectId, StorageManagerIF* store_,
|
||||||
CcsdsDistributorIF* distributor, StorageManagerIF* store_)
|
CcsdsDistributorIF* distributor)
|
||||||
: TcDistributorBase(setObjectId),
|
: TcDistributorBase(setObjectId),
|
||||||
store(store_),
|
store(store_),
|
||||||
checker(setApid, ccsds::PacketType::TC),
|
checker(setApid, ccsds::PacketType::TC),
|
||||||
@ -122,14 +122,12 @@ ReturnValue_t PusDistributor::initialize() {
|
|||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ccsdsDistributor == nullptr) {
|
if (ccsdsDistributor != nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
ReturnValue_t result =
|
||||||
sif::error << "PUSDistributor::initialize: Packet source invalid" << std::endl;
|
ccsdsDistributor->registerApplication(CcsdsDistributorIF::DestInfo(*this, false));
|
||||||
sif::error << " Make sure it exists and implements CCSDSDistributorIF!" << std::endl;
|
if (result != returnvalue::OK) {
|
||||||
#else
|
return result;
|
||||||
sif::printError("PusDistributor::initialize: Packet source invalid\n");
|
}
|
||||||
sif::printError("Make sure it exists and implements CcsdsDistributorIF\n");
|
|
||||||
#endif
|
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
if (verifyChannel == nullptr) {
|
if (verifyChannel == nullptr) {
|
||||||
@ -139,7 +137,7 @@ ReturnValue_t PusDistributor::initialize() {
|
|||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ccsdsDistributor->registerApplication(CcsdsDistributorIF::DestInfo(*this, false));
|
return SystemObject::initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PusDistributor::checkerFailurePrinter() const {
|
void PusDistributor::checkerFailurePrinter() const {
|
||||||
|
@ -31,8 +31,9 @@ class PusDistributor : public TcDistributorBase,
|
|||||||
* @param setPacketSource Object ID of the source of TC packets.
|
* @param setPacketSource Object ID of the source of TC packets.
|
||||||
* Must implement CcsdsDistributorIF.
|
* Must implement CcsdsDistributorIF.
|
||||||
*/
|
*/
|
||||||
PusDistributor(uint16_t setApid, object_id_t setObjectId, CcsdsDistributorIF* packetSource,
|
PusDistributor(uint16_t setApid, object_id_t setObjectId, StorageManagerIF* store = nullptr,
|
||||||
StorageManagerIF* store = nullptr);
|
CcsdsDistributorIF* packetSource = nullptr);
|
||||||
|
|
||||||
[[nodiscard]] const char* getName() const override;
|
[[nodiscard]] const char* getName() const override;
|
||||||
/**
|
/**
|
||||||
* The destructor is empty.
|
* The destructor is empty.
|
||||||
|
@ -27,5 +27,5 @@ static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::TMTC_DISTRIBUTION;
|
|||||||
//! P1: Returnvalue, P2: 0 for TM issues, 1 for TC issues
|
//! P1: Returnvalue, P2: 0 for TM issues, 1 for TC issues
|
||||||
static constexpr Event HANDLE_PACKET_FAILED = event::makeEvent(SUBSYSTEM_ID, 0, severity::LOW);
|
static constexpr Event HANDLE_PACKET_FAILED = event::makeEvent(SUBSYSTEM_ID, 0, severity::LOW);
|
||||||
|
|
||||||
}; // namespace tmtcdistrib
|
}; // namespace tmtcdistrib
|
||||||
#endif // FSFW_TMTCPACKET_DEFINITIONS_H
|
#endif // FSFW_TMTCPACKET_DEFINITIONS_H
|
||||||
|
@ -212,8 +212,8 @@ class CCSDSTime {
|
|||||||
static uint32_t subsecondsToMicroseconds(uint16_t subseconds);
|
static uint32_t subsecondsToMicroseconds(uint16_t subseconds);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CCSDSTime(){};
|
CCSDSTime() {};
|
||||||
virtual ~CCSDSTime(){};
|
virtual ~CCSDSTime() {};
|
||||||
/**
|
/**
|
||||||
* checks a ccs time stream for validity
|
* checks a ccs time stream for validity
|
||||||
*
|
*
|
||||||
|
@ -43,9 +43,10 @@ ReturnValue_t SpacePacketCreator::serialize(uint8_t **buffer, size_t *size, size
|
|||||||
|
|
||||||
void SpacePacketCreator::setCcsdsLenFromTotalDataFieldLen(size_t actualLength) {
|
void SpacePacketCreator::setCcsdsLenFromTotalDataFieldLen(size_t actualLength) {
|
||||||
if (actualLength == 0) {
|
if (actualLength == 0) {
|
||||||
return;
|
setDataLenField(actualLength);
|
||||||
|
} else {
|
||||||
|
setDataLenField(actualLength - 1);
|
||||||
}
|
}
|
||||||
setDataLenField(actualLength - 1);
|
|
||||||
}
|
}
|
||||||
size_t SpacePacketCreator::getSerializedSize() const { return ccsds::HEADER_LEN; }
|
size_t SpacePacketCreator::getSerializedSize() const { return ccsds::HEADER_LEN; }
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ struct PusTmSecHeader {
|
|||||||
|
|
||||||
struct PusTmParams {
|
struct PusTmParams {
|
||||||
PusTmParams() = default;
|
PusTmParams() = default;
|
||||||
explicit PusTmParams(PusTmSecHeader secHeader) : secHeader(secHeader){};
|
explicit PusTmParams(PusTmSecHeader secHeader) : secHeader(secHeader) {};
|
||||||
PusTmParams(PusTmSecHeader secHeader, const SerializeIF& data)
|
PusTmParams(PusTmSecHeader secHeader, const SerializeIF& data)
|
||||||
: secHeader(secHeader), sourceData(&data) {}
|
: secHeader(secHeader), sourceData(&data) {}
|
||||||
PusTmParams(PusTmSecHeader secHeader, const uint8_t* data, size_t dataLen)
|
PusTmParams(PusTmSecHeader secHeader, const uint8_t* data, size_t dataLen)
|
||||||
|
@ -40,7 +40,7 @@ void PusServiceBase::setTaskIF(PeriodicTaskIF* taskHandle_) { this->taskHandle =
|
|||||||
void PusServiceBase::handleRequestQueue() {
|
void PusServiceBase::handleRequestQueue() {
|
||||||
TmTcMessage message;
|
TmTcMessage message;
|
||||||
ReturnValue_t result;
|
ReturnValue_t result;
|
||||||
for (uint8_t count = 0; count < PUS_SERVICE_MAX_RECEPTION; count++) {
|
for (uint8_t count = 0; count < psbParams.maxPacketsPerCycle; count++) {
|
||||||
ReturnValue_t status = psbParams.reqQueue->receiveMessage(&message);
|
ReturnValue_t status = psbParams.reqQueue->receiveMessage(&message);
|
||||||
if (status == MessageQueueIF::EMPTY) {
|
if (status == MessageQueueIF::EMPTY) {
|
||||||
break;
|
break;
|
||||||
@ -98,7 +98,7 @@ ReturnValue_t PusServiceBase::initialize() {
|
|||||||
}
|
}
|
||||||
if (psbParams.reqQueue == nullptr) {
|
if (psbParams.reqQueue == nullptr) {
|
||||||
ownedQueue = true;
|
ownedQueue = true;
|
||||||
psbParams.reqQueue = QueueFactory::instance()->createMessageQueue(PSB_DEFAULT_QUEUE_DEPTH);
|
psbParams.reqQueue = QueueFactory::instance()->createMessageQueue(psbParams.requestQueueDepth);
|
||||||
} else {
|
} else {
|
||||||
ownedQueue = false;
|
ownedQueue = false;
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,14 @@ class StorageManagerIF;
|
|||||||
* Configuration parameters for the PUS Service Base
|
* Configuration parameters for the PUS Service Base
|
||||||
*/
|
*/
|
||||||
struct PsbParams {
|
struct PsbParams {
|
||||||
|
static constexpr uint8_t PSB_DEFAULT_QUEUE_DEPTH = 10;
|
||||||
|
/**
|
||||||
|
* This constant sets the maximum number of packets accepted per call.
|
||||||
|
* Remember that one packet must be completely handled in one
|
||||||
|
* #handleRequest call.
|
||||||
|
*/
|
||||||
|
static constexpr uint8_t MAX_PACKETS_PER_CYCLE = 10;
|
||||||
|
|
||||||
PsbParams() = default;
|
PsbParams() = default;
|
||||||
PsbParams(uint16_t apid, AcceptsTelemetryIF* tmReceiver) : apid(apid), tmReceiver(tmReceiver) {}
|
PsbParams(uint16_t apid, AcceptsTelemetryIF* tmReceiver) : apid(apid), tmReceiver(tmReceiver) {}
|
||||||
PsbParams(const char* name, uint16_t apid, AcceptsTelemetryIF* tmReceiver)
|
PsbParams(const char* name, uint16_t apid, AcceptsTelemetryIF* tmReceiver)
|
||||||
@ -32,6 +40,9 @@ struct PsbParams {
|
|||||||
object_id_t objectId = objects::NO_OBJECT;
|
object_id_t objectId = objects::NO_OBJECT;
|
||||||
uint16_t apid = 0;
|
uint16_t apid = 0;
|
||||||
uint8_t serviceId = 0;
|
uint8_t serviceId = 0;
|
||||||
|
uint32_t requestQueueDepth = PSB_DEFAULT_QUEUE_DEPTH;
|
||||||
|
uint32_t maxPacketsPerCycle = MAX_PACKETS_PER_CYCLE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default destination ID for generated telemetry. If this is not set, @initialize of PSB
|
* The default destination ID for generated telemetry. If this is not set, @initialize of PSB
|
||||||
* will attempt to find a suitable object with the object ID @PusServiceBase::packetDestination
|
* will attempt to find a suitable object with the object ID @PusServiceBase::packetDestination
|
||||||
@ -100,14 +111,6 @@ class PusServiceBase : public ExecutableObjectIF,
|
|||||||
friend void Factory::setStaticFrameworkObjectIds();
|
friend void Factory::setStaticFrameworkObjectIds();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
* This constant sets the maximum number of packets accepted per call.
|
|
||||||
* Remember that one packet must be completely handled in one
|
|
||||||
* #handleRequest call.
|
|
||||||
*/
|
|
||||||
static constexpr uint8_t PUS_SERVICE_MAX_RECEPTION = 10;
|
|
||||||
static constexpr uint8_t PSB_DEFAULT_QUEUE_DEPTH = 10;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The passed values are set, but inter-object initialization is
|
* @brief The passed values are set, but inter-object initialization is
|
||||||
* done in the initialize method.
|
* done in the initialize method.
|
||||||
|
@ -17,11 +17,11 @@ TmTcBridge::TmTcBridge(const char* name, object_id_t objectId, object_id_t tcDes
|
|||||||
|
|
||||||
{
|
{
|
||||||
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
|
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
|
||||||
tmTcReceptionQueue = QueueFactory::instance()->createMessageQueue(
|
tmtcReceptionQueue = QueueFactory::instance()->createMessageQueue(
|
||||||
msgQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
msgQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
TmTcBridge::~TmTcBridge() { QueueFactory::instance()->deleteMessageQueue(tmTcReceptionQueue); }
|
TmTcBridge::~TmTcBridge() { QueueFactory::instance()->deleteMessageQueue(tmtcReceptionQueue); }
|
||||||
|
|
||||||
void TmTcBridge::setNumberOfSentPacketsPerCycle(uint32_t sentPacketsPerCycle_) {
|
void TmTcBridge::setNumberOfSentPacketsPerCycle(uint32_t sentPacketsPerCycle_) {
|
||||||
this->sentPacketsPerCycle = sentPacketsPerCycle_;
|
this->sentPacketsPerCycle = sentPacketsPerCycle_;
|
||||||
@ -34,8 +34,7 @@ ReturnValue_t TmTcBridge::setMaxNumberOfPacketsStored(unsigned int maxNumberOfPa
|
|||||||
} else {
|
} else {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "TmTcBridge::setMaxNumberOfPacketsStored: Number of "
|
sif::warning << "TmTcBridge::setMaxNumberOfPacketsStored: Number of "
|
||||||
<< "packets stored exceeds limits. "
|
<< "packets stored exceeds limits. " << "Keeping default value." << std::endl;
|
||||||
<< "Keeping default value." << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
@ -70,7 +69,7 @@ ReturnValue_t TmTcBridge::initialize() {
|
|||||||
|
|
||||||
tmFifo = new DynamicFIFO<store_address_t>(maxNumberOfPacketsStored);
|
tmFifo = new DynamicFIFO<store_address_t>(maxNumberOfPacketsStored);
|
||||||
|
|
||||||
tmTcReceptionQueue->setDefaultDestination(tcDistributor->getRequestQueue());
|
tmtcReceptionQueue->setDefaultDestination(tcDistributor->getRequestQueue());
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,15 +78,13 @@ ReturnValue_t TmTcBridge::performOperation(uint8_t operationCode) {
|
|||||||
result = handleTc();
|
result = handleTc();
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "TmTcBridge::performOperation: "
|
sif::debug << "TmTcBridge::performOperation: " << "Error handling TCs" << std::endl;
|
||||||
<< "Error handling TCs" << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
result = handleTm();
|
result = handleTm();
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "TmTcBridge::performOperation: "
|
sif::debug << "TmTcBridge::performOperation: " << "Error handling TMs" << std::endl;
|
||||||
<< "Error handling TMs" << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -124,8 +121,8 @@ ReturnValue_t TmTcBridge::handleTmQueue() {
|
|||||||
const uint8_t* data = nullptr;
|
const uint8_t* data = nullptr;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
ReturnValue_t status = returnvalue::OK;
|
ReturnValue_t status = returnvalue::OK;
|
||||||
for (ReturnValue_t result = tmTcReceptionQueue->receiveMessage(&message);
|
for (ReturnValue_t result = tmtcReceptionQueue->receiveMessage(&message);
|
||||||
result == returnvalue::OK; result = tmTcReceptionQueue->receiveMessage(&message)) {
|
result == returnvalue::OK; result = tmtcReceptionQueue->receiveMessage(&message)) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 3
|
#if FSFW_VERBOSE_LEVEL >= 3
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::info << "Sent packet counter: " << static_cast<int>(packetSentCounter) << std::endl;
|
sif::info << "Sent packet counter: " << static_cast<int>(packetSentCounter) << std::endl;
|
||||||
@ -241,7 +238,7 @@ void TmTcBridge::registerCommDisconnect() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t TmTcBridge::getReportReceptionQueue(uint8_t virtualChannel) const {
|
MessageQueueId_t TmTcBridge::getReportReceptionQueue(uint8_t virtualChannel) const {
|
||||||
return tmTcReceptionQueue->getId();
|
return tmtcReceptionQueue->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TmTcBridge::printData(uint8_t* data, size_t dataLen) { arrayprinter::print(data, dataLen); }
|
void TmTcBridge::printData(uint8_t* data, size_t dataLen) { arrayprinter::print(data, dataLen); }
|
||||||
@ -253,7 +250,7 @@ uint32_t TmTcBridge::getIdentifier() const {
|
|||||||
|
|
||||||
MessageQueueId_t TmTcBridge::getRequestQueue() const {
|
MessageQueueId_t TmTcBridge::getRequestQueue() const {
|
||||||
// Default implementation: Relay TC messages to TC distributor directly.
|
// Default implementation: Relay TC messages to TC distributor directly.
|
||||||
return tmTcReceptionQueue->getDefaultDestination();
|
return tmtcReceptionQueue->getDefaultDestination();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TmTcBridge::setFifoToOverwriteOldData(bool overwriteOld) { this->overwriteOld = overwriteOld; }
|
void TmTcBridge::setFifoToOverwriteOldData(bool overwriteOld) { this->overwriteOld = overwriteOld; }
|
||||||
|
@ -80,7 +80,7 @@ class TmTcBridge : public AcceptsTelemetryIF,
|
|||||||
|
|
||||||
//! Used to send and receive TMTC messages.
|
//! Used to send and receive TMTC messages.
|
||||||
//! The TmTcMessage class is used to transport messages between tasks.
|
//! The TmTcMessage class is used to transport messages between tasks.
|
||||||
MessageQueueIF* tmTcReceptionQueue = nullptr;
|
MessageQueueIF* tmtcReceptionQueue = nullptr;
|
||||||
|
|
||||||
StorageManagerIF* tmStore = nullptr;
|
StorageManagerIF* tmStore = nullptr;
|
||||||
StorageManagerIF* tcStore = nullptr;
|
StorageManagerIF* tcStore = nullptr;
|
||||||
|
@ -15,7 +15,7 @@ class GpioCookie;
|
|||||||
*/
|
*/
|
||||||
class GpioIF {
|
class GpioIF {
|
||||||
public:
|
public:
|
||||||
virtual ~GpioIF(){};
|
virtual ~GpioIF() {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Called by the GPIO using object.
|
* @brief Called by the GPIO using object.
|
||||||
|
@ -60,7 +60,7 @@ class GpioBase {
|
|||||||
gpio::Levels initValue)
|
gpio::Levels initValue)
|
||||||
: gpioType(gpioType), consumer(consumer), direction(direction), initValue(initValue) {}
|
: gpioType(gpioType), consumer(consumer), direction(direction), initValue(initValue) {}
|
||||||
|
|
||||||
virtual ~GpioBase(){};
|
virtual ~GpioBase() {};
|
||||||
|
|
||||||
// Can be used to cast GpioBase to a concrete child implementation
|
// Can be used to cast GpioBase to a concrete child implementation
|
||||||
gpio::GpioTypes gpioType = gpio::GpioTypes::NONE;
|
gpio::GpioTypes gpioType = gpio::GpioTypes::NONE;
|
||||||
|
@ -10,11 +10,12 @@ using namespace std;
|
|||||||
|
|
||||||
HostFilesystem::HostFilesystem() = default;
|
HostFilesystem::HostFilesystem() = default;
|
||||||
|
|
||||||
ReturnValue_t HostFilesystem::writeToFile(FileOpParams params, const uint8_t *data) {
|
ReturnValue_t HostFilesystem::writeToFile(const char *path_, size_t offset, const uint8_t *data,
|
||||||
if (params.path() == nullptr) {
|
size_t size) {
|
||||||
|
if (path_ == nullptr) {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
path path(params.path());
|
path path(path_);
|
||||||
std::error_code e;
|
std::error_code e;
|
||||||
if (not exists(path, e)) {
|
if (not exists(path, e)) {
|
||||||
return HasFileSystemIF::FILE_DOES_NOT_EXIST;
|
return HasFileSystemIF::FILE_DOES_NOT_EXIST;
|
||||||
@ -25,17 +26,20 @@ ReturnValue_t HostFilesystem::writeToFile(FileOpParams params, const uint8_t *da
|
|||||||
if (file.fail()) {
|
if (file.fail()) {
|
||||||
return HasFileSystemIF::GENERIC_FILE_ERROR;
|
return HasFileSystemIF::GENERIC_FILE_ERROR;
|
||||||
}
|
}
|
||||||
file.seekp(static_cast<unsigned int>(params.offset));
|
file.seekp(static_cast<unsigned int>(offset));
|
||||||
file.write(reinterpret_cast<const char *>(data), static_cast<unsigned int>(params.size));
|
file.write(reinterpret_cast<const char *>(data), static_cast<unsigned int>(size));
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t HostFilesystem::readFromFile(FileOpParams params, uint8_t **buffer, size_t &readSize,
|
ReturnValue_t HostFilesystem::readFromFile(const char *path_, size_t offset, size_t sizeToRead,
|
||||||
size_t maxSize) {
|
uint8_t *buffer, size_t &actuallyRead, size_t maxSize) {
|
||||||
if (params.path() == nullptr) {
|
if (path_ == nullptr) {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
path path(params.path());
|
if (sizeToRead > maxSize) {
|
||||||
|
return SerializeIF::BUFFER_TOO_SHORT;
|
||||||
|
}
|
||||||
|
path path(path_);
|
||||||
std::error_code e;
|
std::error_code e;
|
||||||
if (not exists(path, e)) {
|
if (not exists(path, e)) {
|
||||||
return HasFileSystemIF::FILE_DOES_NOT_EXIST;
|
return HasFileSystemIF::FILE_DOES_NOT_EXIST;
|
||||||
@ -44,23 +48,17 @@ ReturnValue_t HostFilesystem::readFromFile(FileOpParams params, uint8_t **buffer
|
|||||||
if (file.fail()) {
|
if (file.fail()) {
|
||||||
return HasFileSystemIF::GENERIC_FILE_ERROR;
|
return HasFileSystemIF::GENERIC_FILE_ERROR;
|
||||||
}
|
}
|
||||||
auto sizeToRead = static_cast<unsigned int>(params.size);
|
file.seekg(static_cast<unsigned int>(offset));
|
||||||
file.seekg(static_cast<unsigned int>(params.offset));
|
file.read(reinterpret_cast<char *>(buffer), static_cast<long>(sizeToRead));
|
||||||
if (readSize + sizeToRead > maxSize) {
|
actuallyRead = sizeToRead;
|
||||||
return SerializeIF::BUFFER_TOO_SHORT;
|
|
||||||
}
|
|
||||||
file.read(reinterpret_cast<char *>(*buffer), sizeToRead);
|
|
||||||
readSize += sizeToRead;
|
|
||||||
*buffer += sizeToRead;
|
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t HostFilesystem::createFile(FilesystemParams params, const uint8_t *data,
|
ReturnValue_t HostFilesystem::createFile(const char *path_, const uint8_t *data, size_t size) {
|
||||||
size_t size) {
|
if (path_ == nullptr) {
|
||||||
if (params.path == nullptr) {
|
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
path path(params.path);
|
std::filesystem::path path(path_);
|
||||||
std::error_code e;
|
std::error_code e;
|
||||||
if (exists(path, e)) {
|
if (exists(path, e)) {
|
||||||
return HasFileSystemIF::FILE_ALREADY_EXISTS;
|
return HasFileSystemIF::FILE_ALREADY_EXISTS;
|
||||||
@ -87,11 +85,12 @@ ReturnValue_t HostFilesystem::removeFile(const char *path_, FileSystemArgsIF *ar
|
|||||||
return HasFileSystemIF::GENERIC_FILE_ERROR;
|
return HasFileSystemIF::GENERIC_FILE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t HostFilesystem::createDirectory(FilesystemParams params, bool createParentDirs) {
|
ReturnValue_t HostFilesystem::createDirectory(const char *path, bool createParentDirs,
|
||||||
if (params.path == nullptr) {
|
FileSystemArgsIF *args) {
|
||||||
|
if (path == nullptr) {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
path dirPath(params.path);
|
std::filesystem::path dirPath(path);
|
||||||
|
|
||||||
std::error_code e;
|
std::error_code e;
|
||||||
if (exists(dirPath, e)) {
|
if (exists(dirPath, e)) {
|
||||||
@ -110,11 +109,12 @@ ReturnValue_t HostFilesystem::createDirectory(FilesystemParams params, bool crea
|
|||||||
return HasFileSystemIF::GENERIC_DIR_ERROR;
|
return HasFileSystemIF::GENERIC_DIR_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t HostFilesystem::removeDirectory(FilesystemParams params, bool deleteRecurively) {
|
ReturnValue_t HostFilesystem::removeDirectory(const char *path, bool deleteRecurively,
|
||||||
if (params.path == nullptr) {
|
FileSystemArgsIF *args) {
|
||||||
|
if (path == nullptr) {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
path dirPath(params.path);
|
std::filesystem::path dirPath(path);
|
||||||
std::error_code e;
|
std::error_code e;
|
||||||
if (not exists(dirPath, e)) {
|
if (not exists(dirPath, e)) {
|
||||||
return HasFileSystemIF::DIRECTORY_DOES_NOT_EXIST;
|
return HasFileSystemIF::DIRECTORY_DOES_NOT_EXIST;
|
||||||
@ -153,14 +153,14 @@ ReturnValue_t HostFilesystem::rename(const char *oldPath_, const char *newPath_,
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HostFilesystem::fileExists(FilesystemParams params) {
|
bool HostFilesystem::fileExists(const char *path_, FileSystemArgsIF *args) {
|
||||||
path path(params.path);
|
std::filesystem::path path(path_);
|
||||||
std::error_code e;
|
std::error_code e;
|
||||||
return filesystem::exists(path, e);
|
return filesystem::exists(path, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t HostFilesystem::truncateFile(FilesystemParams params) {
|
ReturnValue_t HostFilesystem::truncateFile(const char *path_, FileSystemArgsIF *args) {
|
||||||
path path(params.path);
|
std::filesystem::path path(path_);
|
||||||
std::error_code e;
|
std::error_code e;
|
||||||
if (not filesystem::exists(path, e)) {
|
if (not filesystem::exists(path, e)) {
|
||||||
return FILE_DOES_NOT_EXIST;
|
return FILE_DOES_NOT_EXIST;
|
||||||
@ -170,12 +170,19 @@ ReturnValue_t HostFilesystem::truncateFile(FilesystemParams params) {
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HostFilesystem::isDirectory(const char *path) { return filesystem::is_directory(path); }
|
ReturnValue_t HostFilesystem::isDirectory(const char *path, bool &isDirectory) {
|
||||||
|
isDirectory = filesystem::is_directory(path);
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t HostFilesystem::getBaseFilename(FilesystemParams params, char *nameBuf, size_t maxLen,
|
ReturnValue_t HostFilesystem::getBaseFilename(const char *path, char *nameBuf, size_t maxLen,
|
||||||
size_t &baseNameLen) {
|
size_t &baseNameLen) {
|
||||||
std::string path(params.path);
|
std::string pathAsStr(path);
|
||||||
std::string baseName = path.substr(path.find_last_of("/\\") + 1);
|
size_t lastPos = pathAsStr.find_last_of("/\\");
|
||||||
|
if (lastPos == std::string::npos) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
std::string baseName = pathAsStr.substr(pathAsStr.find_last_of("/\\") + 1);
|
||||||
if (baseName.size() + 1 > maxLen) {
|
if (baseName.size() + 1 > maxLen) {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
@ -185,10 +192,11 @@ ReturnValue_t HostFilesystem::getBaseFilename(FilesystemParams params, char *nam
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HostFilesystem::getFileSize(FilesystemParams params, uint64_t &fileSize) {
|
ReturnValue_t HostFilesystem::getFileSize(const char *path, uint64_t &fileSize,
|
||||||
if (!fileExists(params)) {
|
FileSystemArgsIF *args) {
|
||||||
return false;
|
if (!fileExists(path, args)) {
|
||||||
|
return HasFileSystemIF::FILE_DOES_NOT_EXIST;
|
||||||
}
|
}
|
||||||
fileSize = std::filesystem::file_size(params.path);
|
fileSize = std::filesystem::file_size(path);
|
||||||
return true;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
@ -9,19 +9,23 @@ class HostFilesystem : public HasFileSystemIF {
|
|||||||
public:
|
public:
|
||||||
HostFilesystem();
|
HostFilesystem();
|
||||||
|
|
||||||
ReturnValue_t getBaseFilename(FilesystemParams params, char *nameBuf, size_t maxLen,
|
ReturnValue_t getBaseFilename(const char *path, char *nameBuf, size_t maxLen,
|
||||||
size_t &baseNameLen) override;
|
size_t &baseNameLen) override;
|
||||||
virtual bool getFileSize(FilesystemParams params, uint64_t &fileSize) override;
|
virtual ReturnValue_t getFileSize(const char *path, uint64_t &fileSize,
|
||||||
bool isDirectory(const char *path) override;
|
FileSystemArgsIF *args) override;
|
||||||
bool fileExists(FilesystemParams params) override;
|
ReturnValue_t isDirectory(const char *path, bool &isDirectory) override;
|
||||||
ReturnValue_t truncateFile(FilesystemParams params) override;
|
bool fileExists(const char *path, FileSystemArgsIF *args) override;
|
||||||
ReturnValue_t writeToFile(FileOpParams params, const uint8_t *data) override;
|
ReturnValue_t truncateFile(const char *path, FileSystemArgsIF *args) override;
|
||||||
ReturnValue_t readFromFile(FileOpParams fileOpInfo, uint8_t **buffer, size_t &readSize,
|
ReturnValue_t writeToFile(const char *path, size_t offset, const uint8_t *data,
|
||||||
size_t maxSize) override;
|
size_t size) override;
|
||||||
ReturnValue_t createFile(FilesystemParams params, const uint8_t *data, size_t size) override;
|
ReturnValue_t readFromFile(const char *path, size_t offset, size_t sizeToRead, uint8_t *buffer,
|
||||||
|
size_t &actuallyRead, size_t maxSize) override;
|
||||||
|
ReturnValue_t createFile(const char *path, const uint8_t *data, size_t size) override;
|
||||||
ReturnValue_t removeFile(const char *path, FileSystemArgsIF *args) override;
|
ReturnValue_t removeFile(const char *path, FileSystemArgsIF *args) override;
|
||||||
ReturnValue_t createDirectory(FilesystemParams params, bool createParentDirs) override;
|
ReturnValue_t createDirectory(const char *path, bool createParentDirs,
|
||||||
ReturnValue_t removeDirectory(FilesystemParams params, bool deleteRecurively) override;
|
FileSystemArgsIF *args) override;
|
||||||
|
ReturnValue_t removeDirectory(const char *path, bool deleteRecurively,
|
||||||
|
FileSystemArgsIF *args) override;
|
||||||
ReturnValue_t rename(const char *oldPath, const char *newPath, FileSystemArgsIF *args) override;
|
ReturnValue_t rename(const char *oldPath, const char *newPath, FileSystemArgsIF *args) override;
|
||||||
|
|
||||||
std::error_code errorCode;
|
std::error_code errorCode;
|
||||||
|
@ -418,8 +418,8 @@ ReturnValue_t LinuxLibgpioIF::checkForConflictsById(gpioId_t gpioIdToCheck,
|
|||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "LinuxLibgpioIF::checkForConflictsRegularGpio: Duplicate GPIO "
|
sif::warning << "LinuxLibgpioIF::checkForConflictsRegularGpio: Duplicate GPIO "
|
||||||
"definition with ID "
|
"definition with ID "
|
||||||
<< gpioIdToCheck << " detected. "
|
<< gpioIdToCheck << " detected. " << "Duplicate will be removed from map to add"
|
||||||
<< "Duplicate will be removed from map to add" << std::endl;
|
<< std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printWarning(
|
sif::printWarning(
|
||||||
"LinuxLibgpioIF::checkForConflictsRegularGpio: Duplicate GPIO definition "
|
"LinuxLibgpioIF::checkForConflictsRegularGpio: Duplicate GPIO definition "
|
||||||
|
@ -49,8 +49,7 @@ ReturnValue_t I2cComIF::initializeInterface(CookieIF* cookie) {
|
|||||||
if (not statusPair.second) {
|
if (not statusPair.second) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "I2cComIF::initializeInterface: Failed to insert device with address "
|
sif::error << "I2cComIF::initializeInterface: Failed to insert device with address "
|
||||||
<< i2cAddress << "to I2C device "
|
<< i2cAddress << "to I2C device " << "map" << std::endl;
|
||||||
<< "map" << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
@ -91,8 +90,8 @@ ReturnValue_t I2cComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, s
|
|||||||
auto i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress);
|
auto i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress);
|
||||||
if (i2cDeviceMapIter == i2cDeviceMap.end()) {
|
if (i2cDeviceMapIter == i2cDeviceMap.end()) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "I2cComIF::sendMessage: i2cAddress of Cookie not "
|
sif::error << "I2cComIF::sendMessage: i2cAddress of Cookie not " << "registered in i2cDeviceMap"
|
||||||
<< "registered in i2cDeviceMap" << std::endl;
|
<< std::endl;
|
||||||
#endif
|
#endif
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#include <fsfw_hal/linux/serial/helper.h>
|
#include <fsfw_hal/linux/serial/helper.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <termios.h>
|
||||||
|
|
||||||
|
#include "FSFWConfig.h"
|
||||||
#include "fsfw/serviceinterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
void serial::setMode(struct termios& options, UartModes mode) {
|
void serial::setMode(struct termios& options, UartModes mode) {
|
||||||
@ -108,7 +110,7 @@ void serial::setBaudrate(struct termios& options, UartBaudRate baud) {
|
|||||||
#endif // ! __APPLE__
|
#endif // ! __APPLE__
|
||||||
default:
|
default:
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "UartComIF::configureBaudrate: Baudrate not supported" << std::endl;
|
sif::warning << "serial::configureBaudrate: Baudrate not supported" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -153,15 +155,16 @@ int serial::readCountersAndErrors(int serialPort, serial_icounter_struct& icount
|
|||||||
}
|
}
|
||||||
|
|
||||||
void serial::setStopbits(struct termios& options, StopBits bits) {
|
void serial::setStopbits(struct termios& options, StopBits bits) {
|
||||||
|
// Regular case: One stop bit.
|
||||||
|
options.c_cflag &= ~CSTOPB;
|
||||||
if (bits == StopBits::TWO_STOP_BITS) {
|
if (bits == StopBits::TWO_STOP_BITS) {
|
||||||
// Use two stop bits
|
// Use two stop bits
|
||||||
options.c_cflag |= CSTOPB;
|
options.c_cflag |= CSTOPB;
|
||||||
} else {
|
|
||||||
// Clear stop field, only one stop bit used in communication
|
|
||||||
options.c_cflag &= ~CSTOPB;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void serial::flushRxBuf(int fd) { tcflush(fd, TCIFLUSH); }
|
void serial::flushRxBuf(int fd) { tcflush(fd, TCIFLUSH); }
|
||||||
|
|
||||||
|
void serial::flushTxBuf(int fd) { tcflush(fd, TCOFLUSH); }
|
||||||
|
|
||||||
void serial::flushTxRxBuf(int fd) { tcflush(fd, TCIOFLUSH); }
|
void serial::flushTxRxBuf(int fd) { tcflush(fd, TCIOFLUSH); }
|
||||||
|
@ -65,6 +65,7 @@ void setParity(struct termios& options, Parity parity);
|
|||||||
void ignoreCtrlLines(struct termios& options);
|
void ignoreCtrlLines(struct termios& options);
|
||||||
|
|
||||||
void flushRxBuf(int fd);
|
void flushRxBuf(int fd);
|
||||||
|
void flushTxBuf(int fd);
|
||||||
void flushTxRxBuf(int fd);
|
void flushTxRxBuf(int fd);
|
||||||
|
|
||||||
int readCountersAndErrors(int serialPort, serial_icounter_struct& icounter);
|
int readCountersAndErrors(int serialPort, serial_icounter_struct& icounter);
|
||||||
|
@ -197,9 +197,8 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
|||||||
if (result == MutexIF::MUTEX_TIMEOUT) {
|
if (result == MutexIF::MUTEX_TIMEOUT) {
|
||||||
sif::error << "SpiComIF::sendMessage: Lock timeout" << std::endl;
|
sif::error << "SpiComIF::sendMessage: Lock timeout" << std::endl;
|
||||||
} else {
|
} else {
|
||||||
sif::error << "SpiComIF::sendMessage: Failed to lock mutex with code "
|
sif::error << "SpiComIF::sendMessage: Failed to lock mutex with code " << "0x" << std::hex
|
||||||
<< "0x" << std::hex << std::setfill('0') << std::setw(4) << result << std::dec
|
<< std::setfill('0') << std::setw(4) << result << std::dec << std::endl;
|
||||||
<< std::endl;
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
sif::printError("SpiComIF::sendMessage: Failed to lock mutex with code %d\n", result);
|
sif::printError("SpiComIF::sendMessage: Failed to lock mutex with code %d\n", result);
|
||||||
@ -307,9 +306,8 @@ ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) {
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "SpiComIF::sendMessage: Failed to lock mutex with code "
|
sif::error << "SpiComIF::sendMessage: Failed to lock mutex with code " << "0x" << std::hex
|
||||||
<< "0x" << std::hex << std::setfill('0') << std::setw(4) << result << std::dec
|
<< std::setfill('0') << std::setw(4) << result << std::dec << std::endl;
|
||||||
<< std::endl;
|
|
||||||
#else
|
#else
|
||||||
sif::printError("SpiComIF::sendMessage: Failed to lock mutex with code %d\n", result);
|
sif::printError("SpiComIF::sendMessage: Failed to lock mutex with code %d\n", result);
|
||||||
#endif
|
#endif
|
||||||
|
@ -12,10 +12,10 @@ namespace stm32h7 {
|
|||||||
* and the second entry is the pin number
|
* and the second entry is the pin number
|
||||||
*/
|
*/
|
||||||
struct GpioCfg {
|
struct GpioCfg {
|
||||||
GpioCfg() : port(nullptr), pin(0), altFnc(0){};
|
GpioCfg() : port(nullptr), pin(0), altFnc(0) {};
|
||||||
|
|
||||||
GpioCfg(GPIO_TypeDef* port, uint16_t pin, uint8_t altFnc = 0)
|
GpioCfg(GPIO_TypeDef* port, uint16_t pin, uint8_t altFnc = 0)
|
||||||
: port(port), pin(pin), altFnc(altFnc){};
|
: port(port), pin(pin), altFnc(altFnc) {};
|
||||||
GPIO_TypeDef* port;
|
GPIO_TypeDef* port;
|
||||||
uint16_t pin;
|
uint16_t pin;
|
||||||
uint8_t altFnc;
|
uint8_t altFnc;
|
||||||
|
@ -37,7 +37,7 @@ struct MspCfgBase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct MspPollingConfigStruct : public MspCfgBase {
|
struct MspPollingConfigStruct : public MspCfgBase {
|
||||||
MspPollingConfigStruct() : MspCfgBase(){};
|
MspPollingConfigStruct() : MspCfgBase() {};
|
||||||
MspPollingConfigStruct(stm32h7::GpioCfg sck, stm32h7::GpioCfg mosi, stm32h7::GpioCfg miso,
|
MspPollingConfigStruct(stm32h7::GpioCfg sck, stm32h7::GpioCfg mosi, stm32h7::GpioCfg miso,
|
||||||
mspCb cleanupCb = nullptr, mspCb setupCb = nullptr)
|
mspCb cleanupCb = nullptr, mspCb setupCb = nullptr)
|
||||||
: MspCfgBase(sck, mosi, miso, cleanupCb, setupCb) {}
|
: MspCfgBase(sck, mosi, miso, cleanupCb, setupCb) {}
|
||||||
@ -46,7 +46,7 @@ struct MspPollingConfigStruct : public MspCfgBase {
|
|||||||
/* A valid instance of this struct must be passed to the MSP initialization function as a void*
|
/* A valid instance of this struct must be passed to the MSP initialization function as a void*
|
||||||
argument */
|
argument */
|
||||||
struct MspIrqConfigStruct : public MspPollingConfigStruct {
|
struct MspIrqConfigStruct : public MspPollingConfigStruct {
|
||||||
MspIrqConfigStruct() : MspPollingConfigStruct(){};
|
MspIrqConfigStruct() : MspPollingConfigStruct() {};
|
||||||
MspIrqConfigStruct(stm32h7::GpioCfg sck, stm32h7::GpioCfg mosi, stm32h7::GpioCfg miso,
|
MspIrqConfigStruct(stm32h7::GpioCfg sck, stm32h7::GpioCfg mosi, stm32h7::GpioCfg miso,
|
||||||
mspCb cleanupCb = nullptr, mspCb setupCb = nullptr)
|
mspCb cleanupCb = nullptr, mspCb setupCb = nullptr)
|
||||||
: MspPollingConfigStruct(sck, mosi, miso, cleanupCb, setupCb) {}
|
: MspPollingConfigStruct(sck, mosi, miso, cleanupCb, setupCb) {}
|
||||||
@ -64,7 +64,7 @@ struct MspIrqConfigStruct : public MspPollingConfigStruct {
|
|||||||
/* A valid instance of this struct must be passed to the MSP initialization function as a void*
|
/* A valid instance of this struct must be passed to the MSP initialization function as a void*
|
||||||
argument */
|
argument */
|
||||||
struct MspDmaConfigStruct : public MspIrqConfigStruct {
|
struct MspDmaConfigStruct : public MspIrqConfigStruct {
|
||||||
MspDmaConfigStruct() : MspIrqConfigStruct(){};
|
MspDmaConfigStruct() : MspIrqConfigStruct() {};
|
||||||
MspDmaConfigStruct(stm32h7::GpioCfg sck, stm32h7::GpioCfg mosi, stm32h7::GpioCfg miso,
|
MspDmaConfigStruct(stm32h7::GpioCfg sck, stm32h7::GpioCfg mosi, stm32h7::GpioCfg miso,
|
||||||
mspCb cleanupCb = nullptr, mspCb setupCb = nullptr)
|
mspCb cleanupCb = nullptr, mspCb setupCb = nullptr)
|
||||||
: MspIrqConfigStruct(sck, mosi, miso, cleanupCb, setupCb) {}
|
: MspIrqConfigStruct(sck, mosi, miso, cleanupCb, setupCb) {}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
target_sources(
|
target_sources(
|
||||||
${FSFW_TEST_TGT} PRIVATE testCfdp.cpp testOtherTlvs.cpp
|
${FSFW_TEST_TGT}
|
||||||
testReservedMsgCreator.cpp testTlv.cpp testLvs.cpp)
|
PRIVATE testCfdp.cpp testOtherTlvs.cpp testReservedMsgCreator.cpp testTlv.cpp
|
||||||
|
testLvs.cpp PduSenderMock.cpp)
|
||||||
|
|
||||||
add_subdirectory(handler)
|
add_subdirectory(handler)
|
||||||
add_subdirectory(pdu)
|
add_subdirectory(pdu)
|
||||||
|
1
unittests/cfdp/PduSenderMock.cpp
Normal file
1
unittests/cfdp/PduSenderMock.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "PduSenderMock.h"
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user