#include "TmStoreTaskBase.h" #include #include #include #include #include "mission/persistentTmStoreDefs.h" TmStoreTaskBase::TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore, VirtualChannel& channel, SdCardMountedIF& sdcMan) : SystemObject(objectId), ipcStore(ipcStore), channel(channel), sdcMan(sdcMan) {} bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store, DumpContext& dumpContext) { ReturnValue_t result; bool tmToStoreReceived = false; bool tcRequestReceived = false; bool dumpsPerformed = false; fileHasSwapped = false; // Store TM persistently result = store.handleNextTm(); if (result == returnvalue::OK) { tmToStoreReceived = true; } dumpContext.vcBusyDuringDump = false; // Dump TMs when applicable if (store.getState() == PersistentTmStore::State::DUMPING) { size_t dumpedLen = 0; if (not channel.isBusy()) { dumpContext.ptmeBusyCounter = 0; tmSinkBusyCd.resetTimer(); bool fileHasSwappedLocal = false; result = store.dumpNextPacket(channel, dumpedLen, fileHasSwappedLocal); if (result == DirectTmSinkIF::IS_BUSY) { sif::warning << "Unexpected PAPB busy" << std::endl; } if ((result == PersistentTmStore::DUMP_DONE or result == returnvalue::OK) and dumpedLen > 0) { dumpContext.dumpedBytes += dumpedLen; dumpContext.numberOfDumpedPackets += 1; dumpContext.packetWasDumped = true; // Only register file swaps if more than 0 bytes were dumped. if(fileHasSwappedLocal) { fileHasSwapped = true; } } if (result == PersistentTmStore::DUMP_DONE) { uint32_t startTime; uint32_t endTime; store.getStartAndEndTimeCurrentOrLastDump(startTime, endTime); triggerEvent(dumpContext.eventIfDone, dumpContext.numberOfDumpedPackets, dumpContext.dumpedBytes); dumpsPerformed = true; } else if (result == returnvalue::OK) { dumpsPerformed = true; } } else { dumpContext.vcBusyDuringDump = true; dumpContext.ptmeBusyCounter++; if (dumpContext.ptmeBusyCounter == 50) { // If this happens, something is probably wrong. sif::warning << "PTME busy for longer period. Dumped length so far: " << dumpContext.dumpedBytes << std::endl; dumpContext.ptmeBusyCounter = 0; triggerEvent(persTmStore::DUMP_WAS_CANCELLED, store.getObjectId()); store.cancelDump(); channel.cancelTransfer(); } } if (cancelDumpCd.hasTimedOut() or tmSinkBusyCd.hasTimedOut()) { triggerEvent(persTmStore::DUMP_WAS_CANCELLED, store.getObjectId()); store.cancelDump(); } } else { Command_t execCmd; // Handle TC requests, for example deletion or retrieval requests. result = store.handleCommandQueue(ipcStore, execCmd); if (result == returnvalue::OK) { if (execCmd == TmStoreMessage::DOWNLINK_STORE_CONTENT_TIME) { cancelDumpCd.resetTimer(); tmSinkBusyCd.resetTimer(); dumpContext.reset(); } tcRequestReceived = true; } } if (tcRequestReceived or tmToStoreReceived or dumpsPerformed) { return true; } return false; } bool TmStoreTaskBase::cyclicStoreCheck() { if (not storesInitialized) { storesInitialized = initStoresIfPossible(); if (not storesInitialized) { TaskFactory::delayTask(400); return false; } } else if (sdCardCheckCd.hasTimedOut()) { if (not sdcMan.isSdCardUsable(std::nullopt)) { // Might be due to imminent shutdown or SD card switch. storesInitialized = false; TaskFactory::delayTask(100); return false; } sdCardCheckCd.resetTimer(); } return true; }