CFDP SOURCE handler #157
@ -56,7 +56,7 @@ const cfdp::DestHandler::FsmResult& cfdp::DestHandler::performStateMachine() {
|
|||||||
}
|
}
|
||||||
return updateFsmRes(errorIdx);
|
return updateFsmRes(errorIdx);
|
||||||
}
|
}
|
||||||
if (fsmRes.state == CfdpStates::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();
|
for (auto infoIter = destParams.packetListRef.begin();
|
||||||
infoIter != destParams.packetListRef.end();) {
|
infoIter != destParams.packetListRef.end();) {
|
||||||
@ -88,7 +88,7 @@ const cfdp::DestHandler::FsmResult& cfdp::DestHandler::performStateMachine() {
|
|||||||
}
|
}
|
||||||
return updateFsmRes(errorIdx);
|
return updateFsmRes(errorIdx);
|
||||||
}
|
}
|
||||||
if (fsmRes.state == CfdpStates::BUSY_CLASS_2_ACKED) {
|
if (fsmRes.state == CfdpState::BUSY_CLASS_2_ACKED) {
|
||||||
// TODO: Will be implemented at a later stage
|
// TODO: Will be implemented at a later stage
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "CFDP state machine for acknowledged mode not implemented yet" << std::endl;
|
sif::warning << "CFDP state machine for acknowledged mode not implemented yet" << std::endl;
|
||||||
@ -231,9 +231,9 @@ ReturnValue_t cfdp::DestHandler::handleEofPdu(const cfdp::PacketInfo& info) {
|
|||||||
destParams.user.eofRecvIndication(getTransactionId());
|
destParams.user.eofRecvIndication(getTransactionId());
|
||||||
}
|
}
|
||||||
if (fsmRes.step == TransactionStep::RECEIVING_FILE_DATA_PDUS) {
|
if (fsmRes.step == TransactionStep::RECEIVING_FILE_DATA_PDUS) {
|
||||||
if (fsmRes.state == CfdpStates::BUSY_CLASS_1_NACKED) {
|
if (fsmRes.state == CfdpState::BUSY_CLASS_1_NACKED) {
|
||||||
fsmRes.step = TransactionStep::TRANSFER_COMPLETION;
|
fsmRes.step = TransactionStep::TRANSFER_COMPLETION;
|
||||||
} else if (fsmRes.state == CfdpStates::BUSY_CLASS_2_ACKED) {
|
} else if (fsmRes.state == CfdpState::BUSY_CLASS_2_ACKED) {
|
||||||
fsmRes.step = TransactionStep::SENDING_ACK_PDU;
|
fsmRes.step = TransactionStep::SENDING_ACK_PDU;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -278,7 +278,7 @@ ReturnValue_t cfdp::DestHandler::handleMetadataParseError(ReturnValue_t result,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, MetadataInfo& info) {
|
ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, MetadataInfo& info) {
|
||||||
if (fsmRes.state != CfdpStates::IDLE) {
|
if (fsmRes.state != CfdpState::IDLE) {
|
||||||
// According to standard, discard metadata PDU if we are busy
|
// According to standard, discard metadata PDU if we are busy
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@ -342,9 +342,9 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, Met
|
|||||||
}
|
}
|
||||||
fsmRes.step = TransactionStep::TRANSACTION_START;
|
fsmRes.step = TransactionStep::TRANSACTION_START;
|
||||||
if (reader.getTransmissionMode() == TransmissionMode::UNACKNOWLEDGED) {
|
if (reader.getTransmissionMode() == TransmissionMode::UNACKNOWLEDGED) {
|
||||||
fsmRes.state = CfdpStates::BUSY_CLASS_1_NACKED;
|
fsmRes.state = CfdpState::BUSY_CLASS_1_NACKED;
|
||||||
} else if (reader.getTransmissionMode() == TransmissionMode::ACKNOWLEDGED) {
|
} else if (reader.getTransmissionMode() == TransmissionMode::ACKNOWLEDGED) {
|
||||||
fsmRes.state = CfdpStates::BUSY_CLASS_2_ACKED;
|
fsmRes.state = CfdpState::BUSY_CLASS_2_ACKED;
|
||||||
}
|
}
|
||||||
transactionParams.checksumType = info.getChecksumType();
|
transactionParams.checksumType = info.getChecksumType();
|
||||||
transactionParams.closureRequested = info.isClosureRequested();
|
transactionParams.closureRequested = info.isClosureRequested();
|
||||||
@ -363,7 +363,7 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, Met
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
cfdp::CfdpStates cfdp::DestHandler::getCfdpState() const { return fsmRes.state; }
|
cfdp::CfdpState cfdp::DestHandler::getCfdpState() const { return fsmRes.state; }
|
||||||
|
|
||||||
ReturnValue_t cfdp::DestHandler::handleTransferCompletion() {
|
ReturnValue_t cfdp::DestHandler::handleTransferCompletion() {
|
||||||
ReturnValue_t result;
|
ReturnValue_t result;
|
||||||
@ -378,13 +378,13 @@ ReturnValue_t cfdp::DestHandler::handleTransferCompletion() {
|
|||||||
result = noticeOfCompletion();
|
result = noticeOfCompletion();
|
||||||
if (result != OK) {
|
if (result != OK) {
|
||||||
}
|
}
|
||||||
if (fsmRes.state == CfdpStates::BUSY_CLASS_1_NACKED) {
|
if (fsmRes.state == CfdpState::BUSY_CLASS_1_NACKED) {
|
||||||
if (transactionParams.closureRequested) {
|
if (transactionParams.closureRequested) {
|
||||||
fsmRes.step = TransactionStep::SENDING_FINISHED_PDU;
|
fsmRes.step = TransactionStep::SENDING_FINISHED_PDU;
|
||||||
} else {
|
} else {
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
} else if (fsmRes.state == CfdpStates::BUSY_CLASS_2_ACKED) {
|
} else if (fsmRes.state == CfdpState::BUSY_CLASS_2_ACKED) {
|
||||||
fsmRes.step = TransactionStep::SENDING_FINISHED_PDU;
|
fsmRes.step = TransactionStep::SENDING_FINISHED_PDU;
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
@ -426,7 +426,7 @@ void cfdp::DestHandler::fileErrorHandler(Event event, ReturnValue_t result,
|
|||||||
void cfdp::DestHandler::finish() {
|
void cfdp::DestHandler::finish() {
|
||||||
transactionParams.reset();
|
transactionParams.reset();
|
||||||
destParams.packetListRef.clear();
|
destParams.packetListRef.clear();
|
||||||
fsmRes.state = CfdpStates::IDLE;
|
fsmRes.state = CfdpState::IDLE;
|
||||||
fsmRes.step = TransactionStep::IDLE;
|
fsmRes.step = TransactionStep::IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ class DestHandler {
|
|||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
CallStatus callStatus = CallStatus::CALL_AFTER_DELAY;
|
CallStatus callStatus = CallStatus::CALL_AFTER_DELAY;
|
||||||
TransactionStep step = TransactionStep::IDLE;
|
TransactionStep step = TransactionStep::IDLE;
|
||||||
CfdpStates state = CfdpStates::IDLE;
|
CfdpState state = CfdpState::IDLE;
|
||||||
uint32_t packetsSent = 0;
|
uint32_t packetsSent = 0;
|
||||||
uint8_t errors = 0;
|
uint8_t errors = 0;
|
||||||
std::array<ReturnValue_t, 3> errorCodes = {};
|
std::array<ReturnValue_t, 3> errorCodes = {};
|
||||||
@ -117,7 +117,7 @@ class DestHandler {
|
|||||||
|
|
||||||
ReturnValue_t initialize();
|
ReturnValue_t initialize();
|
||||||
|
|
||||||
[[nodiscard]] CfdpStates 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;
|
||||||
|
@ -1,3 +1,39 @@
|
|||||||
#include "SourceHandler.h"
|
#include "SourceHandler.h"
|
||||||
|
|
||||||
SourceHandler::SourceHandler(SourceHandlerParams params, FsfwSourceParams fsfwParams) {}
|
SourceHandler::SourceHandler(SourceHandlerParams params, FsfwSourceParams fsfwParams) {}
|
||||||
|
|
||||||
|
void SourceHandler::fsmNacked() {
|
||||||
|
if (step == TransactionStep::IDLE) {
|
||||||
|
step = TransactionStep::TRANSACTION_START;
|
||||||
|
}
|
||||||
|
if (step == TransactionStep::TRANSACTION_START) {
|
||||||
|
// TODO: Use put request information to start the transaction
|
||||||
|
step = TransactionStep::CRC_PROCEDURE;
|
||||||
|
}
|
||||||
|
if (step == TransactionStep::CRC_PROCEDURE) {
|
||||||
|
// TODO: Perform CRC procedure: Generate the CRC32 from the file.
|
||||||
|
}
|
||||||
|
if (step == TransactionStep::SENDING_METADATA) {
|
||||||
|
// TODO: Prepare and send metadata PDU
|
||||||
|
}
|
||||||
|
if (step == TransactionStep::SENDING_FILE_DATA) {
|
||||||
|
// TODO: Prepare and send file data PDUs
|
||||||
|
}
|
||||||
|
if (step == TransactionStep::SENDING_EOF) {
|
||||||
|
// TODO: Send EOF PDU
|
||||||
|
}
|
||||||
|
if (step == TransactionStep::WAIT_FOR_FINISH) {
|
||||||
|
// TODO: In case this is a request with closure, wait for finish.
|
||||||
|
}
|
||||||
|
if (step == TransactionStep::NOTICE_OF_COMPLETION) {
|
||||||
|
// TODO: Notice of completion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void SourceHandler::stateMachine() {
|
||||||
|
if (state == cfdp::CfdpState::IDLE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (state == cfdp::CfdpState::BUSY_CLASS_1_NACKED) {
|
||||||
|
return fsmNacked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
#include "fsfw/events/EventReportingProxyIF.h"
|
#include "fsfw/events/EventReportingProxyIF.h"
|
||||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||||
|
|
||||||
@ -20,6 +21,8 @@ class SourceHandler {
|
|||||||
public:
|
public:
|
||||||
SourceHandler(SourceHandlerParams params, FsfwSourceParams fsfwParams);
|
SourceHandler(SourceHandlerParams params, FsfwSourceParams fsfwParams);
|
||||||
|
|
||||||
|
void stateMachine();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class TransactionStep : uint8_t {
|
enum class TransactionStep : uint8_t {
|
||||||
IDLE = 0,
|
IDLE = 0,
|
||||||
@ -32,6 +35,10 @@ class SourceHandler {
|
|||||||
WAIT_FOR_FINISH = 7,
|
WAIT_FOR_FINISH = 7,
|
||||||
NOTICE_OF_COMPLETION = 8
|
NOTICE_OF_COMPLETION = 8
|
||||||
};
|
};
|
||||||
|
cfdp::CfdpState state;
|
||||||
|
TransactionStep step;
|
||||||
|
|
||||||
|
void fsmNacked();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FSFW_CFDP_CFDPSOURCEHANDLER_H
|
#endif // FSFW_CFDP_CFDPSOURCEHANDLER_H
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
namespace cfdp {
|
namespace cfdp {
|
||||||
|
|
||||||
enum class CfdpStates { 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;
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") {
|
|||||||
userMock.metadataRecvd.pop();
|
userMock.metadataRecvd.pop();
|
||||||
REQUIRE(fsMock.fileMap.find(destName) != fsMock.fileMap.end());
|
REQUIRE(fsMock.fileMap.find(destName) != fsMock.fileMap.end());
|
||||||
REQUIRE(res.result == OK);
|
REQUIRE(res.result == OK);
|
||||||
REQUIRE(res.state == CfdpStates::BUSY_CLASS_1_NACKED);
|
REQUIRE(res.state == CfdpState::BUSY_CLASS_1_NACKED);
|
||||||
REQUIRE(res.step == DestHandler::TransactionStep::RECEIVING_FILE_DATA_PDUS);
|
REQUIRE(res.step == DestHandler::TransactionStep::RECEIVING_FILE_DATA_PDUS);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") {
|
|||||||
|
|
||||||
auto eofCheck = [&](const cfdp::DestHandler::FsmResult& res, const TransactionId& id) {
|
auto eofCheck = [&](const cfdp::DestHandler::FsmResult& res, const TransactionId& id) {
|
||||||
REQUIRE(res.result == OK);
|
REQUIRE(res.result == OK);
|
||||||
REQUIRE(res.state == CfdpStates::IDLE);
|
REQUIRE(res.state == CfdpState::IDLE);
|
||||||
REQUIRE(res.errors == 0);
|
REQUIRE(res.errors == 0);
|
||||||
REQUIRE(res.step == DestHandler::TransactionStep::IDLE);
|
REQUIRE(res.step == DestHandler::TransactionStep::IDLE);
|
||||||
// Assert that the packet was deleted after handling
|
// Assert that the packet was deleted after handling
|
||||||
@ -120,7 +120,7 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") {
|
|||||||
auto fileDataPduCheck = [&](const cfdp::DestHandler::FsmResult& res,
|
auto fileDataPduCheck = [&](const cfdp::DestHandler::FsmResult& res,
|
||||||
const std::vector<store_address_t>& idsToCheck) {
|
const std::vector<store_address_t>& idsToCheck) {
|
||||||
REQUIRE(res.result == OK);
|
REQUIRE(res.result == OK);
|
||||||
REQUIRE(res.state == CfdpStates::BUSY_CLASS_1_NACKED);
|
REQUIRE(res.state == CfdpState::BUSY_CLASS_1_NACKED);
|
||||||
REQUIRE(res.step == DestHandler::TransactionStep::RECEIVING_FILE_DATA_PDUS);
|
REQUIRE(res.step == DestHandler::TransactionStep::RECEIVING_FILE_DATA_PDUS);
|
||||||
for (const auto id : idsToCheck) {
|
for (const auto id : idsToCheck) {
|
||||||
REQUIRE(not tcStore.hasDataAtId(id));
|
REQUIRE(not tcStore.hasDataAtId(id));
|
||||||
@ -129,7 +129,7 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") {
|
|||||||
};
|
};
|
||||||
|
|
||||||
SECTION("State") {
|
SECTION("State") {
|
||||||
CHECK(destHandler.getCfdpState() == CfdpStates::IDLE);
|
CHECK(destHandler.getCfdpState() == CfdpState::IDLE);
|
||||||
CHECK(destHandler.getTransactionStep() == DestHandler::TransactionStep::IDLE);
|
CHECK(destHandler.getTransactionStep() == DestHandler::TransactionStep::IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +138,7 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") {
|
|||||||
CHECK(res.result == OK);
|
CHECK(res.result == OK);
|
||||||
CHECK(res.callStatus == CallStatus::CALL_AFTER_DELAY);
|
CHECK(res.callStatus == CallStatus::CALL_AFTER_DELAY);
|
||||||
CHECK(res.errors == 0);
|
CHECK(res.errors == 0);
|
||||||
CHECK(destHandler.getCfdpState() == CfdpStates::IDLE);
|
CHECK(destHandler.getCfdpState() == CfdpState::IDLE);
|
||||||
CHECK(destHandler.getTransactionStep() == DestHandler::TransactionStep::IDLE);
|
CHECK(destHandler.getTransactionStep() == DestHandler::TransactionStep::IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user