2021-09-26 08:29:30 +02:00
|
|
|
#include "VirtualChannel.h"
|
2021-09-22 16:54:55 +02:00
|
|
|
|
2023-10-13 09:20:51 +02:00
|
|
|
#include <fsfw/tasks/TaskFactory.h>
|
|
|
|
|
2023-03-09 17:44:05 +01:00
|
|
|
VirtualChannel::VirtualChannel(object_id_t objectId, uint8_t vcId, const char* vcName, PtmeIF& ptme,
|
2023-03-27 21:23:09 +02:00
|
|
|
const std::atomic_bool& txOn)
|
2023-03-27 21:39:37 +02:00
|
|
|
: SystemObject(objectId), ptme(ptme), vcId(vcId), vcName(vcName), txOn(txOn) {}
|
2023-03-09 17:44:05 +01:00
|
|
|
|
|
|
|
ReturnValue_t VirtualChannel::initialize() { return returnvalue::OK; }
|
|
|
|
|
2023-10-13 09:20:51 +02:00
|
|
|
ReturnValue_t VirtualChannel::sendNextTm(const uint8_t* data, size_t size, size_t& writtenSize) {
|
|
|
|
return write(data, size, writtenSize);
|
2021-09-22 16:54:55 +02:00
|
|
|
}
|
|
|
|
|
2023-10-13 09:20:51 +02:00
|
|
|
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);
|
2021-09-22 16:54:55 +02:00
|
|
|
}
|
|
|
|
|
2023-03-09 17:44:05 +01:00
|
|
|
uint8_t VirtualChannel::getVcid() const { return vcId; }
|
2022-09-16 11:43:11 +02:00
|
|
|
|
2023-10-13 15:10:52 +02:00
|
|
|
ReturnValue_t VirtualChannel::advanceWrite(size_t& writtenSize) {
|
2023-10-13 09:20:51 +02:00
|
|
|
if (!ptme.containsVc(vcId)) {
|
|
|
|
return CHANNEL_DOES_NOT_EXIST;
|
|
|
|
}
|
2023-10-13 15:10:52 +02:00
|
|
|
return ptme.getVirtChannel(vcId)->advanceWrite(writtenSize);
|
2023-10-13 09:20:51 +02:00
|
|
|
}
|
|
|
|
|
2023-10-13 15:24:06 +02:00
|
|
|
bool VirtualChannel::writeActive() const {
|
|
|
|
if (!ptme.containsVc(vcId)) {
|
|
|
|
return CHANNEL_DOES_NOT_EXIST;
|
|
|
|
}
|
|
|
|
return ptme.getVirtChannel(vcId)->writeActive();
|
|
|
|
}
|
|
|
|
|
2022-09-16 11:43:11 +02:00
|
|
|
const char* VirtualChannel::getName() const { return vcName.c_str(); }
|
2023-03-10 18:04:04 +01:00
|
|
|
|
2023-10-13 09:20:51 +02:00
|
|
|
bool VirtualChannel::isBusy() const {
|
|
|
|
if (!ptme.containsVc(vcId)) {
|
|
|
|
return CHANNEL_DOES_NOT_EXIST;
|
|
|
|
}
|
|
|
|
return ptme.getVirtChannel(vcId)->isBusy();
|
|
|
|
}
|
2023-03-23 18:31:47 +01:00
|
|
|
|
2023-10-13 09:20:51 +02:00
|
|
|
void VirtualChannel::cancelTransfer() {
|
|
|
|
if (!ptme.containsVc(vcId)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
ptme.getVirtChannel(vcId)->cancelTransfer();
|
|
|
|
}
|
2023-03-28 10:13:39 +02:00
|
|
|
|
2023-03-28 14:59:31 +02:00
|
|
|
bool VirtualChannel::isTxOn() const { return txOn; }
|
2023-10-13 09:20:51 +02:00
|
|
|
|
2023-10-13 15:10:52 +02:00
|
|
|
ReturnValue_t VirtualChannel::handleWriteCompletionSynchronously(size_t& writtenSize,
|
|
|
|
unsigned maxCompletionTimeMs) {
|
2023-10-13 09:20:51 +02:00
|
|
|
unsigned delayMs = 0;
|
|
|
|
while (true) {
|
|
|
|
if (isBusy()) {
|
2023-10-13 15:10:52 +02:00
|
|
|
if (delayMs >= maxCompletionTimeMs) {
|
2023-10-13 09:20:51 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
TaskFactory::delayTask(10);
|
|
|
|
delayMs += 10;
|
|
|
|
continue;
|
|
|
|
}
|
2023-10-13 15:10:52 +02:00
|
|
|
ReturnValue_t result = advanceWrite(writtenSize);
|
|
|
|
if (result == returnvalue::OK) {
|
|
|
|
// Transfer complete
|
|
|
|
return result;
|
|
|
|
} else if (result != PARTIALLY_WRITTEN) {
|
|
|
|
// Some error where we can not or should not continue the transfer.
|
|
|
|
return result;
|
|
|
|
}
|
2023-10-13 09:20:51 +02:00
|
|
|
}
|
2023-11-23 16:48:40 +01:00
|
|
|
// Timeout. Cancel the transfer
|
|
|
|
cancelTransfer();
|
|
|
|
return TIMEOUT;
|
2023-10-13 09:20:51 +02:00
|
|
|
}
|