|
|
|
@ -178,16 +178,25 @@ ReturnValue_t cfdp::DestHandler::handleFileDataPdu(const cfdp::PacketInfo& info)
|
|
|
|
|
dp.user.fileSegmentRecvdIndication(segParams);
|
|
|
|
|
}
|
|
|
|
|
result = dp.user.vfs.writeToFile(fileOpParams, fileData);
|
|
|
|
|
if (offset.value() + fileSegmentLen > tp.progress) {
|
|
|
|
|
tp.progress = offset.value() + fileSegmentLen;
|
|
|
|
|
}
|
|
|
|
|
if (result != returnvalue::OK) {
|
|
|
|
|
// TODO: Proper Error handling
|
|
|
|
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
|
|
|
sif::error << "File write error" << std::endl;
|
|
|
|
|
sif::error << "cfdp::DestHandler: VFS file write error with code 0x" << std::hex << std::setw(2)
|
|
|
|
|
<< result << std::endl;
|
|
|
|
|
#endif
|
|
|
|
|
tp.vfsErrorCount++;
|
|
|
|
|
if (tp.vfsErrorCount < 3) {
|
|
|
|
|
// TODO: Provide execution step as parameter
|
|
|
|
|
fp.eventReporter->forwardEvent(events::FILESTORE_ERROR, static_cast<uint8_t>(fsmRes.step),
|
|
|
|
|
result);
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
} else {
|
|
|
|
|
tp.deliveryStatus = FileDeliveryStatus::RETAINED_IN_FILESTORE;
|
|
|
|
|
tp.vfsErrorCount = 0;
|
|
|
|
|
}
|
|
|
|
|
if (offset.value() + fileSegmentLen > tp.progress) {
|
|
|
|
|
tp.progress = offset.value() + fileSegmentLen;
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
@ -271,35 +280,62 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, Met
|
|
|
|
|
return OK;
|
|
|
|
|
}
|
|
|
|
|
ReturnValue_t result = OK;
|
|
|
|
|
fsmRes.step = TransactionStep::TRANSACTION_START;
|
|
|
|
|
if (reader.getTransmissionMode() == TransmissionMode::UNACKNOWLEDGED) {
|
|
|
|
|
fsmRes.state = CfdpStates::BUSY_CLASS_1_NACKED;
|
|
|
|
|
} else if (reader.getTransmissionMode() == TransmissionMode::ACKNOWLEDGED) {
|
|
|
|
|
fsmRes.state = CfdpStates::BUSY_CLASS_2_ACKED;
|
|
|
|
|
}
|
|
|
|
|
tp.checksumType = info.getChecksumType();
|
|
|
|
|
tp.closureRequested = info.isClosureRequested();
|
|
|
|
|
size_t sourceNameSize = 0;
|
|
|
|
|
const uint8_t* sourceNamePtr = info.getSourceFileName().getValue(&sourceNameSize);
|
|
|
|
|
if (sourceNameSize > tp.sourceName.size()) {
|
|
|
|
|
// TODO: Warning, event etc.
|
|
|
|
|
if (sourceNameSize + 1 > tp.sourceName.size()) {
|
|
|
|
|
fp.eventReporter->forwardEvent(events::FILENAME_TOO_LARGE_ERROR, 0, 0);
|
|
|
|
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
|
|
|
sif::warning << "cfdp::DestHandler: source filename too large" << std::endl;
|
|
|
|
|
#endif
|
|
|
|
|
return FAILED;
|
|
|
|
|
}
|
|
|
|
|
std::memcpy(tp.sourceName.data(), sourceNamePtr, sourceNameSize);
|
|
|
|
|
tp.sourceName[sourceNameSize] = '\0';
|
|
|
|
|
size_t destNameSize = 0;
|
|
|
|
|
const uint8_t* destNamePtr = info.getDestFileName().getValue(&destNameSize);
|
|
|
|
|
if (destNameSize > tp.destName.size()) {
|
|
|
|
|
// TODO: Warning, event etc.
|
|
|
|
|
if (destNameSize + 1 > tp.destName.size()) {
|
|
|
|
|
fp.eventReporter->forwardEvent(events::FILENAME_TOO_LARGE_ERROR, 0, 0);
|
|
|
|
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
|
|
|
sif::warning << "cfdp::DestHandler: dest filename too large" << std::endl;
|
|
|
|
|
#endif
|
|
|
|
|
return FAILED;
|
|
|
|
|
}
|
|
|
|
|
std::memcpy(tp.destName.data(), destNamePtr, destNameSize);
|
|
|
|
|
tp.destName[destNameSize] = '\0';
|
|
|
|
|
reader.fillConfig(tp.pduConf);
|
|
|
|
|
tp.pduConf.direction = Direction::TOWARDS_SENDER;
|
|
|
|
|
tp.transactionId.entityId = tp.pduConf.sourceId;
|
|
|
|
|
tp.transactionId.seqNum = tp.pduConf.seqNum;
|
|
|
|
|
if (not dp.remoteCfgTable.getRemoteCfg(tp.pduConf.sourceId, &tp.remoteCfg)) {
|
|
|
|
|
|
|
|
|
|
// If both dest name size and source name size are 0, we are dealing with a metadata only PDU,
|
|
|
|
|
// so there is no need to create a file or truncate an existing file
|
|
|
|
|
if (destNameSize > 0 and sourceNameSize > 0) {
|
|
|
|
|
FilesystemParams fparams(tp.destName.data());
|
|
|
|
|
if (dp.user.vfs.fileExists(fparams)) {
|
|
|
|
|
result = dp.user.vfs.truncateFile(fparams);
|
|
|
|
|
if (result != returnvalue::OK) {
|
|
|
|
|
// TODO: Provide execution step as parameter
|
|
|
|
|
fp.eventReporter->forwardEvent(events::FILESTORE_ERROR, static_cast<uint8_t>(fsmRes.step),
|
|
|
|
|
result);
|
|
|
|
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
|
|
|
sif::warning << "cfdp::DestHandler: file truncation error with code " << result
|
|
|
|
|
<< std::endl;
|
|
|
|
|
#endif
|
|
|
|
|
return FAILED;
|
|
|
|
|
// TODO: Relevant for filestore rejection error?
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
result = dp.user.vfs.createFile(fparams);
|
|
|
|
|
if (result != OK) {
|
|
|
|
|
fp.eventReporter->forwardEvent(events::FILESTORE_ERROR, static_cast<uint8_t>(fsmRes.step),
|
|
|
|
|
result);
|
|
|
|
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
|
|
|
sif::warning << "cfdp::DestHandler: file creation error with code " << result << std::endl;
|
|
|
|
|
#endif
|
|
|
|
|
return FAILED;
|
|
|
|
|
// TODO: Relevant for filestore rejection error?
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
EntityId sourceId;
|
|
|
|
|
reader.getSourceId(sourceId);
|
|
|
|
|
if (not dp.remoteCfgTable.getRemoteCfg(sourceId, &tp.remoteCfg)) {
|
|
|
|
|
// TODO: Warning, event etc.
|
|
|
|
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
|
|
|
sif::warning << "cfdp::DestHandler" << __func__
|
|
|
|
@ -308,22 +344,18 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, Met
|
|
|
|
|
#endif
|
|
|
|
|
return FAILED;
|
|
|
|
|
}
|
|
|
|
|
// If both dest name size and source name size are 0, we are dealing with a metadata only PDU,
|
|
|
|
|
// so there is no need to create a file or truncate an existing file
|
|
|
|
|
if (destNameSize > 0 and sourceNameSize > 0) {
|
|
|
|
|
FilesystemParams fparams(tp.destName.data());
|
|
|
|
|
// TODO: Filesystem errors?
|
|
|
|
|
if (dp.user.vfs.fileExists(fparams)) {
|
|
|
|
|
dp.user.vfs.truncateFile(fparams);
|
|
|
|
|
} else {
|
|
|
|
|
result = dp.user.vfs.createFile(fparams);
|
|
|
|
|
if (result != OK) {
|
|
|
|
|
// TODO: Handle FS error. This is probably a case for the filestore rejection mechanism of
|
|
|
|
|
// CFDP.
|
|
|
|
|
// In any case, it does not really make sense to continue here
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fsmRes.step = TransactionStep::TRANSACTION_START;
|
|
|
|
|
if (reader.getTransmissionMode() == TransmissionMode::UNACKNOWLEDGED) {
|
|
|
|
|
fsmRes.state = CfdpStates::BUSY_CLASS_1_NACKED;
|
|
|
|
|
} else if (reader.getTransmissionMode() == TransmissionMode::ACKNOWLEDGED) {
|
|
|
|
|
fsmRes.state = CfdpStates::BUSY_CLASS_2_ACKED;
|
|
|
|
|
}
|
|
|
|
|
tp.checksumType = info.getChecksumType();
|
|
|
|
|
tp.closureRequested = info.isClosureRequested();
|
|
|
|
|
reader.fillConfig(tp.pduConf);
|
|
|
|
|
tp.pduConf.direction = Direction::TOWARDS_SENDER;
|
|
|
|
|
tp.transactionId.entityId = tp.pduConf.sourceId;
|
|
|
|
|
tp.transactionId.seqNum = tp.pduConf.seqNum;
|
|
|
|
|
fsmRes.step = TransactionStep::RECEIVING_FILE_DATA_PDUS;
|
|
|
|
|
MetadataRecvdParams params(tp.transactionId, tp.pduConf.sourceId);
|
|
|
|
|
params.fileSize = tp.fileSize.getSize();
|
|
|
|
|