fsfw/src/fsfw/cfdp/handler/DestHandler.h

178 lines
6.1 KiB
C
Raw Normal View History

2022-09-14 19:29:43 +02:00
#ifndef FSFW_CFDP_CFDPDESTHANDLER_H
#define FSFW_CFDP_CFDPDESTHANDLER_H
#include <etl/list.h>
#include <etl/set.h>
#include <optional>
#include <utility>
#include "RemoteConfigTableIF.h"
#include "UserBase.h"
#include "defs.h"
#include "fsfw/cfdp/handler/mib.h"
#include "fsfw/cfdp/pdu/MetadataPduReader.h"
#include "fsfw/cfdp/pdu/PduConfig.h"
2023-07-24 10:06:45 +02:00
#include "fsfw/cfdp/tlv/MessageToUserTlv.h"
2022-09-14 19:29:43 +02:00
#include "fsfw/container/DynamicFIFO.h"
#include "fsfw/storagemanager/StorageManagerIF.h"
#include "fsfw/storagemanager/storeAddress.h"
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
namespace cfdp {
template <size_t SIZE>
using LostSegmentsList = etl::set<etl::pair<uint64_t, uint64_t>, SIZE>;
using LostSegmentsListBase = etl::iset<etl::pair<uint64_t, uint64_t>>;
struct DestHandlerParams {
DestHandlerParams(LocalEntityCfg cfg, UserBase& user, RemoteConfigTableIF& remoteCfgTable,
PacketInfoListBase& packetList,
// TODO: This container can potentially take tons of space. For a better
// memory efficient implementation, an additional abstraction could be
// be used so users can use uint32_t as the pair type
2023-07-24 10:06:45 +02:00
// TODO: Actually, we can provide a better abstraction via interface, which
// allows using something like a bounded map. This simplifies
// the implementation significantly.
2022-09-14 19:29:43 +02:00
LostSegmentsListBase& lostSegmentsContainer)
: cfg(std::move(cfg)),
user(user),
remoteCfgTable(remoteCfgTable),
packetListRef(packetList),
lostSegmentsContainer(lostSegmentsContainer) {}
LocalEntityCfg cfg;
UserBase& user;
RemoteConfigTableIF& remoteCfgTable;
PacketInfoListBase& packetListRef;
LostSegmentsListBase& lostSegmentsContainer;
2023-07-24 10:06:45 +02:00
uint8_t maxTlvsInOnePdu = 20;
2022-09-14 19:29:43 +02:00
size_t maxFilenameLen = 255;
};
class DestHandler {
public:
2023-02-24 15:49:05 +01:00
enum class TransactionStep : uint8_t {
2022-09-14 19:29:43 +02:00
IDLE = 0,
TRANSACTION_START = 1,
RECEIVING_FILE_DATA_PDUS = 2,
SENDING_ACK_PDU = 3,
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;
2023-07-14 15:56:38 +02:00
CfdpState state = CfdpState::IDLE;
2022-09-14 19:29:43 +02:00
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
*/
ReturnValue_t PARTIAL_SUCCESS = returnvalue::makeCode(0, 2);
ReturnValue_t FAILURE = returnvalue::makeCode(0, 3);
2023-07-17 10:25:09 +02:00
explicit DestHandler(DestHandlerParams handlerParams, FsfwParams fsfwParams);
2022-09-14 19:29:43 +02:00
/**
*
* @return
* - @c returnvalue::OK State machine OK for this execution cycle
* - @c CALL_FSM_AGAIN State machine should be called again.
*/
2023-08-14 20:47:27 +02:00
const FsmResult& stateMachine();
2022-09-14 19:29:43 +02:00
void setMsgQueue(MessageQueueIF& queue);
void setEventReporter(EventReportingProxyIF& reporter);
ReturnValue_t passPacket(PacketInfo packet);
ReturnValue_t initialize();
2023-07-14 15:56:38 +02:00
[[nodiscard]] CfdpState getCfdpState() const;
2022-09-14 19:29:43 +02:00
[[nodiscard]] TransactionStep getTransactionStep() const;
[[nodiscard]] const TransactionId& getTransactionId() const;
[[nodiscard]] const DestHandlerParams& getDestHandlerParams() const;
[[nodiscard]] StorageManagerIF* getTcStore() const;
[[nodiscard]] StorageManagerIF* getTmStore() const;
private:
struct TransactionParams {
// Initialize char vectors with length + 1 for 0 termination
explicit TransactionParams(size_t maxFileNameLen)
: sourceName(maxFileNameLen + 1), destName(maxFileNameLen + 1) {}
void reset() {
pduConf = PduConfig();
transactionId = TransactionId();
std::fill(sourceName.begin(), sourceName.end(), '\0');
std::fill(destName.begin(), destName.end(), '\0');
fileSize.setFileSize(0, false);
2022-09-15 18:44:00 +02:00
conditionCode = ConditionCode::NO_ERROR;
2022-09-14 19:29:43 +02:00
deliveryCode = FileDeliveryCode::DATA_INCOMPLETE;
deliveryStatus = FileDeliveryStatus::DISCARDED_DELIBERATELY;
crc = 0;
progress = 0;
remoteCfg = nullptr;
metadataOnly = false;
2022-09-14 19:29:43 +02:00
closureRequested = false;
2023-02-24 15:49:05 +01:00
vfsErrorCount = 0;
2022-09-15 18:44:00 +02:00
checksumType = ChecksumType::NULL_CHECKSUM;
2022-09-14 19:29:43 +02:00
}
bool metadataOnly = false;
2022-09-15 18:44:00 +02:00
ChecksumType checksumType = ChecksumType::NULL_CHECKSUM;
2022-09-14 19:29:43 +02:00
bool closureRequested = false;
2023-02-24 15:49:05 +01:00
uint16_t vfsErrorCount = 0;
2022-09-14 19:29:43 +02:00
std::vector<char> sourceName;
std::vector<char> destName;
2023-07-19 13:44:52 +02:00
cfdp::Fss fileSize;
2022-09-14 19:29:43 +02:00
TransactionId transactionId;
PduConfig pduConf;
2022-09-15 18:44:00 +02:00
ConditionCode conditionCode = ConditionCode::NO_ERROR;
2022-09-14 19:29:43 +02:00
FileDeliveryCode deliveryCode = FileDeliveryCode::DATA_INCOMPLETE;
FileDeliveryStatus deliveryStatus = FileDeliveryStatus::DISCARDED_DELIBERATELY;
uint32_t crc = 0;
uint64_t progress = 0;
RemoteEntityCfg* remoteCfg = nullptr;
};
std::vector<cfdp::Tlv> tlvVec;
2023-07-24 10:06:45 +02:00
std::vector<MessageToUserTlv> msgToUserVec;
2023-07-27 14:55:46 +02:00
TransactionParams transactionParams;
2023-06-30 11:59:22 +02:00
DestHandlerParams destParams;
2023-07-17 10:25:09 +02:00
cfdp::FsfwParams fsfwParams;
2022-09-14 19:29:43 +02:00
FsmResult fsmRes;
2023-08-30 11:18:49 +02:00
ReturnValue_t startTransaction(const MetadataPduReader& reader);
2022-09-14 19:29:43 +02:00
ReturnValue_t handleMetadataPdu(const PacketInfo& info);
ReturnValue_t handleFileDataPdu(const PacketInfo& info);
ReturnValue_t handleEofPdu(const PacketInfo& info);
ReturnValue_t handleMetadataParseError(ReturnValue_t result, const uint8_t* rawData,
size_t maxSize);
ReturnValue_t handleTransferCompletion();
ReturnValue_t tryBuildingAbsoluteDestName(size_t destNameSize);
2022-09-14 19:29:43 +02:00
ReturnValue_t sendFinishedPdu();
ReturnValue_t noticeOfCompletion();
ReturnValue_t checksumVerification();
void fileErrorHandler(Event event, ReturnValue_t result, const char* info) const;
2022-09-14 19:29:43 +02:00
const FsmResult& updateFsmRes(uint8_t errors);
void checkAndHandleError(ReturnValue_t result, uint8_t& errorIdx);
void finish();
};
} // namespace cfdp
#endif // FSFW_CFDP_CFDPDESTHANDLER_H