Update FSFW from upstream #71
@ -23,12 +23,11 @@ cfdp::DestHandler::DestHandler(DestHandlerParams params, FsfwParams fsfwParams)
|
||||
tp.pduConf.direction = cfdp::Direction::TOWARDS_SENDER;
|
||||
}
|
||||
|
||||
const cfdp::DestFsmResult& cfdp::DestHandler::performStateMachine() {
|
||||
const cfdp::DestHandler::FsmResult& cfdp::DestHandler::performStateMachine() {
|
||||
ReturnValue_t result;
|
||||
uint8_t errorIdx = 0;
|
||||
fsmRes.callStatus = CallStatus::CALL_AFTER_DELAY;
|
||||
fsmRes.result = OK;
|
||||
if (step == TransactionStep::IDLE) {
|
||||
fsmRes.resetOfIteration();
|
||||
if (fsmRes.step == TransactionStep::IDLE) {
|
||||
for (auto infoIter = dp.packetListRef.begin(); infoIter != dp.packetListRef.end();) {
|
||||
if (infoIter->pduType == PduType::FILE_DIRECTIVE and
|
||||
infoIter->directiveType == FileDirectives::METADATA) {
|
||||
@ -42,7 +41,7 @@ const cfdp::DestFsmResult& cfdp::DestHandler::performStateMachine() {
|
||||
}
|
||||
infoIter++;
|
||||
}
|
||||
if (step == TransactionStep::IDLE) {
|
||||
if (fsmRes.step == TransactionStep::IDLE) {
|
||||
// To decrease the already high complexity of the software, all packets arriving before
|
||||
// a metadata PDU are deleted.
|
||||
for (auto infoIter = dp.packetListRef.begin(); infoIter != dp.packetListRef.end();) {
|
||||
@ -52,13 +51,13 @@ const cfdp::DestFsmResult& cfdp::DestHandler::performStateMachine() {
|
||||
dp.packetListRef.clear();
|
||||
}
|
||||
|
||||
if (step != TransactionStep::IDLE) {
|
||||
if (fsmRes.step != TransactionStep::IDLE) {
|
||||
fsmRes.callStatus = CallStatus::CALL_AGAIN;
|
||||
}
|
||||
return updateFsmRes(errorIdx);
|
||||
}
|
||||
if (cfdpState == CfdpStates::BUSY_CLASS_1_NACKED) {
|
||||
if (step == TransactionStep::RECEIVING_FILE_DATA_PDUS) {
|
||||
if (fsmRes.state == CfdpStates::BUSY_CLASS_1_NACKED) {
|
||||
if (fsmRes.step == TransactionStep::RECEIVING_FILE_DATA_PDUS) {
|
||||
for (auto infoIter = dp.packetListRef.begin(); infoIter != dp.packetListRef.end();) {
|
||||
if (infoIter->pduType == PduType::FILE_DATA) {
|
||||
result = handleFileDataPdu(*infoIter);
|
||||
@ -83,14 +82,14 @@ const cfdp::DestFsmResult& cfdp::DestHandler::performStateMachine() {
|
||||
infoIter++;
|
||||
}
|
||||
}
|
||||
if (step == TransactionStep::TRANSFER_COMPLETION) {
|
||||
if (fsmRes.step == TransactionStep::TRANSFER_COMPLETION) {
|
||||
result = handleTransferCompletion();
|
||||
if (result != OK and errorIdx < 3) {
|
||||
fsmRes.errorCodes[errorIdx] = result;
|
||||
errorIdx++;
|
||||
}
|
||||
}
|
||||
if (step == TransactionStep::SENDING_FINISHED_PDU) {
|
||||
if (fsmRes.step == TransactionStep::SENDING_FINISHED_PDU) {
|
||||
result = sendFinishedPdu();
|
||||
if (result != OK and errorIdx < 3) {
|
||||
fsmRes.errorCodes[errorIdx] = result;
|
||||
@ -100,7 +99,7 @@ const cfdp::DestFsmResult& cfdp::DestHandler::performStateMachine() {
|
||||
}
|
||||
return updateFsmRes(errorIdx);
|
||||
}
|
||||
if (cfdpState == CfdpStates::BUSY_CLASS_2_ACKED) {
|
||||
if (fsmRes.state == CfdpStates::BUSY_CLASS_2_ACKED) {
|
||||
// TODO: Will be implemented at a later stage
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "CFDP state machine for acknowledged mode not implemented yet" << std::endl;
|
||||
@ -225,11 +224,11 @@ ReturnValue_t cfdp::DestHandler::handleEofPdu(const cfdp::PacketInfo& info) {
|
||||
}
|
||||
tp.fileSize.setFileSize(fileSizeFromEof, std::nullopt);
|
||||
}
|
||||
if (step == TransactionStep::RECEIVING_FILE_DATA_PDUS) {
|
||||
if (cfdpState == CfdpStates::BUSY_CLASS_1_NACKED) {
|
||||
step = TransactionStep::TRANSFER_COMPLETION;
|
||||
} else if (cfdpState == CfdpStates::BUSY_CLASS_2_ACKED) {
|
||||
step = TransactionStep::SENDING_ACK_PDU;
|
||||
if (fsmRes.step == TransactionStep::RECEIVING_FILE_DATA_PDUS) {
|
||||
if (fsmRes.state == CfdpStates::BUSY_CLASS_1_NACKED) {
|
||||
fsmRes.step = TransactionStep::TRANSFER_COMPLETION;
|
||||
} else if (fsmRes.state == CfdpStates::BUSY_CLASS_2_ACKED) {
|
||||
fsmRes.step = TransactionStep::SENDING_ACK_PDU;
|
||||
}
|
||||
}
|
||||
return returnvalue::OK;
|
||||
@ -272,15 +271,15 @@ ReturnValue_t cfdp::DestHandler::handleMetadataParseError(ReturnValue_t result,
|
||||
}
|
||||
|
||||
ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, MetadataInfo& info) {
|
||||
if (cfdpState != CfdpStates::IDLE) {
|
||||
if (fsmRes.state != CfdpStates::IDLE) {
|
||||
// According to standard, discard metadata PDU if we are busy
|
||||
return returnvalue::OK;
|
||||
}
|
||||
step = TransactionStep::TRANSACTION_START;
|
||||
fsmRes.step = TransactionStep::TRANSACTION_START;
|
||||
if (reader.getTransmissionMode() == TransmissionModes::UNACKNOWLEDGED) {
|
||||
cfdpState = CfdpStates::BUSY_CLASS_1_NACKED;
|
||||
fsmRes.state = CfdpStates::BUSY_CLASS_1_NACKED;
|
||||
} else if (reader.getTransmissionMode() == TransmissionModes::ACKNOWLEDGED) {
|
||||
cfdpState = CfdpStates::BUSY_CLASS_2_ACKED;
|
||||
fsmRes.state = CfdpStates::BUSY_CLASS_2_ACKED;
|
||||
}
|
||||
tp.checksumType = info.getChecksumType();
|
||||
tp.closureRequested = info.isClosureRequested();
|
||||
@ -313,7 +312,7 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, Met
|
||||
#endif
|
||||
return FAILED;
|
||||
}
|
||||
step = TransactionStep::RECEIVING_FILE_DATA_PDUS;
|
||||
fsmRes.step = TransactionStep::RECEIVING_FILE_DATA_PDUS;
|
||||
MetadataRecvdParams params(tp.transactionId, tp.pduConf.sourceId);
|
||||
params.fileSize = tp.fileSize.getSize();
|
||||
params.destFileName = tp.destName.data();
|
||||
@ -324,7 +323,7 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, Met
|
||||
return OK;
|
||||
}
|
||||
|
||||
cfdp::CfdpStates cfdp::DestHandler::getCfdpState() const { return cfdpState; }
|
||||
cfdp::CfdpStates cfdp::DestHandler::getCfdpState() const { return fsmRes.state; }
|
||||
|
||||
ReturnValue_t cfdp::DestHandler::handleTransferCompletion() {
|
||||
ReturnValue_t result;
|
||||
@ -339,14 +338,14 @@ ReturnValue_t cfdp::DestHandler::handleTransferCompletion() {
|
||||
result = noticeOfCompletion();
|
||||
if (result != OK) {
|
||||
}
|
||||
if (cfdpState == CfdpStates::BUSY_CLASS_1_NACKED) {
|
||||
if (fsmRes.state == CfdpStates::BUSY_CLASS_1_NACKED) {
|
||||
if (tp.closureRequested) {
|
||||
step = TransactionStep::SENDING_FINISHED_PDU;
|
||||
fsmRes.step = TransactionStep::SENDING_FINISHED_PDU;
|
||||
} else {
|
||||
finish();
|
||||
}
|
||||
} else if (cfdpState == CfdpStates::BUSY_CLASS_2_ACKED) {
|
||||
step = TransactionStep::SENDING_FINISHED_PDU;
|
||||
} else if (fsmRes.state == CfdpStates::BUSY_CLASS_2_ACKED) {
|
||||
fsmRes.step = TransactionStep::SENDING_FINISHED_PDU;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
@ -354,8 +353,8 @@ ReturnValue_t cfdp::DestHandler::handleTransferCompletion() {
|
||||
void cfdp::DestHandler::finish() {
|
||||
tp.reset();
|
||||
dp.packetListRef.clear();
|
||||
cfdpState = CfdpStates::IDLE;
|
||||
step = TransactionStep::IDLE;
|
||||
fsmRes.state = CfdpStates::IDLE;
|
||||
fsmRes.step = TransactionStep::IDLE;
|
||||
}
|
||||
|
||||
ReturnValue_t cfdp::DestHandler::checksumVerification() {
|
||||
@ -430,12 +429,15 @@ ReturnValue_t cfdp::DestHandler::sendFinishedPdu() {
|
||||
// TODO: Error handling and event, this is a non CFDP specific error (most likely store is full)
|
||||
return result;
|
||||
}
|
||||
fsmRes.packetsSent++;
|
||||
return OK;
|
||||
}
|
||||
|
||||
cfdp::DestHandler::TransactionStep cfdp::DestHandler::getTransactionStep() const { return step; }
|
||||
cfdp::DestHandler::TransactionStep cfdp::DestHandler::getTransactionStep() const {
|
||||
return fsmRes.step;
|
||||
}
|
||||
|
||||
const cfdp::DestFsmResult& cfdp::DestHandler::updateFsmRes(uint8_t errors) {
|
||||
const cfdp::DestHandler::FsmResult& cfdp::DestHandler::updateFsmRes(uint8_t errors) {
|
||||
fsmRes.errors = errors;
|
||||
fsmRes.result = OK;
|
||||
if (fsmRes.errors > 0) {
|
||||
|
@ -72,14 +72,6 @@ struct FsfwParams {
|
||||
|
||||
enum class CallStatus { DONE, CALL_AFTER_DELAY, CALL_AGAIN };
|
||||
|
||||
struct DestFsmResult {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
CallStatus callStatus = CallStatus::CALL_AFTER_DELAY;
|
||||
uint32_t packetsSent = 0;
|
||||
uint8_t errors = 0;
|
||||
std::array<ReturnValue_t, 3> errorCodes = {};
|
||||
};
|
||||
|
||||
class DestHandler {
|
||||
public:
|
||||
enum class TransactionStep {
|
||||
@ -90,6 +82,24 @@ class DestHandler {
|
||||
TRANSFER_COMPLETION = 4,
|
||||
SENDING_FINISHED_PDU = 5
|
||||
};
|
||||
|
||||
struct FsmResult {
|
||||
public:
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
CallStatus callStatus = CallStatus::CALL_AFTER_DELAY;
|
||||
TransactionStep step = TransactionStep::IDLE;
|
||||
CfdpStates state = CfdpStates::IDLE;
|
||||
uint32_t packetsSent = 0;
|
||||
uint8_t errors = 0;
|
||||
std::array<ReturnValue_t, 3> errorCodes = {};
|
||||
void resetOfIteration() {
|
||||
result = returnvalue::OK;
|
||||
callStatus = CallStatus::CALL_AFTER_DELAY;
|
||||
packetsSent = 0;
|
||||
errors = 0;
|
||||
errorCodes.fill(returnvalue::OK);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Will be returned if it is advisable to call the state machine operation call again
|
||||
*/
|
||||
@ -103,7 +113,7 @@ class DestHandler {
|
||||
* - @c returnvalue::OK State machine OK for this execution cycle
|
||||
* - @c CALL_FSM_AGAIN State machine should be called again.
|
||||
*/
|
||||
const DestFsmResult& performStateMachine();
|
||||
const FsmResult& performStateMachine();
|
||||
|
||||
ReturnValue_t passPacket(PacketInfo packet);
|
||||
|
||||
@ -149,14 +159,12 @@ class DestHandler {
|
||||
RemoteEntityCfg* remoteCfg = nullptr;
|
||||
};
|
||||
|
||||
TransactionStep step = TransactionStep::IDLE;
|
||||
CfdpStates cfdpState = CfdpStates::IDLE;
|
||||
std::vector<cfdp::Tlv> tlvVec;
|
||||
std::vector<cfdp::Tlv> userTlvVec;
|
||||
DestHandlerParams dp;
|
||||
FsfwParams fp;
|
||||
TransactionParams tp;
|
||||
DestFsmResult fsmRes;
|
||||
FsmResult fsmRes;
|
||||
|
||||
ReturnValue_t startTransaction(MetadataPduReader& reader, MetadataInfo& info);
|
||||
ReturnValue_t handleMetadataPdu(const PacketInfo& info);
|
||||
@ -168,7 +176,7 @@ class DestHandler {
|
||||
ReturnValue_t sendFinishedPdu();
|
||||
ReturnValue_t noticeOfCompletion();
|
||||
ReturnValue_t checksumVerification();
|
||||
const DestFsmResult& updateFsmRes(uint8_t errors);
|
||||
const FsmResult& updateFsmRes(uint8_t errors);
|
||||
void finish();
|
||||
};
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
class FileSystemArgsIF {
|
||||
public:
|
||||
virtual ~FileSystemArgsIF(){};
|
||||
virtual ~FileSystemArgsIF() = default;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_MEMORY_FILESYSTEMARGS_H_ */
|
||||
|
@ -73,6 +73,15 @@ class HasFileSystemIF {
|
||||
return MessageQueueIF::NO_QUEUE;
|
||||
}
|
||||
|
||||
virtual bool fileExists(FilesystemParams params) = 0;
|
||||
|
||||
/**
|
||||
* Truncate a file, deleting its contents and setting its size to 0 accordingly.
|
||||
* @param params
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t truncateFile(FilesystemParams params) = 0;
|
||||
|
||||
/**
|
||||
* @brief Generic function to append to file.
|
||||
* @param fileOpInfo General information: File name, size to write, offset, additional arguments
|
||||
|
@ -144,3 +144,17 @@ ReturnValue_t HostFilesystem::rename(const char *oldPath_, const char *newPath_,
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
bool HostFilesystem::fileExists(FilesystemParams params) {
|
||||
path path(params.path);
|
||||
return filesystem::exists(path);
|
||||
}
|
||||
|
||||
ReturnValue_t HostFilesystem::truncateFile(FilesystemParams params) {
|
||||
path path(params.path);
|
||||
if (not filesystem::exists(path)) {
|
||||
return FILE_DOES_NOT_EXIST;
|
||||
}
|
||||
ofstream of(path);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
@ -8,6 +8,9 @@
|
||||
class HostFilesystem : public HasFileSystemIF {
|
||||
public:
|
||||
HostFilesystem();
|
||||
|
||||
bool fileExists(FilesystemParams params) override;
|
||||
ReturnValue_t truncateFile(FilesystemParams params) override;
|
||||
ReturnValue_t writeToFile(FileOpParams params, const uint8_t *data) override;
|
||||
ReturnValue_t readFromFile(FileOpParams fileOpInfo, uint8_t **buffer, size_t &readSize,
|
||||
size_t maxSize) override;
|
||||
|
@ -56,7 +56,7 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") {
|
||||
}
|
||||
|
||||
SECTION("Empty File Transfer") {
|
||||
const DestFsmResult& res = destHandler.performStateMachine();
|
||||
const DestHandler::FsmResult& res = destHandler.performStateMachine();
|
||||
CHECK(res.result == OK);
|
||||
FileSize size(0);
|
||||
std::string srcNameString = "hello.txt";
|
||||
@ -76,6 +76,8 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") {
|
||||
packetInfoList.push_back(packetInfo);
|
||||
destHandler.performStateMachine();
|
||||
CHECK(res.result == OK);
|
||||
CHECK(res.callStatus == CallStatus::CALL_AGAIN);
|
||||
destHandler.performStateMachine();
|
||||
}
|
||||
|
||||
SECTION("Small File Transfer") {}
|
||||
|
@ -124,3 +124,17 @@ void FilesystemMock::reset() {
|
||||
std::queue<RenameInfo> empty;
|
||||
std::swap(renameQueue, empty);
|
||||
}
|
||||
|
||||
bool FilesystemMock::fileExists(FilesystemParams params) {
|
||||
std::string filename(params.path);
|
||||
auto iter = fileMap.find(filename);
|
||||
if (iter == fileMap.end()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ReturnValue_t FilesystemMock::truncateFile(FilesystemParams params) {
|
||||
truncateCalledOnFile = params.path;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
@ -53,8 +53,12 @@ class FilesystemMock : public HasFileSystemIF {
|
||||
std::string newName;
|
||||
};
|
||||
std::queue<RenameInfo> renameQueue;
|
||||
|
||||
std::string truncateCalledOnFile;
|
||||
ReturnValue_t feedFile(const std::string &filename, std::ifstream &file);
|
||||
|
||||
bool fileExists(FilesystemParams params) override;
|
||||
ReturnValue_t truncateFile(FilesystemParams params) override;
|
||||
|
||||
ReturnValue_t writeToFile(FileOpParams params, const uint8_t *data) override;
|
||||
ReturnValue_t readFromFile(FileOpParams params, uint8_t **buffer, size_t &readSize,
|
||||
size_t maxSize) override;
|
||||
|
Loading…
Reference in New Issue
Block a user