diff --git a/linux/devices/devicedefinitions/PlocSupervisorDefinitions.h b/linux/devices/devicedefinitions/PlocSupervisorDefinitions.h index 2b248404..dfc7acce 100644 --- a/linux/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/linux/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -56,18 +56,19 @@ static const ReturnValue_t PATH_DOES_NOT_EXIST = MAKE_RETURN_CODE(0xAD); //! [EXPORT] : [COMMENT] MRAM dump file does not exists. The file should actually already have //! been created with the reception of the first dump packet. static const ReturnValue_t MRAM_FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xAE); +static constexpr ReturnValue_t INVALID_REPLY_LENGTH = MAKE_RETURN_CODE(0xAF); //! [EXPORT] : [COMMENT] Received action command has invalid length -static const ReturnValue_t INVALID_LENGTH = MAKE_RETURN_CODE(0xAF); +static const ReturnValue_t INVALID_LENGTH = MAKE_RETURN_CODE(0xB0); //! [EXPORT] : [COMMENT] Filename too long -static const ReturnValue_t FILENAME_TOO_LONG = MAKE_RETURN_CODE(0xB0); +static const ReturnValue_t FILENAME_TOO_LONG = MAKE_RETURN_CODE(0xB1); //! [EXPORT] : [COMMENT] Received update status report with invalid packet length field -static const ReturnValue_t UPDATE_STATUS_REPORT_INVALID_LENGTH = MAKE_RETURN_CODE(0xB1); +static const ReturnValue_t UPDATE_STATUS_REPORT_INVALID_LENGTH = MAKE_RETURN_CODE(0xB2); //! [EXPORT] : [COMMENT] Update status report does not contain expected CRC. There might be a bit //! flip in the update memory region. -static const ReturnValue_t UPDATE_CRC_FAILURE = MAKE_RETURN_CODE(0xB2); +static const ReturnValue_t UPDATE_CRC_FAILURE = MAKE_RETURN_CODE(0xB3); //! [EXPORT] : [COMMENT] Supervisor helper task ist currently executing a command (wait until //! helper tas has finished or interrupt by sending the terminate command) -static const ReturnValue_t SUPV_HELPER_EXECUTING = MAKE_RETURN_CODE(0xB3); +static const ReturnValue_t SUPV_HELPER_EXECUTING = MAKE_RETURN_CODE(0xB4); static constexpr ReturnValue_t BUF_TOO_SMALL = MAKE_RETURN_CODE(0xC0); static constexpr ReturnValue_t NO_REPLY_TIMEOUT = MAKE_RETURN_CODE(0xC1); @@ -470,6 +471,12 @@ class TmBase : public ploc::SpTmReader { uint8_t getServiceId() const { return getPacketData()[TIMESTAMP_LEN]; } const uint8_t* getPayloadStart() const { return getPacketData() + SECONDARY_HEADER_LEN; } + size_t getPayloadLen() const { + if (getFullPacketLen() > SECONDARY_HEADER_LEN + ccsds::HEADER_LEN) { + return getFullPacketLen() - SECONDARY_HEADER_LEN - ccsds::HEADER_LEN; + } + return 0; + } private: bool crcOk = false; @@ -1110,7 +1117,8 @@ class VerificationReport { if (readerBase.getApid() != Apid::TMTC_MAN) { return result::INVALID_APID; } - if (readerBase.getBufSize() < MIN_PAYLOAD_LEN + 8) { + if (readerBase.getBufSize() < MIN_TMTC_LEN + PAYLOAD_LEN or + readerBase.getPayloadLen() < PAYLOAD_LEN) { sif::error << "VerificationReport: Invalid verification report, payload too small" << std::endl; return result::BUF_TOO_SMALL; @@ -1507,6 +1515,59 @@ class ExecutionReport : public VerificationReport { }; }; +class UpdateStatusReport { + public: + UpdateStatusReport(TmBase& tmReader) : tmReader(tmReader) {} + + ReturnValue_t parse() { + if (not tmReader.crcIsOk()) { + return result::CRC_FAILURE; + } + if (tmReader.getApid() != Apid::MEM_MAN) { + return result::INVALID_APID; + } + if (tmReader.getBufSize() < MIN_TMTC_LEN + PAYLOAD_LEN or + tmReader.getPayloadLen() < PAYLOAD_LEN) { + sif::error << "VerificationReport: Invalid verification report, payload too small" + << std::endl; + return result::BUF_TOO_SMALL; + } + size_t remLen = PAYLOAD_LEN; + if (remLen < PAYLOAD_LEN) { + return result::INVALID_REPLY_LENGTH; + } + const uint8_t* dataFieldPtr = tmReader.getPayloadStart(); + SerializeAdapter::deSerialize(&memoryId, &dataFieldPtr, &remLen, SerializeIF::Endianness::BIG); + SerializeAdapter::deSerialize(&n, &dataFieldPtr, &remLen, SerializeIF::Endianness::BIG); + SerializeAdapter::deSerialize(&startAddress, &dataFieldPtr, &remLen, + SerializeIF::Endianness::BIG); + SerializeAdapter::deSerialize(&length, &dataFieldPtr, &remLen, SerializeIF::Endianness::BIG); + SerializeAdapter::deSerialize(&crc, &dataFieldPtr, &remLen, SerializeIF::Endianness::BIG); + return returnvalue::OK; + } + + ReturnValue_t verifyCrc(uint16_t goodCrc) const { + if (crc != goodCrc) { + return result::UPDATE_CRC_FAILURE; + } + return returnvalue::OK; + } + + uint16_t getCrc() const { return crc; } + + private: + TmBase& tmReader; + + // Nominal size of the space packet + static const uint16_t PAYLOAD_LEN = 12; // header, data field and crc + + uint8_t memoryId = 0; + uint8_t n = 0; + uint32_t startAddress = 0; + uint32_t length = 0; + uint16_t crc = 0; +}; + /** * @brief This dataset stores the boot status report of the supervisor. */ @@ -1661,56 +1722,6 @@ class LoggingReport : public StaticLocalDataSet { } }; -class UpdateStatusReport : public ploc::SpTmReader { - public: - UpdateStatusReport() = default; - UpdateStatusReport(const uint8_t* buf, size_t maxSize) : ploc::SpTmReader(buf, maxSize) {} - - ReturnValue_t parseDataField() { - ReturnValue_t result = lengthCheck(); - if (result != returnvalue::OK) { - return result; - } - const uint8_t* dataFieldPtr = getFullData() + ccsds::HEADER_LEN; - size_t size = 12; - SerializeAdapter::deSerialize(&memoryId, &dataFieldPtr, &size, SerializeIF::Endianness::BIG); - SerializeAdapter::deSerialize(&n, &dataFieldPtr, &size, SerializeIF::Endianness::BIG); - SerializeAdapter::deSerialize(&startAddress, &dataFieldPtr, &size, - SerializeIF::Endianness::BIG); - SerializeAdapter::deSerialize(&length, &dataFieldPtr, &size, SerializeIF::Endianness::BIG); - SerializeAdapter::deSerialize(&crc, &dataFieldPtr, &size, SerializeIF::Endianness::BIG); - return returnvalue::OK; - } - - ReturnValue_t verifycrc(uint16_t goodCrc) const { - if (crc != goodCrc) { - return result::UPDATE_CRC_FAILURE; - } - return returnvalue::OK; - } - - uint16_t getCrc() const { return crc; } - - uint16_t getNominalSize() const { return FULL_SIZE; } - - private: - // Nominal size of the space packet - static const uint16_t FULL_SIZE = 20; // header, data field and crc - - uint8_t memoryId = 0; - uint8_t n = 0; - uint32_t startAddress = 0; - uint32_t length = 0; - uint16_t crc = 0; - - ReturnValue_t lengthCheck() { - if (getFullPacketLen() != FULL_SIZE) { - return result::UPDATE_STATUS_REPORT_INVALID_LENGTH; - } - return returnvalue::OK; - } -}; - /** * @brief This dataset stores the ADC report. */ diff --git a/linux/devices/ploc/PlocSupervisorHandler.cpp b/linux/devices/ploc/PlocSupervisorHandler.cpp index f0e56347..3e31437b 100644 --- a/linux/devices/ploc/PlocSupervisorHandler.cpp +++ b/linux/devices/ploc/PlocSupervisorHandler.cpp @@ -60,11 +60,6 @@ ReturnValue_t PlocSupervisorHandler::initialize() { sif::warning << "PlocSupervisorHandler::initialize: Invalid supervisor helper" << std::endl; return ObjectManagerIF::CHILD_INIT_FAILED; } - // result = supvHelper->setComIF(uartComIf); - // if (result != returnvalue::OK) { - // return ObjectManagerIF::CHILD_INIT_FAILED; - // } - // supvHelper->setComCookie(comCookie); result = eventSubscription(); if (result != returnvalue::OK) { @@ -928,25 +923,22 @@ ReturnValue_t PlocSupervisorHandler::handleAckReport(const uint8_t* data) { using namespace supv; ReturnValue_t result = returnvalue::OK; + tmReader.setData(data, SIZE_ACK_REPORT); + if(tmReader.checkCrc() != returnvalue::OK) { + sif::error << "PlocSupervisorHandler::handleAckReport: CRC failure" << std::endl; + nextReplyId = supv::NONE; + replyRawReplyIfnotWiretapped(data, supv::SIZE_ACK_REPORT); + triggerEvent(SUPV_CRC_FAILURE_EVENT); + sendFailureReport(supv::ACK_REPORT, result::CRC_FAILURE); + disableAllReplies(); + return returnvalue::OK; + } + AcknowledgmentReport ack(tmReader); + result = ack.parse(); + if (result != returnvalue::OK) { + return result; + } // TODO: Fix - - // AcknowledgmentReport ack(data, SIZE_ACK_REPORT); - // result = ack.checkSize(); - // if (result != returnvalue::OK) { - // return result; - // } - // - // result = ack.checkCrc(); - // if (result != returnvalue::OK) { - // sif::error << "PlocSupervisorHandler::handleAckReport: CRC failure" << std::endl; - // nextReplyId = supv::NONE; - // replyRawReplyIfnotWiretapped(data, supv::SIZE_ACK_REPORT); - // triggerEvent(SUPV_CRC_FAILURE_EVENT); - // sendFailureReport(supv::ACK_REPORT, SupvReturnValuesIF::CRC_FAILURE); - // disableAllReplies(); - // return returnvalue::OK; - // } - // // result = ack.checkApid(); // // switch (result) { diff --git a/linux/devices/ploc/PlocSupvUartMan.cpp b/linux/devices/ploc/PlocSupvUartMan.cpp index ef571c11..622acc89 100644 --- a/linux/devices/ploc/PlocSupvUartMan.cpp +++ b/linux/devices/ploc/PlocSupvUartMan.cpp @@ -159,17 +159,6 @@ bool PlocSupvHelper::handleUartReception() { return false; } -// ReturnValue_t PlocSupvHelper::setComIF(UartComIF* uartComIF_) { -// if (uartComIF_ == nullptr) { -// sif::warning << "PlocSupvHelper::initialize: Provided invalid uart com if" << std::endl; -// return returnvalue::FAILED; -// } -// //uartComIF = uartComIF_; -// return returnvalue::OK; -// } - -// void PlocSupvHelper::setComCookie(CookieIF* comCookie_) { comCookie = comCookie_; } - ReturnValue_t PlocSupvHelper::startUpdate(std::string file, uint8_t memoryId, uint32_t startAddress) { supv::UpdateParams params; @@ -432,8 +421,7 @@ ReturnValue_t PlocSupvHelper::writeUpdatePackets() { update.bytesWritten); return result; } - // TODO: Fix - // result = handlePacketTransmission(packet); + result = encodeAndSendPacket(packet.getFullPacket(), packet.getFullPacketLen()); if (result != returnvalue::OK) { triggerEvent(WRITE_MEMORY_FAILED, buildProgParams1(progPercent, update.sequenceCount), update.bytesWritten); @@ -728,12 +716,7 @@ ReturnValue_t PlocSupvHelper::calcImageCrc() { ReturnValue_t PlocSupvHelper::handleCheckMemoryCommand() { ReturnValue_t result = returnvalue::OK; - // TODO: Fix resetSpParams(); - // Will hold status report for later processing - // std::array statusReportBuf{}; - // supv::UpdateStatusReport updateStatusReport(tmBuf.data(), tmBuf.size()); - // Verification of update write procedure supv::CheckMemory packet(spParams); result = packet.buildPacket(update.memoryId, update.startAddress, update.fullFileSize); if (result != returnvalue::OK) { @@ -766,8 +749,7 @@ ReturnValue_t PlocSupvHelper::handleCheckMemoryCommand() { } else if (retval == -1) { return returnvalue::FAILED; } - } else if (not checkReplyReceived) { - // if (serviceId == ) + } else if (checkReplyReceived) { retval = handleExeAckReception(packet, serviceId, packetLen); if (retval == 1) { break; @@ -775,6 +757,26 @@ ReturnValue_t PlocSupvHelper::handleCheckMemoryCommand() { return returnvalue::FAILED; } } + } else if (tmReader.getApid() == Apid::MEM_MAN) { + if (ackReceived) { + supv::UpdateStatusReport report(tmReader); + result = report.parse(); + if (result != returnvalue::OK) { + return result; + } + if (update.crcShouldBeChecked) { + result = report.verifyCrc(update.crc); + if (result != returnvalue::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) + << report.getCrc() << std::dec << std::endl; + return result; + } + } + checkReplyReceived = true; + } } else { pushIpcData(decodedBuf.data(), packetLen); decodedRingBuf.deleteData(packetLen); diff --git a/linux/devices/ploc/PlocSupvUartMan.h b/linux/devices/ploc/PlocSupvUartMan.h index 34d8bd2e..f8f175d5 100644 --- a/linux/devices/ploc/PlocSupvUartMan.h +++ b/linux/devices/ploc/PlocSupvUartMan.h @@ -277,17 +277,6 @@ class PlocSupvHelper : public DeviceCommunicationIF, int handleAckReception(supv::TcBase& tc, uint8_t serviceId, size_t packetLen); int handleExeAckReception(supv::TcBase& tc, uint8_t serviceId, size_t packetLen); - // ReturnValue_t sendCommand(ploc::SpTcBase& packet); - /** - * @brief Function which reads form the communication interface - * - * @param data Pointer to buffer where read data will be written to - * @param raedBytes Actual number of bytes read - * @param requestBytes Number of bytes to read - */ - // ReturnValue_t receive(uint8_t* data, size_t* readBytes, size_t requestBytes); - ReturnValue_t handleAck(); - ReturnValue_t handleExe(uint32_t timeout = 1000); /** * @brief Handles reading of TM packets from the communication interface *