diff --git a/linux/devices/devicedefinitions/PlocSupervisorDefinitions.h b/linux/devices/devicedefinitions/PlocSupervisorDefinitions.h index 9c371305..d36e4c0c 100644 --- a/linux/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/linux/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -60,7 +60,7 @@ static const DeviceCommandId_t REQUEST_ADC_REPORT = 57; static const DeviceCommandId_t RESET_PL = 58; static const DeviceCommandId_t ENABLE_NVMS = 59; static const DeviceCommandId_t CONTINUE_UPDATE = 60; -static const DeviceCommandId_t MEMORY_CHECK = 61; +static const DeviceCommandId_t MEMORY_CHECK_WITH_FILE = 61; /** Reply IDs */ static const DeviceCommandId_t ACK_REPORT = 100; diff --git a/linux/devices/ploc/PlocSupervisorHandler.cpp b/linux/devices/ploc/PlocSupervisorHandler.cpp index 7bc78f61..1e2a20f3 100644 --- a/linux/devices/ploc/PlocSupervisorHandler.cpp +++ b/linux/devices/ploc/PlocSupervisorHandler.cpp @@ -1,5 +1,7 @@ #include "PlocSupervisorHandler.h" +#include + #include #include #include @@ -132,27 +134,16 @@ ReturnValue_t PlocSupervisorHandler::executeAction(ActionId_t actionId, plocSupvHelperExecuting = true; return EXECUTION_FINISHED; } - case MEMORY_CHECK: { - size_t deserLen = 9; - uint8_t memId; - uint32_t startAddr; - uint32_t sizeToCheck; - result = - SerializeAdapter::deSerialize(&memId, &data, &deserLen, SerializeIF::Endianness::NETWORK); + case MEMORY_CHECK_WITH_FILE: { + UpdateParams params; + ReturnValue_t result = extractBaseParams(&data, size, params); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::deSerialize(&startAddr, &data, &deserLen, - SerializeIF::Endianness::NETWORK); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; + if (not std::filesystem::exists(params.file)) { + return HasFileSystemIF::FILE_DOES_NOT_EXIST; } - result = SerializeAdapter::deSerialize(&sizeToCheck, &data, &deserLen, - SerializeIF::Endianness::NETWORK); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - supvHelper->performMemCheck(memId, startAddr, sizeToCheck); + supvHelper->performMemCheck(params.file, params.memId, params.startAddr); plocSupvHelperExecuting = true; return EXECUTION_FINISHED; } @@ -886,7 +877,9 @@ void PlocSupervisorHandler::handleEvent(EventMessage* eventMessage) { if (event == PlocSupvHelper::SUPV_UPDATE_FAILED || event == PlocSupvHelper::SUPV_UPDATE_SUCCESSFUL || event == PlocSupvHelper::SUPV_CONTINUE_UPDATE_FAILED || - event == PlocSupvHelper::SUPV_CONTINUE_UPDATE_SUCCESSFUL) { + event == PlocSupvHelper::SUPV_CONTINUE_UPDATE_SUCCESSFUL || + event == PlocSupvHelper::SUPV_MEM_CHECK_FAIL || + event == PlocSupvHelper::SUPV_MEM_CHECK_OK) { result = this->executeAction(supv::SHUTDOWN_MPSOC, NO_COMMANDER, nullptr, 0); if (result != RETURN_OK) { triggerEvent(SUPV_MPSOC_SHUWDOWN_BUILD_FAILED); @@ -1998,30 +1991,15 @@ ReturnValue_t PlocSupervisorHandler::getTimeStampString(std::string& timeStamp) ReturnValue_t PlocSupervisorHandler::extractUpdateCommand(const uint8_t* commandData, size_t size, UpdateParams& params) { - ReturnValue_t result = RETURN_OK; + size_t remSize = size; if (size > (config::MAX_FILENAME_SIZE + config::MAX_PATH_SIZE + sizeof(params.memId)) + - sizeof(params.startAddr)) { + sizeof(params.startAddr) + sizeof(params.bytesWritten) + sizeof(params.seqCount)) { sif::warning << "PlocSupervisorHandler::extractUpdateCommand: Data size too big" << std::endl; return SupvReturnValuesIF::INVALID_LENGTH; } - params.file = std::string(reinterpret_cast(commandData)); - if (params.file.size() > (config::MAX_FILENAME_SIZE + config::MAX_PATH_SIZE)) { - sif::warning << "PlocSupervisorHandler::extractUpdateCommand: Filename too long" << std::endl; - return SupvReturnValuesIF::FILENAME_TOO_LONG; - } - params.memId = *(commandData + params.file.size() + SIZE_NULL_TERMINATOR); - const uint8_t* startAddressPtr = - commandData + params.file.size() + SIZE_NULL_TERMINATOR + sizeof(params.memId); - size_t remainingSize = 10; - result = SerializeAdapter::deSerialize(¶ms.startAddr, &startAddressPtr, &remainingSize, - SerializeIF::Endianness::BIG); - if (result != RETURN_OK) { - sif::warning - << "PlocSupervisorHandler::extractUpdateCommand: Failed to deserialize start address" - << std::endl; - return result; - } - result = SerializeAdapter::deSerialize(¶ms.bytesWritten, &startAddressPtr, &remainingSize, + ReturnValue_t result = RETURN_OK; + result = extractBaseParams(&commandData, size, params); + result = SerializeAdapter::deSerialize(¶ms.bytesWritten, &commandData, &remSize, SerializeIF::Endianness::BIG); if (result != RETURN_OK) { sif::warning << "PlocSupervisorHandler::extractUpdateCommand: Failed to deserialize bytes " @@ -2029,7 +2007,7 @@ ReturnValue_t PlocSupervisorHandler::extractUpdateCommand(const uint8_t* command << std::endl; return result; } - result = SerializeAdapter::deSerialize(¶ms.seqCount, &startAddressPtr, &remainingSize, + result = SerializeAdapter::deSerialize(¶ms.seqCount, &commandData, &remSize, SerializeIF::Endianness::BIG); if (result != RETURN_OK) { sif::warning @@ -2040,6 +2018,38 @@ ReturnValue_t PlocSupervisorHandler::extractUpdateCommand(const uint8_t* command return RETURN_OK; } +ReturnValue_t PlocSupervisorHandler::extractBaseParams(const uint8_t** commandData, size_t& remSize, + UpdateParams& params) { + bool nullTermFound = false; + for (size_t idx = 0; idx < remSize; idx++) { + if ((*commandData)[idx] == '\0') { + nullTermFound = true; + break; + } + } + if (not nullTermFound) { + return HasReturnvaluesIF::RETURN_FAILED; + } + params.file = std::string(reinterpret_cast(*commandData)); + if (params.file.size() > (config::MAX_FILENAME_SIZE + config::MAX_PATH_SIZE)) { + sif::warning << "PlocSupervisorHandler::extractUpdateCommand: Filename too long" << std::endl; + return SupvReturnValuesIF::FILENAME_TOO_LONG; + } + *commandData += params.file.size() + SIZE_NULL_TERMINATOR; + remSize -= (params.file.size() + SIZE_NULL_TERMINATOR); + params.memId = **commandData; + *commandData += 1; + remSize -= 1; + ReturnValue_t result = SerializeAdapter::deSerialize(¶ms.startAddr, commandData, &remSize, + SerializeIF::Endianness::BIG); + if (result != RETURN_OK) { + sif::warning << "PlocSupervisorHandler::extractBaseParams: Failed to deserialize start address" + << std::endl; + return result; + } + return result; +} + ReturnValue_t PlocSupervisorHandler::eventSubscription() { ReturnValue_t result = RETURN_OK; EventManagerIF* manager = ObjectManager::instance()->get(objects::EVENT_MANAGER); diff --git a/linux/devices/ploc/PlocSupervisorHandler.h b/linux/devices/ploc/PlocSupervisorHandler.h index 7f0b2574..e410340f 100644 --- a/linux/devices/ploc/PlocSupervisorHandler.h +++ b/linux/devices/ploc/PlocSupervisorHandler.h @@ -376,6 +376,8 @@ class PlocSupervisorHandler : public DeviceHandlerBase { }; ReturnValue_t extractUpdateCommand(const uint8_t* commandData, size_t size, UpdateParams& params); + ReturnValue_t extractBaseParams(const uint8_t** commandData, size_t& remSize, + UpdateParams& params); ReturnValue_t eventSubscription(); ReturnValue_t handleExecutionSuccessReport(const uint8_t* data); diff --git a/linux/devices/ploc/PlocSupvHelper.cpp b/linux/devices/ploc/PlocSupvHelper.cpp index b324b15b..36e3b392 100644 --- a/linux/devices/ploc/PlocSupvHelper.cpp +++ b/linux/devices/ploc/PlocSupvHelper.cpp @@ -58,9 +58,7 @@ ReturnValue_t PlocSupvHelper::performOperation(uint8_t operationCode) { break; } case InternalState::CHECK_MEMORY: { - sif::info << "PlocSupvHelper::performUpdate: Memory Check" << std::endl; - result = handleCheckMemoryCommand(); - triggerEvent(SUPV_MEM_CHECK_STATUS, result); + executeFullCheckMemoryCommand(); internalState = InternalState::IDLE; break; } @@ -150,11 +148,18 @@ ReturnValue_t PlocSupvHelper::performUpdate(std::string file, uint8_t memoryId, return result; } +ReturnValue_t PlocSupvHelper::performMemCheck(std::string file, uint8_t memoryId, + uint32_t startAddress) { + update.file = file; + return performMemCheck(memoryId, startAddress, getFileSize(update.file), true); +} + ReturnValue_t PlocSupvHelper::performMemCheck(uint8_t memoryId, uint32_t startAddress, - size_t sizeToCheck) { + size_t sizeToCheck, bool checkCrc) { update.memoryId = memoryId; update.startAddress = startAddress; update.length = sizeToCheck; + update.crcShouldBeChecked = checkCrc; internalState = InternalState::CHECK_MEMORY; uartComIF->flushUartTxAndRxBuf(comCookie); semaphore.release(); @@ -185,6 +190,37 @@ ReturnValue_t PlocSupvHelper::startEventbBufferRequest(std::string path) { void PlocSupvHelper::stopProcess() { terminate = true; } +void PlocSupvHelper::executeFullCheckMemoryCommand() { + ReturnValue_t result; + if (update.crcShouldBeChecked) { + sif::info << "PlocSupvHelper::performUpdate: Calculating Image CRC" << std::endl; + result = calcImageCrc(); + if (result != RETURN_OK) { + triggerEvent(SUPV_MEM_CHECK_FAIL, result); + return; + } + } + sif::info << "PlocSupvHelper::executeFullCheckMemoryCommand: Selecting Memory" << std::endl; + result = selectMemory(); + if (result != RETURN_OK) { + triggerEvent(SUPV_MEM_CHECK_FAIL, result); + return; + } + sif::info << "PlocSupvHelper::executeFullCheckMemoryCommand: Preparing Update" << std::endl; + result = prepareUpdate(); + if (result != RETURN_OK) { + triggerEvent(SUPV_MEM_CHECK_FAIL, result); + return; + } + sif::info << "PlocSupvHelper::executeFullCheckMemoryCommand: Memory Check" << std::endl; + result = handleCheckMemoryCommand(); + if (result == HasReturnvaluesIF::RETURN_OK) { + triggerEvent(SUPV_MEM_CHECK_OK, result); + } else { + triggerEvent(SUPV_MEM_CHECK_FAIL, result); + } +} + ReturnValue_t PlocSupvHelper::performUpdate() { ReturnValue_t result = RETURN_OK; sif::info << "PlocSupvHelper::performUpdate: Calculating Image CRC" << std::endl; @@ -471,7 +507,7 @@ ReturnValue_t PlocSupvHelper::exeReportHandling() { } return result; } - return exeReportHandling(); + return result; } ReturnValue_t PlocSupvHelper::handleTmReception(size_t remainingBytes, uint8_t* readBuf, @@ -542,15 +578,19 @@ ReturnValue_t PlocSupvHelper::receive(uint8_t* data, size_t* readBytes, size_t r ReturnValue_t PlocSupvHelper::calcImageCrc() { ReturnValue_t result = RETURN_OK; + if (update.length == 0) { + return HasReturnvaluesIF::RETURN_FAILED; + } #ifdef XIPHOS_Q7S result = FilesystemHelper::checkPath(update.file); -#endif - auto crc16Calcer = etl::crc16_ccitt(); if (result != RETURN_OK) { sif::warning << "PlocSupvHelper::calcImageCrc: File " << update.file << " does not exist" << std::endl; return result; } +#endif + + auto crc16Calcer = etl::crc16_ccitt(); std::ifstream file(update.file, std::ifstream::binary); std::array crcBuf; #if OBSW_DEBUG_PLOC_SUPERVISOR == 1 @@ -586,7 +626,7 @@ ReturnValue_t PlocSupvHelper::handleCheckMemoryCommand() { resetSpParams(); // Will hold status report for later processing std::array statusReportBuf{}; - supv::UpdateStatusReport updateStatusReport(statusReportBuf.data(), statusReportBuf.size()); + supv::UpdateStatusReport updateStatusReport(tmBuf.data(), tmBuf.size()); // Verification of update write procedure supv::CheckMemory packet(spParams); result = packet.buildPacket(update.memoryId, update.startAddress, update.length); @@ -611,7 +651,10 @@ ReturnValue_t PlocSupvHelper::handleCheckMemoryCommand() { if (result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "Reading exe failure report failed" << std::endl; } - return exeReportHandling(); + result = exeReportHandling(); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Handling exe report failed" << std::endl; + } } else if (spReader.getApid() == supv::APID_UPDATE_STATUS_REPORT) { size_t remBytes = spReader.getPacketDataLen() + 1; result = handleTmReception(remBytes, tmBuf.data() + ccsds::HEADER_LEN); @@ -623,9 +666,11 @@ ReturnValue_t PlocSupvHelper::handleCheckMemoryCommand() { } result = updateStatusReport.checkCrc(); if (result != RETURN_OK) { - sif::warning << "PlocSupvHelper::handleTmReception: CRC check failed" << std::endl; + sif::warning << "PlocSupvHelper::handleCheckMemoryCommand: CRC check failed" << std::endl; return result; } + // Copy into other buffer because data will be overwritten when reading execution report + std::memcpy(statusReportBuf.data(), tmBuf.data(), updateStatusReport.getNominalSize()); } result = handleExe(CRC_EXECUTION_TIMEOUT); @@ -634,16 +679,20 @@ ReturnValue_t PlocSupvHelper::handleCheckMemoryCommand() { } // Now process the status report + updateStatusReport.setData(statusReportBuf.data(), statusReportBuf.size()); result = updateStatusReport.parseDataField(); if (result != RETURN_OK) { return result; } - result = updateStatusReport.verifycrc(update.crc); - if (result != RETURN_OK) { - sif::warning << "PlocSupvHelper::handleCheckMemoryCommand: CRC failure. Expected CRC 0x" - << std::hex << update.crc << " but received CRC 0x" << updateStatusReport.getCrc() - << std::endl; - return result; + if (update.crcShouldBeChecked) { + result = updateStatusReport.verifycrc(update.crc); + if (result != RETURN_OK) { + sif::warning << "PlocSupvHelper::handleCheckMemoryCommand: CRC failure. Expected CRC 0x" + << std::setfill('0') << std::hex << std::setw(4) + << static_cast(update.crc) << " but received CRC 0x" << std::setw(4) + << updateStatusReport.getCrc() << std::dec << std::endl; + return result; + } } return result; } diff --git a/linux/devices/ploc/PlocSupvHelper.h b/linux/devices/ploc/PlocSupvHelper.h index 81cbfd1d..6be2ff68 100644 --- a/linux/devices/ploc/PlocSupvHelper.h +++ b/linux/devices/ploc/PlocSupvHelper.h @@ -94,7 +94,8 @@ class PlocSupvHelper : public SystemObject, public ExecutableObjectIF, public Ha static constexpr Event SUPV_UPDATE_PROGRESS = MAKE_EVENT(22, severity::INFO); //! Status of memory check command //! P1: Returncode, 0 for success, other value with returncode for failure - static constexpr Event SUPV_MEM_CHECK_STATUS = MAKE_EVENT(23, severity::INFO); + static constexpr Event SUPV_MEM_CHECK_OK = MAKE_EVENT(23, severity::INFO); + static constexpr Event SUPV_MEM_CHECK_FAIL = MAKE_EVENT(24, severity::INFO); PlocSupvHelper(object_id_t objectId); virtual ~PlocSupvHelper(); @@ -118,7 +119,10 @@ class PlocSupvHelper : public SystemObject, public ExecutableObjectIF, public Ha size_t startBytesWritten, uint16_t initSeqCount); ReturnValue_t startUpdate(std::string file, uint8_t memoryId, uint32_t startAddress); - ReturnValue_t performMemCheck(uint8_t memoryId, uint32_t startAddress, size_t sizeToCheck); + ReturnValue_t performMemCheck(uint8_t memoryId, uint32_t startAddress, size_t sizeToCheck, + bool checkCrc); + ReturnValue_t performMemCheck(std::string file, uint8_t memoryId, uint32_t startAddress); + /** * @brief This initiate the continuation of a failed update. */ @@ -165,6 +169,7 @@ class PlocSupvHelper : public SystemObject, public ExecutableObjectIF, public Ha // Size of update uint32_t length; uint32_t crc; + bool crcShouldBeChecked = false; // size_t remainingSize; size_t bytesWritten; uint32_t packetNum; @@ -211,6 +216,8 @@ class PlocSupvHelper : public SystemObject, public ExecutableObjectIF, public Ha // Remembers APID to know at which command a procedure failed uint16_t rememberApid = 0; + void executeFullCheckMemoryCommand(); + ReturnValue_t performUpdate(); ReturnValue_t continueUpdate(); ReturnValue_t updateOperation(); diff --git a/tmtc b/tmtc index 425870d1..56514759 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 425870d16150f5b99e8e450ac892104e557aff20 +Subproject commit 56514759551204c20687c393f463e74204b821f2