#include "VirtualChannelWithQueue.h" #include "OBSWConfig.h" #include "fsfw/ipc/QueueFactory.h" #include "fsfw/objectmanager/ObjectManager.h" #include "fsfw/serviceinterface/ServiceInterfaceStream.h" #include "fsfw/tmtcservices/TmTcMessage.h" #include "mission/com/CcsdsIpCoreHandler.h" VirtualChannelWithQueue::VirtualChannelWithQueue(object_id_t objectId, uint8_t vcId, const char* vcName, PtmeIF& ptme, const std::atomic_bool& linkStateProvider, StorageManagerIF& tmStore, uint32_t tmQueueDepth) : VirtualChannel(objectId, vcId, vcName, ptme, linkStateProvider), tmStore(tmStore) { auto mqArgs = MqArgs(getObjectId(), reinterpret_cast(getVcid())); tmQueue = QueueFactory::instance()->createMessageQueue( tmQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs); } const char* VirtualChannelWithQueue::getName() const { return VirtualChannel::getName(); } ReturnValue_t VirtualChannelWithQueue::handleNextTm(bool performWriteOp) { TmTcMessage message; ReturnValue_t result = tmQueue->receiveMessage(&message); if (result == MessageQueueIF::EMPTY) { return result; } store_address_t storeId = message.getStorageId(); const uint8_t* data = nullptr; size_t size = 0; result = tmStore.getData(storeId, &data, &size); if (result != returnvalue::OK) { sif::warning << "VirtualChannel::performOperation: Failed to read data from TM store" << std::endl; tmStore.deleteData(storeId); return result; } // TODO: Hnadle partial write handling size_t partiallyWrittenSize = 0; if (performWriteOp) { 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. tmStore.deleteData(storeId); return result; } MessageQueueId_t VirtualChannelWithQueue::getReportReceptionQueue(uint8_t virtualChannel) const { return tmQueue->getId(); }