fsfw/src/fsfw/cfdp/handler/SourceHandler.cpp

154 lines
4.8 KiB
C++
Raw Normal View History

2022-09-14 19:29:43 +02:00
#include "SourceHandler.h"
2023-06-30 11:36:19 +02:00
2023-07-17 09:53:23 +02:00
#include <etl/crc32.h>
2023-07-17 11:37:20 +02:00
2023-07-17 09:53:23 +02:00
#include <array>
2023-07-17 11:37:20 +02:00
#include "fsfw/filesystem/HasFileSystemIF.h"
2023-07-17 09:53:23 +02:00
using namespace returnvalue;
2023-07-17 10:25:09 +02:00
cfdp::SourceHandler::SourceHandler(SourceHandlerParams params, FsfwParams fsfwParams)
2023-07-17 10:15:06 +02:00
: transactionParams(params.maxFilePathSize),
sourceParams(std::move(params)),
fsfwParams(fsfwParams) {}
2023-07-17 09:53:23 +02:00
2023-07-17 15:21:22 +02:00
cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() {
2023-07-17 15:11:51 +02:00
ReturnValue_t result;
2023-07-14 15:56:38 +02:00
if (step == TransactionStep::IDLE) {
step = TransactionStep::TRANSACTION_START;
}
if (step == TransactionStep::TRANSACTION_START) {
step = TransactionStep::CRC_PROCEDURE;
}
if (step == TransactionStep::CRC_PROCEDURE) {
2023-07-17 15:11:51 +02:00
result = checksumGeneration();
2023-07-17 09:53:23 +02:00
if (result != OK) {
// TODO: Some error handling
}
2023-07-17 15:03:08 +02:00
step = TransactionStep::SENDING_METADATA;
2023-07-14 15:56:38 +02:00
}
if (step == TransactionStep::SENDING_METADATA) {
2023-07-17 15:11:51 +02:00
result = prepareAndSendMetadataPdu();
if (result != OK) {
// TODO: Error handling
}
2023-07-17 15:21:22 +02:00
return fsmResult;
2023-07-14 15:56:38 +02:00
}
if (step == TransactionStep::SENDING_FILE_DATA) {
2023-07-17 15:21:22 +02:00
result = prepareAndSendNextFileDataPdu();
2023-07-17 15:11:51 +02:00
if (result != OK) {
// TODO: Error handling
}
2023-07-17 15:21:22 +02:00
return fsmResult;
2023-07-14 15:56:38 +02:00
}
if (step == TransactionStep::SENDING_EOF) {
2023-07-17 15:21:22 +02:00
result = prepareAndSendEofPdu();
2023-07-17 15:11:51 +02:00
if (result != OK) {
// TODO: Error handling
}
2023-07-17 15:21:22 +02:00
return fsmResult;
2023-07-14 15:56:38 +02:00
}
if (step == TransactionStep::WAIT_FOR_FINISH) {
// TODO: In case this is a request with closure, wait for finish.
2023-07-17 15:11:51 +02:00
// Done, issue notice of completion
step = TransactionStep::NOTICE_OF_COMPLETION;
2023-07-14 15:56:38 +02:00
}
if (step == TransactionStep::NOTICE_OF_COMPLETION) {
// TODO: Notice of completion
2023-07-17 15:11:51 +02:00
// We are done, go back to idle state.
// TODO: Possible reset state?
step = TransactionStep::IDLE;
state = CfdpState::IDLE;
2023-07-14 15:56:38 +02:00
}
2023-07-17 15:21:22 +02:00
return fsmResult;
2023-07-14 15:56:38 +02:00
}
2023-07-17 15:21:22 +02:00
cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::stateMachine() {
2023-07-14 15:56:38 +02:00
if (state == cfdp::CfdpState::IDLE) {
2023-07-17 15:21:22 +02:00
return fsmResult;
2023-07-14 15:56:38 +02:00
}
if (state == cfdp::CfdpState::BUSY_CLASS_1_NACKED) {
return fsmNacked();
}
2023-07-17 15:21:22 +02:00
return fsmResult;
2023-07-14 15:56:38 +02:00
}
2023-07-17 09:53:23 +02:00
ReturnValue_t cfdp::SourceHandler::checksumGeneration() {
std::array<uint8_t, 1024> buf{};
etl::crc32 crcCalc;
uint64_t currentOffset = 0;
FileOpParams params(transactionParams.destName.data(), transactionParams.fileSize.value());
while (currentOffset < transactionParams.fileSize.value()) {
uint64_t readLen;
if (currentOffset + buf.size() > transactionParams.fileSize.value()) {
readLen = transactionParams.fileSize.value() - currentOffset;
} else {
readLen = buf.size();
}
if (readLen > 0) {
params.offset = currentOffset;
params.size = readLen;
auto result = sourceParams.user.vfs.readFromFile(params, buf.data(), buf.size());
if (result != OK) {
// 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
return FAILED;
}
crcCalc.add(buf.begin(), buf.begin() + readLen);
}
currentOffset += readLen;
}
transactionParams.crc = crcCalc.value();
return OK;
}
2023-07-17 10:15:06 +02:00
2023-07-17 13:43:48 +02:00
ReturnValue_t cfdp::SourceHandler::putRequest(PutRequestFull& putRequest, RemoteEntityCfg& cfg) {
2023-07-17 15:03:08 +02:00
if (state != CfdpState::IDLE) {
return SOURCE_TRANSACTION_PENDING;
}
transactionParams.closureRequested = putRequest.closureRequested;
transactionParams.destId = putRequest.destId;
transactionParams.transmissionMode = putRequest.transmissionMode;
2023-07-17 15:03:08 +02:00
if (transactionParams.transmissionMode == TransmissionMode::ACKNOWLEDGED) {
state = cfdp::CfdpState::BUSY_CLASS_2_ACKED;
} else if (transactionParams.transmissionMode == TransmissionMode::UNACKNOWLEDGED) {
state = cfdp::CfdpState::BUSY_CLASS_1_NACKED;
}
step = TransactionStep::IDLE;
if (transactionParams.transmissionMode == TransmissionMode::ACKNOWLEDGED) {
}
if (putRequest.sourceNameSize > transactionParams.sourceName.size()) {
return FAILED;
}
std::memcpy(transactionParams.sourceName.data(), putRequest.sourceName,
putRequest.sourceNameSize);
if (putRequest.destNameSize > transactionParams.destName.size()) {
return FAILED;
}
std::memcpy(transactionParams.destName.data(), putRequest.destName, putRequest.destNameSize);
2023-07-17 14:54:45 +02:00
currentRemoteCfg = cfg;
return OK;
2023-07-17 13:43:48 +02:00
}
2023-07-17 15:11:51 +02:00
ReturnValue_t cfdp::SourceHandler::prepareAndSendMetadataPdu() {
// TODO: Implement
// Advance FSM if everythings works
step = TransactionStep::SENDING_FILE_DATA;
return OK;
}
2023-07-17 15:21:22 +02:00
ReturnValue_t cfdp::SourceHandler::prepareAndSendNextFileDataPdu() {
2023-07-17 15:11:51 +02:00
// TODO: Implement
// Advance FSM after all file data PDUs were sent
step = TransactionStep::SENDING_EOF;
return OK;
}
2023-07-17 15:21:22 +02:00
ReturnValue_t cfdp::SourceHandler::prepareAndSendEofPdu() {
2023-07-17 15:11:51 +02:00
// TODO: Implement
step = TransactionStep::WAIT_FOR_FINISH;
return OK;
}