Merge branch 'refactor-fix-ptme' into cfdp-source-handler
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit

This commit is contained in:
2023-10-13 09:45:21 +02:00
34 changed files with 392 additions and 113 deletions

View File

@ -138,8 +138,17 @@ ReturnValue_t TmStoreTaskBase::performDump(PersistentTmStoreWithTmQueue& store,
return result;
}
dumpedLen = tmReader.getFullPacketLen();
result = channel.write(tmReader.getFullData(), dumpedLen);
if (result == DirectTmSinkIF::IS_BUSY) {
size_t partiallyWrittenSize = 0;
result = channel.write(tmReader.getFullData(), dumpedLen, partiallyWrittenSize);
if (result == VirtualChannelIF::PARTIALLY_WRITTEN) {
result = channel.handleLastWriteSynchronously(tmReader.getFullData(), partiallyWrittenSize,
dumpedLen - partiallyWrittenSize, 200);
if (result != returnvalue::OK) {
// TODO: Event? Might lead to dangerous spam though..
sif::warning << "PersistentTmStore: Synchronous write of last segment failed with code 0x"
<< std::setw(4) << std::hex << result << std::dec << std::endl;
}
} else if (result == DirectTmSinkIF::IS_BUSY) {
sif::warning << "PersistentTmStore: Unexpected VC channel busy" << std::endl;
} else if (result != returnvalue::OK) {
sif::warning << "PersistentTmStore: Unexpected VC channel write failure" << std::endl;

View File

@ -1,25 +1,64 @@
#include "VirtualChannel.h"
#include <fsfw/tasks/TaskFactory.h>
VirtualChannel::VirtualChannel(object_id_t objectId, uint8_t vcId, const char* vcName, PtmeIF& ptme,
const std::atomic_bool& txOn)
: SystemObject(objectId), ptme(ptme), vcId(vcId), vcName(vcName), txOn(txOn) {}
ReturnValue_t VirtualChannel::initialize() { return returnvalue::OK; }
ReturnValue_t VirtualChannel::sendNextTm(const uint8_t* data, size_t size) {
return write(data, size);
ReturnValue_t VirtualChannel::sendNextTm(const uint8_t* data, size_t size, size_t& writtenSize) {
return write(data, size, writtenSize);
}
ReturnValue_t VirtualChannel::write(const uint8_t* data, size_t size) {
return ptme.writeToVc(vcId, data, size);
ReturnValue_t VirtualChannel::write(const uint8_t* data, size_t size, size_t& writtenSize) {
if (!ptme.containsVc(vcId)) {
return CHANNEL_DOES_NOT_EXIST;
}
return ptme.getVirtChannel(vcId)->write(data, size, writtenSize);
}
uint8_t VirtualChannel::getVcid() const { return vcId; }
ReturnValue_t VirtualChannel::finishWrite(const uint8_t* data, size_t start, size_t remainingSize) {
if (!ptme.containsVc(vcId)) {
return CHANNEL_DOES_NOT_EXIST;
}
return ptme.getVirtChannel(vcId)->finishWrite(data, start, remainingSize);
}
const char* VirtualChannel::getName() const { return vcName.c_str(); }
bool VirtualChannel::isBusy() const { return ptme.isBusy(vcId); }
bool VirtualChannel::isBusy() const {
if (!ptme.containsVc(vcId)) {
return CHANNEL_DOES_NOT_EXIST;
}
return ptme.getVirtChannel(vcId)->isBusy();
}
void VirtualChannel::cancelTransfer() { ptme.cancelTransfer(vcId); }
void VirtualChannel::cancelTransfer() {
if (!ptme.containsVc(vcId)) {
return;
}
ptme.getVirtChannel(vcId)->cancelTransfer();
}
bool VirtualChannel::isTxOn() const { return txOn; }
ReturnValue_t VirtualChannel::handleLastWriteSynchronously(const uint8_t* data, size_t start,
size_t remLen, unsigned maxDelayMs) {
unsigned delayMs = 0;
while (true) {
if (isBusy()) {
if (delayMs >= maxDelayMs) {
break;
}
TaskFactory::delayTask(10);
delayMs += 10;
continue;
}
return finishWrite(data, start, remLen);
}
return returnvalue::FAILED;
}

View File

@ -15,6 +15,10 @@
*/
class VirtualChannel : public SystemObject, public VirtualChannelIF {
public:
static constexpr uint8_t CLASS_ID = CLASS_ID::VIRTUAL_CHANNEL;
static constexpr ReturnValue_t CHANNEL_DOES_NOT_EXIST = returnvalue::makeCode(CLASS_ID, 0);
/**
* @brief Constructor
*
@ -25,9 +29,12 @@ class VirtualChannel : public SystemObject, public VirtualChannelIF {
const std::atomic_bool& linkStateProvider);
ReturnValue_t initialize() override;
ReturnValue_t sendNextTm(const uint8_t* data, size_t size);
ReturnValue_t sendNextTm(const uint8_t* data, size_t size, size_t& writtenSize);
bool isBusy() const override;
ReturnValue_t write(const uint8_t* data, size_t size) override;
ReturnValue_t write(const uint8_t* data, size_t size, size_t& writtenSize) override;
ReturnValue_t finishWrite(const uint8_t* data, size_t start, size_t remainingSize) override;
ReturnValue_t handleLastWriteSynchronously(const uint8_t* data, size_t start, size_t remLen,
unsigned maxDelayMs);
void cancelTransfer() override;
uint8_t getVcid() const;
bool isTxOn() const;

View File

@ -36,8 +36,19 @@ ReturnValue_t VirtualChannelWithQueue::handleNextTm(bool performWriteOp) {
return result;
}
// TODO: Hnadle partial write handling
size_t partiallyWrittenSize = 0;
if (performWriteOp) {
result = write(data, size);
result = write(data, size, partiallyWrittenSize);
if (result == PARTIALLY_WRITTEN) {
result = handleLastWriteSynchronously(data, size, partiallyWrittenSize, 200);
if (result != returnvalue::OK) {
// TODO: Event? Might lead to dangerous spam though..
sif::warning
<< "VirtualChannelWithQueue: Synchronous write of last segment failed with code 0x"
<< std::setw(4) << std::hex << result << std::dec << std::endl;
}
}
}
// Try delete in any case, ignore failures (which should not happen), it is more important to
// propagate write errors.