nice
This commit is contained in:
parent
f49e607881
commit
a856f91c67
@ -185,3 +185,17 @@ const uint8_t *cfdp::PutRequest::getMessagesToUser(size_t &totalSize) {
|
||||
totalSize = this->msgsToUsersTotalSize;
|
||||
return msgsToUserStartPtr;
|
||||
}
|
||||
|
||||
bool cfdp::PutRequest::getClosureRequested(bool &closureRequested_) const {
|
||||
if (hasClosureRequested) {
|
||||
closureRequested_ = this->closureRequested;
|
||||
}
|
||||
return hasClosureRequested;
|
||||
}
|
||||
|
||||
bool cfdp::PutRequest::getTransmissionMode(cfdp::TransmissionMode &mode) const {
|
||||
if (hasTransmissionMode) {
|
||||
mode = static_cast<cfdp::TransmissionMode>(this->transmissionMode);
|
||||
}
|
||||
return hasTransmissionMode;
|
||||
}
|
||||
|
@ -22,7 +22,9 @@ class PutRequest : public SerializeIF {
|
||||
PutRequest(EntityId destId, const uint8_t* msgsToUser, size_t msgsToUserTotalSize,
|
||||
const uint8_t* fsRequests, size_t fsRequestsSize);
|
||||
/**
|
||||
* Put request to initiate file transfers.
|
||||
* Put request to initiate file transfers. By default, the transmission mode and closure requested
|
||||
* parameter are not present, thereby being derived from the remote configuration for a
|
||||
* particular destination ID.
|
||||
* @param destId
|
||||
* @param sourceName
|
||||
* @param destName
|
||||
@ -53,6 +55,9 @@ class PutRequest : public SerializeIF {
|
||||
|
||||
[[nodiscard]] bool isMetadataOnly() const;
|
||||
|
||||
bool getTransmissionMode(TransmissionMode& mode) const;
|
||||
bool getClosureRequested(bool& closureRequested) const;
|
||||
|
||||
[[nodiscard]] const EntityId& getDestId() const;
|
||||
void setDestId(EntityId id);
|
||||
|
||||
|
@ -138,21 +138,23 @@ ReturnValue_t cfdp::SourceHandler::checksumGeneration() {
|
||||
return OK;
|
||||
}
|
||||
|
||||
ReturnValue_t cfdp::SourceHandler::putRequest(PutRequestFull& putRequest, RemoteEntityCfg& cfg) {
|
||||
ReturnValue_t cfdp::SourceHandler::transactionStart(PutRequest& putRequest, RemoteEntityCfg& cfg) {
|
||||
if (state != CfdpState::IDLE) {
|
||||
return SOURCE_TRANSACTION_PENDING;
|
||||
}
|
||||
if (putRequest.sourceNameSize > transactionParams.sourceName.size()) {
|
||||
return FAILED;
|
||||
if (cfg.remoteId != putRequest.getDestId()) {
|
||||
return WRONG_REMOTE_CFG_ENTITY_ID;
|
||||
}
|
||||
if (putRequest.destNameSize > transactionParams.destName.size()) {
|
||||
return FAILED;
|
||||
if (putRequest.getSourceName().getValueLen() == 0) {
|
||||
return SOURCE_NAME_EMPTY;
|
||||
}
|
||||
std::memcpy(transactionParams.destName.data(), putRequest.destName, putRequest.destNameSize);
|
||||
std::memcpy(transactionParams.sourceName.data(), putRequest.sourceName,
|
||||
putRequest.sourceNameSize);
|
||||
transactionParams.sourceNameSize = putRequest.sourceNameSize;
|
||||
transactionParams.destNameSize = putRequest.destNameSize;
|
||||
if (putRequest.getDestName().getValueLen() == 0) {
|
||||
return DEST_NAME_EMPTY;
|
||||
}
|
||||
const char* srcNamePtr = putRequest.getSourceName().getString(transactionParams.sourceNameSize);
|
||||
const char* destNamePtr = putRequest.getDestName().getString(transactionParams.destNameSize);
|
||||
std::strncpy(transactionParams.sourceName.data(), srcNamePtr, transactionParams.sourceNameSize);
|
||||
std::strncpy(transactionParams.destName.data(), destNamePtr, transactionParams.destNameSize);
|
||||
FilesystemParams params(transactionParams.sourceName.data());
|
||||
if (!sourceParams.user.vfs.fileExists(params)) {
|
||||
return FILE_DOES_NOT_EXIST;
|
||||
@ -160,9 +162,15 @@ ReturnValue_t cfdp::SourceHandler::putRequest(PutRequestFull& putRequest, Remote
|
||||
if (cfg.maxFileSegmentLen > fileBuf.size() or cfg.maxFileSegmentLen == 0) {
|
||||
return FILE_SEGMENT_LEN_INVALID;
|
||||
}
|
||||
transactionParams.closureRequested = putRequest.closureRequested;
|
||||
transactionParams.pduConf.mode = putRequest.transmissionMode;
|
||||
transactionParams.pduConf.destId = putRequest.destId;
|
||||
// If transmission mode is not set, use default transmission mode for the remote entity.
|
||||
if (not putRequest.getTransmissionMode(transactionParams.pduConf.mode)) {
|
||||
transactionParams.pduConf.mode = cfg.defaultTransmissionMode;
|
||||
}
|
||||
// If closure request field is not set, use default option for the remote entity.
|
||||
if (not putRequest.getClosureRequested(transactionParams.closureRequested)) {
|
||||
transactionParams.closureRequested = cfg.closureRequested;
|
||||
}
|
||||
transactionParams.pduConf.destId = putRequest.getDestId();
|
||||
// Only used for PDU forwarding, file is sent to file receiver regularly here.
|
||||
transactionParams.pduConf.direction = Direction::TOWARDS_RECEIVER;
|
||||
transactionParams.pduConf.sourceId = sourceParams.cfg.localId;
|
||||
@ -304,3 +312,6 @@ ReturnValue_t cfdp::SourceHandler::reset() {
|
||||
transactionParams.reset();
|
||||
return OK;
|
||||
}
|
||||
cfdp::CfdpState cfdp::SourceHandler::getState() const { return state; }
|
||||
|
||||
cfdp::SourceHandler::TransactionStep cfdp::SourceHandler::getStep() const { return step; }
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "UserBase.h"
|
||||
#include "defs.h"
|
||||
#include "fsfw/cfdp/Fss.h"
|
||||
#include "fsfw/cfdp/handler/PutRequest.h"
|
||||
#include "fsfw/cfdp/handler/mib.h"
|
||||
#include "fsfw/events/EventReportingProxyIF.h"
|
||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||
@ -26,6 +27,17 @@ struct SourceHandlerParams {
|
||||
|
||||
class SourceHandler {
|
||||
public:
|
||||
enum class TransactionStep : uint8_t {
|
||||
IDLE = 0,
|
||||
TRANSACTION_START = 1,
|
||||
CRC_PROCEDURE = 2,
|
||||
SENDING_METADATA = 3,
|
||||
SENDING_FILE_DATA = 4,
|
||||
SENDING_EOF = 5,
|
||||
WAIT_FOR_ACK = 6,
|
||||
WAIT_FOR_FINISH = 7,
|
||||
NOTICE_OF_COMPLETION = 8
|
||||
};
|
||||
struct FsmResult {
|
||||
public:
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
@ -38,33 +50,25 @@ class SourceHandler {
|
||||
|
||||
SourceHandler(SourceHandlerParams params, FsfwParams fsfwParams);
|
||||
|
||||
[[nodiscard]] CfdpState getState() const;
|
||||
[[nodiscard]] TransactionStep getStep() const;
|
||||
|
||||
/**
|
||||
* Pass a put request to the source handler, which might initiate a CFDP transaction and start
|
||||
* the state machine
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t putRequest(PutRequestFull& putRequest, RemoteEntityCfg& cfg);
|
||||
ReturnValue_t transactionStart(PutRequest& putRequest, RemoteEntityCfg& cfg);
|
||||
FsmResult& stateMachine();
|
||||
|
||||
ReturnValue_t initialize();
|
||||
|
||||
private:
|
||||
enum class TransactionStep : uint8_t {
|
||||
IDLE = 0,
|
||||
TRANSACTION_START = 1,
|
||||
CRC_PROCEDURE = 2,
|
||||
SENDING_METADATA = 3,
|
||||
SENDING_FILE_DATA = 4,
|
||||
SENDING_EOF = 5,
|
||||
WAIT_FOR_ACK = 6,
|
||||
WAIT_FOR_FINISH = 7,
|
||||
NOTICE_OF_COMPLETION = 8
|
||||
};
|
||||
struct TransactionParams {
|
||||
uint32_t crc{};
|
||||
std::array<char, 524> sourceName{};
|
||||
std::array<char, UINT8_MAX + 1> sourceName{};
|
||||
size_t sourceNameSize = 0;
|
||||
std::array<char, 524> destName{};
|
||||
std::array<char, UINT8_MAX + 1> destName{};
|
||||
size_t destNameSize = 0;
|
||||
cfdp::Fss fileSize;
|
||||
size_t progress = 0;
|
||||
@ -72,7 +76,7 @@ class SourceHandler {
|
||||
RemoteEntityCfg remoteCfg;
|
||||
PduConfig pduConf;
|
||||
cfdp::TransactionId id{};
|
||||
cfdp::WidthInBytes seqCountWidth;
|
||||
cfdp::WidthInBytes seqCountWidth{};
|
||||
|
||||
void reset() {
|
||||
sourceNameSize = 0;
|
||||
|
@ -48,18 +48,6 @@ template <size_t SIZE>
|
||||
using PacketInfoList = etl::list<PacketInfo, SIZE>;
|
||||
using PacketInfoListBase = etl::ilist<PacketInfo>;
|
||||
|
||||
struct PutRequestFull {
|
||||
public:
|
||||
EntityId destId;
|
||||
TransmissionMode transmissionMode = TransmissionMode::UNACKNOWLEDGED;
|
||||
char destName[524]{};
|
||||
size_t destNameSize = 0;
|
||||
char sourceName[524]{};
|
||||
size_t sourceNameSize = 0;
|
||||
bool closureRequested = true;
|
||||
// MessageToUserTlv
|
||||
};
|
||||
|
||||
enum class CallStatus { DONE, CALL_AFTER_DELAY, CALL_AGAIN };
|
||||
|
||||
namespace events {
|
||||
@ -75,7 +63,10 @@ static constexpr Event FILENAME_TOO_LARGE_ERROR = event::makeEvent(SSID, 4, seve
|
||||
|
||||
static constexpr ReturnValue_t SOURCE_TRANSACTION_PENDING = returnvalue::makeCode(CID, 0);
|
||||
static constexpr ReturnValue_t FILE_DOES_NOT_EXIST = returnvalue::makeCode(CID, 1);
|
||||
static constexpr ReturnValue_t FILE_SEGMENT_LEN_INVALID = returnvalue::makeCode(CID, 1);
|
||||
static constexpr ReturnValue_t FILE_SEGMENT_LEN_INVALID = returnvalue::makeCode(CID, 2);
|
||||
static constexpr ReturnValue_t SOURCE_NAME_EMPTY = returnvalue::makeCode(CID, 3);
|
||||
static constexpr ReturnValue_t DEST_NAME_EMPTY = returnvalue::makeCode(CID, 4);
|
||||
static constexpr ReturnValue_t WRONG_REMOTE_CFG_ENTITY_ID = returnvalue::makeCode(CID, 5);
|
||||
|
||||
} // namespace cfdp
|
||||
#endif // FSFW_CFDP_HANDLER_DEFS_H
|
||||
|
@ -93,3 +93,5 @@ cfdp::Lv& cfdp::Lv::operator=(cfdp::Lv&& other) noexcept {
|
||||
other.value = SerialBufferAdapter<uint8_t>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_t cfdp::Lv::getValueLen() const { return getSerializedSize() - 1; }
|
||||
|
@ -40,6 +40,8 @@ class Lv : public SerializeIF {
|
||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
size_t getValueLen() const;
|
||||
|
||||
/**
|
||||
* Get value field and its size.
|
||||
* @param size Optionally retrieve size. Size will be the size of the actual value field
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <filesystem>
|
||||
|
||||
#include "fsfw/cfdp.h"
|
||||
#include "fsfw/cfdp/handler/PutRequest.h"
|
||||
#include "fsfw/cfdp/handler/SourceHandler.h"
|
||||
#include "fsfw/cfdp/pdu/EofPduCreator.h"
|
||||
#include "fsfw/cfdp/pdu/FileDataCreator.h"
|
||||
@ -18,6 +20,7 @@
|
||||
TEST_CASE("CFDP Source Handler", "[cfdp]") {
|
||||
using namespace cfdp;
|
||||
using namespace returnvalue;
|
||||
using namespace std::filesystem;
|
||||
MessageQueueId_t destQueueId = 2;
|
||||
AcceptsTmMock tmReceiver(destQueueId);
|
||||
MessageQueueMock mqMock(destQueueId);
|
||||
@ -36,4 +39,22 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") {
|
||||
StorageManagerMock tmStore(3, storeCfg);
|
||||
FsfwParams fp(tmReceiver, &mqMock, &eventReporterMock);
|
||||
auto sourceHandler = SourceHandler(dp, fp);
|
||||
|
||||
SECTION("Test Basic") {
|
||||
CHECK(sourceHandler.getState() == CfdpState::IDLE);
|
||||
CHECK(sourceHandler.getStep() == SourceHandler::TransactionStep::IDLE);
|
||||
}
|
||||
|
||||
SECTION("Transfer empty file") {
|
||||
RemoteEntityCfg cfg;
|
||||
EntityId id(cfdp::WidthInBytes::ONE_BYTE, 5);
|
||||
cfg.remoteId = id;
|
||||
FilesystemParams srcFileName("/tmp/cfdp-test.txt");
|
||||
fsMock.createFile(srcFileName);
|
||||
cfdp::StringLv srcNameLv(srcFileName.path, std::strlen(srcFileName.path));
|
||||
FilesystemParams destFileName("/tmp/cfdp-test.txt");
|
||||
cfdp::StringLv destNameLv(destFileName.path, std::strlen(destFileName.path));
|
||||
PutRequest putRequest(id, srcNameLv, destNameLv);
|
||||
CHECK(sourceHandler.transactionStart(putRequest, cfg) == OK);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user