Merge branch 'cfdp-source-handler' of https://egit.irs.uni-stuttgart.de/eive/fsfw into cfdp-source-handler
This commit is contained in:
commit
4c9e731113
@ -32,6 +32,7 @@ add_subdirectory(timemanager)
|
||||
add_subdirectory(tmtcpacket)
|
||||
add_subdirectory(tmtcservices)
|
||||
add_subdirectory(filesystem)
|
||||
add_subdirectory(util)
|
||||
|
||||
# Optional
|
||||
|
||||
|
@ -3,8 +3,8 @@
|
||||
#include "fsfw/serialize/SerializeAdapter.h"
|
||||
#include "fsfw/serviceinterface.h"
|
||||
|
||||
cfdp::VarLenField::VarLenField(cfdp::WidthInBytes width, size_t value) : VarLenField() {
|
||||
ReturnValue_t result = this->setValue(width, value);
|
||||
cfdp::VarLenField::VarLenField(cfdp::WidthInBytes width, uint64_t value) : VarLenField() {
|
||||
ReturnValue_t result = this->setValueAndWidth(width, value);
|
||||
if (result != returnvalue::OK) {
|
||||
#if FSFW_DISABLE_PRINTOUT == 0
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
@ -20,8 +20,8 @@ cfdp::VarLenField::VarLenField() : width(cfdp::WidthInBytes::ONE_BYTE) { value.o
|
||||
|
||||
cfdp::WidthInBytes cfdp::VarLenField::getWidth() const { return width; }
|
||||
|
||||
ReturnValue_t cfdp::VarLenField::setValue(cfdp::WidthInBytes widthInBytes, size_t value_) {
|
||||
switch (widthInBytes) {
|
||||
ReturnValue_t cfdp::VarLenField::setValueAndWidth(cfdp::WidthInBytes width_, uint64_t value_) {
|
||||
switch (width_) {
|
||||
case (cfdp::WidthInBytes::ONE_BYTE): {
|
||||
if (value_ > UINT8_MAX) {
|
||||
return returnvalue::FAILED;
|
||||
@ -43,15 +43,18 @@ ReturnValue_t cfdp::VarLenField::setValue(cfdp::WidthInBytes widthInBytes, size_
|
||||
this->value.fourBytes = value_;
|
||||
break;
|
||||
}
|
||||
case (cfdp::WidthInBytes::EIGHT_BYTES): {
|
||||
this->value.eightBytes = value_;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
this->width = widthInBytes;
|
||||
this->width = width_;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
size_t cfdp::VarLenField::getValue() const {
|
||||
uint64_t cfdp::VarLenField::getValue() const {
|
||||
switch (width) {
|
||||
case (cfdp::WidthInBytes::ONE_BYTE): {
|
||||
return value.oneByte;
|
||||
@ -62,6 +65,9 @@ size_t cfdp::VarLenField::getValue() const {
|
||||
case (cfdp::WidthInBytes::FOUR_BYTES): {
|
||||
return value.fourBytes;
|
||||
}
|
||||
case (cfdp::WidthInBytes::EIGHT_BYTES): {
|
||||
return value.eightBytes;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -84,6 +90,10 @@ ReturnValue_t cfdp::VarLenField::serialize(uint8_t **buffer, size_t *size, size_
|
||||
case (cfdp::WidthInBytes::FOUR_BYTES): {
|
||||
return SerializeAdapter::serialize(&value.fourBytes, buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
case (cfdp::WidthInBytes::EIGHT_BYTES): {
|
||||
return SerializeAdapter::serialize(&value.eightBytes, buffer, size, maxSize,
|
||||
streamEndianness);
|
||||
}
|
||||
default: {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
@ -98,6 +108,10 @@ ReturnValue_t cfdp::VarLenField::deSerialize(cfdp::WidthInBytes width_, const ui
|
||||
return deSerialize(buffer, size, streamEndianness);
|
||||
}
|
||||
|
||||
ReturnValue_t cfdp::VarLenField::setValue(uint64_t value_) {
|
||||
return setValueAndWidth(getWidth(), value_);
|
||||
}
|
||||
|
||||
ReturnValue_t cfdp::VarLenField::deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) {
|
||||
switch (width) {
|
||||
@ -112,6 +126,9 @@ ReturnValue_t cfdp::VarLenField::deSerialize(const uint8_t **buffer, size_t *siz
|
||||
case (cfdp::WidthInBytes::FOUR_BYTES): {
|
||||
return SerializeAdapter::deSerialize(&value.fourBytes, buffer, size, streamEndianness);
|
||||
}
|
||||
case (cfdp::WidthInBytes::EIGHT_BYTES): {
|
||||
return SerializeAdapter::deSerialize(&value.eightBytes, buffer, size, streamEndianness);
|
||||
}
|
||||
default: {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
@ -31,7 +31,8 @@ class VarLenField : public SerializeIF {
|
||||
bool operator!=(const VarLenField &other) const;
|
||||
bool operator<(const VarLenField &other) const;
|
||||
|
||||
ReturnValue_t setValue(cfdp::WidthInBytes, size_t value);
|
||||
ReturnValue_t setValueAndWidth(cfdp::WidthInBytes width, uint64_t value);
|
||||
ReturnValue_t setValue(uint64_t value);
|
||||
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
@ -64,7 +65,7 @@ template <typename T>
|
||||
cfdp::VarLenField::VarLenField(UnsignedByteField<T> byteField)
|
||||
: width(static_cast<cfdp::WidthInBytes>(sizeof(T))) {
|
||||
static_assert((sizeof(T) % 2) == 0);
|
||||
setValue(width, byteField.getValue());
|
||||
setValueAndWidth(width, byteField.getValue());
|
||||
}
|
||||
|
||||
struct EntityId : public VarLenField {
|
||||
|
@ -68,6 +68,7 @@ enum WidthInBytes : uint8_t {
|
||||
ONE_BYTE = 1,
|
||||
TWO_BYTES = 2,
|
||||
FOUR_BYTES = 4,
|
||||
EIGHT_BYTES = 8
|
||||
};
|
||||
|
||||
enum FileDirective : uint8_t {
|
||||
|
@ -9,12 +9,33 @@
|
||||
#include "fsfw/cfdp/pdu/MetadataPduCreator.h"
|
||||
#include "fsfw/filesystem/HasFileSystemIF.h"
|
||||
#include "fsfw/objectmanager.h"
|
||||
#include "fsfw/serviceinterface.h"
|
||||
#include "fsfw/tmtcservices/TmTcMessage.h"
|
||||
|
||||
using namespace returnvalue;
|
||||
|
||||
cfdp::SourceHandler::SourceHandler(SourceHandlerParams params, FsfwParams fsfwParams)
|
||||
: sourceParams(std::move(params)), fsfwParams(fsfwParams) {}
|
||||
: sourceParams(std::move(params)), fsfwParams(fsfwParams) {
|
||||
// The entity ID portion of the transaction ID will always remain fixed.
|
||||
transactionParams.id.entityId = sourceParams.cfg.localId;
|
||||
if (sourceParams.seqCountProvider.bitWidth() == 8) {
|
||||
transactionParams.seqCountWidth = cfdp::WidthInBytes::ONE_BYTE;
|
||||
} else if (sourceParams.seqCountProvider.bitWidth() == 16) {
|
||||
transactionParams.seqCountWidth = cfdp::WidthInBytes::TWO_BYTES;
|
||||
} else if (sourceParams.seqCountProvider.bitWidth() == 32) {
|
||||
transactionParams.seqCountWidth = cfdp::WidthInBytes::FOUR_BYTES;
|
||||
} else {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "cfdp::SourceHandler: Seq count provider bit width "
|
||||
<< sourceParams.seqCountProvider.bitWidth() << " not allowed" << std::endl;
|
||||
#else
|
||||
sif::printError("cfdp::SourceHandler: Seq count provider bit width %d not allowed\n",
|
||||
sourceParams.seqCountProvider.bitWidth());
|
||||
#endif
|
||||
// Yeah, what am I supposed to do here? Can't throw an exception in the FSFW..
|
||||
transactionParams.seqCountWidth = cfdp::WidthInBytes::ONE_BYTE;
|
||||
}
|
||||
}
|
||||
|
||||
cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() {
|
||||
ReturnValue_t result;
|
||||
@ -22,6 +43,7 @@ cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() {
|
||||
step = TransactionStep::TRANSACTION_START;
|
||||
}
|
||||
if (step == TransactionStep::TRANSACTION_START) {
|
||||
sourceParams.user.transactionIndication(transactionParams.id);
|
||||
step = TransactionStep::CRC_PROCEDURE;
|
||||
}
|
||||
if (step == TransactionStep::CRC_PROCEDURE) {
|
||||
@ -50,19 +72,23 @@ cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() {
|
||||
if (result != OK) {
|
||||
// TODO: Error handling
|
||||
}
|
||||
if (sourceParams.cfg.indicCfg.eofSentIndicRequired) {
|
||||
sourceParams.user.eofSentIndication(transactionParams.id);
|
||||
}
|
||||
if (transactionParams.closureRequested) {
|
||||
step = TransactionStep::WAIT_FOR_FINISH;
|
||||
return fsmResult;
|
||||
}
|
||||
step = TransactionStep::NOTICE_OF_COMPLETION;
|
||||
}
|
||||
if (step == TransactionStep::WAIT_FOR_FINISH) {
|
||||
// TODO: In case this is a request with closure, wait for finish.
|
||||
// Done, issue notice of completion
|
||||
step = TransactionStep::NOTICE_OF_COMPLETION;
|
||||
}
|
||||
if (step == TransactionStep::NOTICE_OF_COMPLETION) {
|
||||
// TODO: Notice of completion
|
||||
// We are done, go back to idle state.
|
||||
// TODO: Possible reset state?
|
||||
step = TransactionStep::IDLE;
|
||||
state = CfdpState::IDLE;
|
||||
noticeOfCompletion();
|
||||
reset();
|
||||
}
|
||||
return fsmResult;
|
||||
}
|
||||
@ -78,6 +104,11 @@ cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::stateMachine() {
|
||||
}
|
||||
|
||||
ReturnValue_t cfdp::SourceHandler::checksumGeneration() {
|
||||
if (transactionParams.fileSize.value() == 0) {
|
||||
// NULL checksum for empty file.
|
||||
transactionParams.crc = 0;
|
||||
return OK;
|
||||
}
|
||||
std::array<uint8_t, 1024> buf{};
|
||||
etl::crc32 crcCalc;
|
||||
uint64_t currentOffset = 0;
|
||||
@ -135,6 +166,7 @@ ReturnValue_t cfdp::SourceHandler::putRequest(PutRequestFull& putRequest, Remote
|
||||
// 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;
|
||||
transactionParams.id.seqNum.setValue(sourceParams.seqCountProvider.getAndIncrement());
|
||||
|
||||
if (transactionParams.pduConf.mode == TransmissionMode::ACKNOWLEDGED) {
|
||||
state = cfdp::CfdpState::BUSY_CLASS_2_ACKED;
|
||||
@ -206,14 +238,13 @@ ReturnValue_t cfdp::SourceHandler::prepareAndSendNextFileDataPdu() {
|
||||
}
|
||||
|
||||
ReturnValue_t cfdp::SourceHandler::prepareAndSendEofPdu() {
|
||||
// TODO: Checksum
|
||||
auto eofInfo = EofInfo(ConditionCode::NO_ERROR, 0, transactionParams.fileSize);
|
||||
auto eofInfo =
|
||||
EofInfo(ConditionCode::NO_ERROR, transactionParams.crc, transactionParams.fileSize);
|
||||
auto eofPdu = EofPduCreator(transactionParams.pduConf, eofInfo);
|
||||
ReturnValue_t result = sendGenericPdu(eofPdu);
|
||||
if (result != OK) {
|
||||
return result;
|
||||
}
|
||||
step = TransactionStep::WAIT_FOR_FINISH;
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -255,3 +286,20 @@ ReturnValue_t cfdp::SourceHandler::sendGenericPdu(const SerializeIF& pdu) const
|
||||
TmTcMessage tcMsg(storeId);
|
||||
return fsfwParams.msgQueue->sendMessage(fsfwParams.packetDest.getReportReceptionQueue(), &tcMsg);
|
||||
}
|
||||
|
||||
ReturnValue_t cfdp::SourceHandler::noticeOfCompletion() {
|
||||
if (sourceParams.cfg.indicCfg.transactionFinishedIndicRequired) {
|
||||
cfdp::TransactionFinishedParams params(transactionParams.id, ConditionCode::NO_ERROR,
|
||||
FileDeliveryCode::DATA_COMPLETE,
|
||||
FileDeliveryStatus::RETAINED_IN_FILESTORE);
|
||||
sourceParams.user.transactionFinishedIndication(params);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
ReturnValue_t cfdp::SourceHandler::reset() {
|
||||
step = TransactionStep::IDLE;
|
||||
state = cfdp::CfdpState::IDLE;
|
||||
transactionParams.reset();
|
||||
return OK;
|
||||
}
|
||||
|
@ -11,15 +11,17 @@
|
||||
#include "fsfw/events/EventReportingProxyIF.h"
|
||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
|
||||
#include "fsfw/util/ProvidesSeqCountIF.h"
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
struct SourceHandlerParams {
|
||||
SourceHandlerParams(LocalEntityCfg cfg, UserBase& user) : cfg(std::move(cfg)), user(user) {}
|
||||
SourceHandlerParams(LocalEntityCfg cfg, UserBase& user, ProvidesSeqCountIF& seqCountProvider)
|
||||
: cfg(std::move(cfg)), user(user), seqCountProvider(seqCountProvider) {}
|
||||
|
||||
LocalEntityCfg cfg;
|
||||
UserBase& user;
|
||||
size_t maxFilePathSize = 256;
|
||||
ProvidesSeqCountIF& seqCountProvider;
|
||||
};
|
||||
|
||||
class SourceHandler {
|
||||
@ -69,7 +71,18 @@ class SourceHandler {
|
||||
bool closureRequested = false;
|
||||
RemoteEntityCfg remoteCfg;
|
||||
PduConfig pduConf;
|
||||
cfdp::TransactionId id{};
|
||||
cfdp::WidthInBytes seqCountWidth;
|
||||
|
||||
void reset() {
|
||||
sourceNameSize = 0;
|
||||
destNameSize = 0;
|
||||
fileSize.setFileSize(0, false);
|
||||
progress = 0;
|
||||
closureRequested = false;
|
||||
}
|
||||
} transactionParams;
|
||||
|
||||
cfdp::CfdpState state = cfdp::CfdpState::IDLE;
|
||||
TransactionStep step = TransactionStep::IDLE;
|
||||
std::array<uint8_t, 4096> fileBuf{};
|
||||
@ -82,8 +95,10 @@ class SourceHandler {
|
||||
ReturnValue_t prepareAndSendMetadataPdu();
|
||||
ReturnValue_t prepareAndSendNextFileDataPdu();
|
||||
ReturnValue_t prepareAndSendEofPdu();
|
||||
ReturnValue_t noticeOfCompletion();
|
||||
ReturnValue_t reset();
|
||||
|
||||
ReturnValue_t sendGenericPdu(const SerializeIF& pdu) const;
|
||||
[[nodiscard]] ReturnValue_t sendGenericPdu(const SerializeIF& pdu) const;
|
||||
};
|
||||
|
||||
} // namespace cfdp
|
||||
|
@ -103,11 +103,11 @@ void PduHeaderReader::getTransactionSeqNum(cfdp::TransactionSeqNum &seqNum) cons
|
||||
}
|
||||
|
||||
void PduHeaderReader::assignVarLenField(cfdp::VarLenField *field, cfdp::WidthInBytes width,
|
||||
void *sourcePtr) const {
|
||||
void *sourcePtr) {
|
||||
switch (width) {
|
||||
case (cfdp::WidthInBytes::ONE_BYTE): {
|
||||
auto *fieldTyped = static_cast<uint8_t *>(sourcePtr);
|
||||
field->setValue(width, *fieldTyped);
|
||||
field->setValueAndWidth(width, *fieldTyped);
|
||||
break;
|
||||
}
|
||||
case (cfdp::WidthInBytes::TWO_BYTES): {
|
||||
@ -115,7 +115,7 @@ void PduHeaderReader::assignVarLenField(cfdp::VarLenField *field, cfdp::WidthInB
|
||||
size_t deserSize = 0;
|
||||
SerializeAdapter::deSerialize(&fieldTyped, static_cast<uint8_t *>(sourcePtr), &deserSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
field->setValue(width, fieldTyped);
|
||||
field->setValueAndWidth(width, fieldTyped);
|
||||
break;
|
||||
}
|
||||
case (cfdp::WidthInBytes::FOUR_BYTES): {
|
||||
@ -123,7 +123,15 @@ void PduHeaderReader::assignVarLenField(cfdp::VarLenField *field, cfdp::WidthInB
|
||||
size_t deserSize = 0;
|
||||
SerializeAdapter::deSerialize(&fieldTyped, static_cast<uint8_t *>(sourcePtr), &deserSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
field->setValue(width, fieldTyped);
|
||||
field->setValueAndWidth(width, fieldTyped);
|
||||
break;
|
||||
}
|
||||
case (cfdp::WidthInBytes::EIGHT_BYTES): {
|
||||
uint64_t fieldTyped = 0;
|
||||
size_t deserSize = 0;
|
||||
SerializeAdapter::deSerialize(&fieldTyped, static_cast<uint8_t *>(sourcePtr), &deserSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
field->setValueAndWidth(width, fieldTyped);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -105,7 +105,8 @@ class PduHeaderReader : public RedirectableDataPointerIF, public PduHeaderIF {
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t setData(uint8_t* dataPtr, size_t maxSize, void* args) override;
|
||||
void assignVarLenField(cfdp::VarLenField* field, cfdp::WidthInBytes width, void* sourcePtr) const;
|
||||
static void assignVarLenField(cfdp::VarLenField* field, cfdp::WidthInBytes width,
|
||||
void* sourcePtr);
|
||||
void* sourceIdRaw = nullptr;
|
||||
void* seqNumRaw = nullptr;
|
||||
void* destIdRaw = nullptr;
|
||||
|
1
src/fsfw/util/CMakeLists.txt
Normal file
1
src/fsfw/util/CMakeLists.txt
Normal file
@ -0,0 +1 @@
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE)
|
19
src/fsfw/util/ProvidesSeqCountIF.h
Normal file
19
src/fsfw/util/ProvidesSeqCountIF.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class ProvidesSeqCountIF {
|
||||
public:
|
||||
virtual ~ProvidesSeqCountIF() = default;
|
||||
|
||||
[[nodiscard]] virtual unsigned int bitWidth() const = 0;
|
||||
|
||||
virtual uint64_t get() = 0;
|
||||
virtual void increment() = 0;
|
||||
|
||||
virtual uint64_t getAndIncrement() {
|
||||
uint64_t val = get();
|
||||
increment();
|
||||
return val;
|
||||
}
|
||||
};
|
25
src/fsfw/util/SeqCountProvider.h
Normal file
25
src/fsfw/util/SeqCountProvider.h
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "ProvidesSeqCountIF.h"
|
||||
|
||||
template <typename T>
|
||||
class SeqCountProvider : public ProvidesSeqCountIF {
|
||||
static_assert(std::is_same<T, uint8_t>::value || std::is_same<T, uint16_t>::value ||
|
||||
std::is_same<T, uint32_t>::value,
|
||||
"Only uint8_t, uint16_t, and uint32_t are allowed.");
|
||||
|
||||
public:
|
||||
[[nodiscard]] unsigned int bitWidth() const override { return sizeof(T) * 8; }
|
||||
uint64_t get() override { return counter; }
|
||||
// I'm also abusing the primitive C variable overflow wrap around here.
|
||||
void increment() override { counter++; }
|
||||
|
||||
private:
|
||||
T counter{};
|
||||
};
|
||||
|
||||
using SeqCountProviderU8 = SeqCountProvider<uint8_t>;
|
||||
using SeqCountProviderU16 = SeqCountProvider<uint16_t>;
|
||||
using SeqCountProviderU32 = SeqCountProvider<uint32_t>;
|
@ -5,6 +5,7 @@
|
||||
#include "fsfw/cfdp/pdu/EofPduCreator.h"
|
||||
#include "fsfw/cfdp/pdu/FileDataCreator.h"
|
||||
#include "fsfw/cfdp/pdu/MetadataPduCreator.h"
|
||||
#include "fsfw/util/SeqCountProvider.h"
|
||||
#include "mocks/AcceptsTmMock.h"
|
||||
#include "mocks/EventReportingProxyMock.h"
|
||||
#include "mocks/FilesystemMock.h"
|
||||
@ -26,7 +27,8 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") {
|
||||
LocalEntityCfg localEntityCfg(localId, IndicationCfg(), fhMock);
|
||||
FilesystemMock fsMock;
|
||||
UserMock userMock(fsMock);
|
||||
SourceHandlerParams dp(localEntityCfg, userMock);
|
||||
SeqCountProviderU16 seqCountProvider;
|
||||
SourceHandlerParams dp(localEntityCfg, userMock, seqCountProvider);
|
||||
|
||||
EventReportingProxyMock eventReporterMock;
|
||||
LocalPool::LocalPoolConfig storeCfg = {{10, 32}, {10, 64}, {10, 128}, {10, 1024}};
|
||||
|
@ -110,9 +110,9 @@ TEST_CASE("CFDP Header", "[cfdp]") {
|
||||
}
|
||||
|
||||
SECTION("Other variable sized fields") {
|
||||
pduConf.seqNum.setValue(cfdp::WidthInBytes::TWO_BYTES, 0x0fff);
|
||||
pduConf.sourceId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0xff00ff00);
|
||||
pduConf.destId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0x00ff00ff);
|
||||
pduConf.seqNum.setValueAndWidth(cfdp::WidthInBytes::TWO_BYTES, 0x0fff);
|
||||
pduConf.sourceId.setValueAndWidth(cfdp::WidthInBytes::FOUR_BYTES, 0xff00ff00);
|
||||
pduConf.destId.setValueAndWidth(cfdp::WidthInBytes::FOUR_BYTES, 0x00ff00ff);
|
||||
REQUIRE(pduConf.sourceId.getSerializedSize() == 4);
|
||||
REQUIRE(creator.getSerializedSize() == 14);
|
||||
REQUIRE(creator.serialize(&serTarget, &serSize, serBuf.size(),
|
||||
@ -146,9 +146,9 @@ TEST_CASE("CFDP Header", "[cfdp]") {
|
||||
}
|
||||
|
||||
SECTION("Buffer Too Short") {
|
||||
pduConf.seqNum.setValue(cfdp::WidthInBytes::TWO_BYTES, 0x0fff);
|
||||
pduConf.sourceId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0xff00ff00);
|
||||
pduConf.destId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0x00ff00ff);
|
||||
pduConf.seqNum.setValueAndWidth(cfdp::WidthInBytes::TWO_BYTES, 0x0fff);
|
||||
pduConf.sourceId.setValueAndWidth(cfdp::WidthInBytes::FOUR_BYTES, 0xff00ff00);
|
||||
pduConf.destId.setValueAndWidth(cfdp::WidthInBytes::FOUR_BYTES, 0x00ff00ff);
|
||||
for (uint8_t idx = 0; idx < 14; idx++) {
|
||||
REQUIRE(creator.serialize(&serTarget, &serSize, idx, SerializeIF::Endianness::BIG) ==
|
||||
SerializeIF::BUFFER_TOO_SHORT);
|
||||
@ -157,11 +157,11 @@ TEST_CASE("CFDP Header", "[cfdp]") {
|
||||
}
|
||||
|
||||
SECTION("Invalid Variable Sized Fields") {
|
||||
result = pduConf.sourceId.setValue(cfdp::WidthInBytes::ONE_BYTE, 0xfff);
|
||||
result = pduConf.sourceId.setValueAndWidth(cfdp::WidthInBytes::ONE_BYTE, 0xfff);
|
||||
REQUIRE(result == returnvalue::FAILED);
|
||||
result = pduConf.sourceId.setValue(cfdp::WidthInBytes::TWO_BYTES, 0xfffff);
|
||||
result = pduConf.sourceId.setValueAndWidth(cfdp::WidthInBytes::TWO_BYTES, 0xfffff);
|
||||
REQUIRE(result == returnvalue::FAILED);
|
||||
result = pduConf.sourceId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0xfffffffff);
|
||||
result = pduConf.sourceId.setValueAndWidth(cfdp::WidthInBytes::FOUR_BYTES, 0xfffffffff);
|
||||
REQUIRE(result == returnvalue::FAILED);
|
||||
}
|
||||
|
||||
@ -207,7 +207,7 @@ TEST_CASE("CFDP Header", "[cfdp]") {
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(pduConf.sourceId.getValue() == 0xf0f0f0f0);
|
||||
|
||||
pduConf.sourceId.setValue(cfdp::WidthInBytes::ONE_BYTE, 1);
|
||||
pduConf.sourceId.setValueAndWidth(cfdp::WidthInBytes::ONE_BYTE, 1);
|
||||
serTarget = serBuf.data();
|
||||
serSize = 1;
|
||||
result = pduConf.sourceId.serialize(&serTarget, &serSize, 1, SerializeIF::Endianness::MACHINE);
|
||||
@ -257,11 +257,11 @@ TEST_CASE("CFDP Header", "[cfdp]") {
|
||||
creator.setSegmentationControl(cfdp::SegmentationControl::RECORD_BOUNDARIES_PRESERVATION);
|
||||
creator.setPduType(cfdp::PduType::FILE_DATA);
|
||||
creator.setSegmentMetadataFlag(cfdp::SegmentMetadataFlag::PRESENT);
|
||||
result = pduConf.seqNum.setValue(cfdp::WidthInBytes::TWO_BYTES, 0x0fff);
|
||||
result = pduConf.seqNum.setValueAndWidth(cfdp::WidthInBytes::TWO_BYTES, 0x0fff);
|
||||
REQUIRE(result == returnvalue::OK);
|
||||
result = pduConf.sourceId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0xff00ff00);
|
||||
result = pduConf.sourceId.setValueAndWidth(cfdp::WidthInBytes::FOUR_BYTES, 0xff00ff00);
|
||||
REQUIRE(result == returnvalue::OK);
|
||||
result = pduConf.destId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0x00ff00ff);
|
||||
result = pduConf.destId.setValueAndWidth(cfdp::WidthInBytes::FOUR_BYTES, 0x00ff00ff);
|
||||
REQUIRE(result == returnvalue::OK);
|
||||
serTarget = serBuf.data();
|
||||
serSize = 0;
|
||||
@ -302,8 +302,8 @@ TEST_CASE("CFDP Header", "[cfdp]") {
|
||||
SECTION("Manipulate Source Dest ID") {
|
||||
serTarget = serBuf.data();
|
||||
serSize = 0;
|
||||
pduConf.sourceId.setValue(cfdp::WidthInBytes::ONE_BYTE, 22);
|
||||
pduConf.destId.setValue(cfdp::WidthInBytes::ONE_BYTE, 48);
|
||||
pduConf.sourceId.setValueAndWidth(cfdp::WidthInBytes::ONE_BYTE, 22);
|
||||
pduConf.destId.setValueAndWidth(cfdp::WidthInBytes::ONE_BYTE, 48);
|
||||
result = creator.serialize(&serTarget, &serSize, serBuf.size(), SerializeIF::Endianness::BIG);
|
||||
reader.getSourceId(sourceDestId);
|
||||
REQUIRE(sourceDestId.getWidth() == cfdp::WidthInBytes::ONE_BYTE);
|
||||
|
@ -40,7 +40,7 @@ TEST_CASE("CFDP TLV", "[cfdp][tlv]") {
|
||||
SECTION("TLV Other Value") {
|
||||
auto tlv = Tlv(TlvType::ENTITY_ID, rawBuf.data(), deserSize);
|
||||
// Set new value
|
||||
sourceId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 12);
|
||||
sourceId.setValueAndWidth(cfdp::WidthInBytes::FOUR_BYTES, 12);
|
||||
REQUIRE(sourceId.serialize(&serPtr, &deserSize, rawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK) == returnvalue::OK);
|
||||
tlv.setValue(rawBuf.data(), cfdp::WidthInBytes::FOUR_BYTES);
|
||||
|
@ -1 +1,2 @@
|
||||
target_sources(${FSFW_TEST_TGT} PRIVATE testUnsignedByteField.cpp)
|
||||
target_sources(${FSFW_TEST_TGT} PRIVATE testUnsignedByteField.cpp
|
||||
testSeqCountProvider.cpp)
|
||||
|
35
unittests/util/testSeqCountProvider.cpp
Normal file
35
unittests/util/testSeqCountProvider.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw/util/SeqCountProvider.h"
|
||||
|
||||
TEST_CASE("Seq Count Providers", "[util]") {
|
||||
auto genericProviderTest = [](ProvidesSeqCountIF& provider, unsigned expectedWidth) {
|
||||
CHECK(provider.get() == 0);
|
||||
CHECK(provider.bitWidth() == expectedWidth);
|
||||
CHECK(provider.getAndIncrement() == 0);
|
||||
CHECK(provider.getAndIncrement() == 1);
|
||||
CHECK(provider.get() == 2);
|
||||
provider.increment();
|
||||
provider.increment();
|
||||
CHECK(provider.get() == 4);
|
||||
};
|
||||
{
|
||||
SeqCountProviderU16 provider;
|
||||
genericProviderTest(provider, 16);
|
||||
}
|
||||
|
||||
{
|
||||
SeqCountProviderU32 provider;
|
||||
genericProviderTest(provider, 32);
|
||||
}
|
||||
|
||||
{
|
||||
SeqCountProviderU8 provider;
|
||||
genericProviderTest(provider, 8);
|
||||
for (unsigned i = 4; i < UINT8_MAX + 1; i++) {
|
||||
provider.increment();
|
||||
}
|
||||
// Verify wrap-around.
|
||||
CHECK(provider.get() == 0);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user