From 28cd78db96ba6999d4b1376bb35fe2336d851073 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 8 Nov 2022 16:26:30 +0100 Subject: [PATCH] implemented the last tricky parts --- .../PlocSupervisorDefinitions.h | 151 ++++---- linux/devices/ploc/PlocSupervisorHandler.cpp | 10 +- linux/devices/ploc/PlocSupvUartMan.cpp | 364 ++++++++++-------- linux/devices/ploc/PlocSupvUartMan.h | 34 +- mission/devices/devicedefinitions/SpBase.h | 2 + 5 files changed, 297 insertions(+), 264 deletions(-) diff --git a/linux/devices/devicedefinitions/PlocSupervisorDefinitions.h b/linux/devices/devicedefinitions/PlocSupervisorDefinitions.h index 34ac413e..2b248404 100644 --- a/linux/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/linux/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -70,6 +70,8 @@ static const ReturnValue_t UPDATE_CRC_FAILURE = MAKE_RETURN_CODE(0xB2); static const ReturnValue_t SUPV_HELPER_EXECUTING = MAKE_RETURN_CODE(0xB3); static constexpr ReturnValue_t BUF_TOO_SMALL = MAKE_RETURN_CODE(0xC0); +static constexpr ReturnValue_t NO_REPLY_TIMEOUT = MAKE_RETURN_CODE(0xC1); + }; // namespace result static constexpr uint16_t DEFAULT_SEQ_COUNT = 0; @@ -270,6 +272,7 @@ namespace timeout { // Erase memory can require up to 60 seconds for execution static const uint32_t ERASE_MEMORY = 60000; static const uint32_t UPDATE_STATUS_REPORT = 70000; +static const uint32_t CRC_EXECUTION_TIMEOUT = 60000; } // namespace timeout static constexpr size_t TIMESTAMP_LEN = 7; @@ -421,6 +424,8 @@ class TcBase : public ploc::SpTcBase { payloadStart[supv::PAYLOAD_OFFSET] = id; } + uint8_t getServiceId() const { return payloadStart[supv::PAYLOAD_OFFSET]; } + static size_t fullSpDataLenFromPayloadLen(size_t payloadLen) { return SECONDARY_HEADER_LEN + payloadLen + CRC_LEN; } @@ -1168,19 +1173,11 @@ class AcknowledgmentReport : public VerificationReport { AcknowledgmentReport(TmBase& readerBase) : VerificationReport(readerBase) {} virtual ReturnValue_t parse() override { - // if (readerBase.getServiceId() != ) - // uint16_t apid = this->getApid(); - // if (apid == APID_ACK_SUCCESS) { - // return returnvalue::OK; - // } else if (apid == APID_ACK_FAILURE) { - // printStatusInformation(); - // return SupvReturnValuesIF::RECEIVED_ACK_FAILURE; - // } else { - // sif::warning << "AcknowledgmentReport::checkApid: Invalid apid: 0x" << std::hex << apid - // << std::endl; - // return SupvReturnValuesIF::INVALID_APID; - // } - return OK; + if (readerBase.getServiceId() != static_cast(tm::TmtcId::ACK) and + readerBase.getServiceId() != static_cast(tm::TmtcId::NAK)) { + return returnvalue::FAILED; + } + return VerificationReport::parse(); } void printStatusInformation() { @@ -1244,78 +1241,12 @@ class ExecutionReport : public VerificationReport { ExecutionReport(TmBase& readerBase) : VerificationReport(readerBase) {} ReturnValue_t parse() override { - if (readerBase.getServiceId() == static_cast(tm::TmtcId::EXEC_NAK)) { - printStatusInformation(); - return result::RECEIVED_EXE_FAILURE; + if (readerBase.getServiceId() != static_cast(tm::TmtcId::EXEC_ACK) and + readerBase.getServiceId() != static_cast(tm::TmtcId::EXEC_NAK)) { + return returnvalue::FAILED; } - /* uint16_t apid = this->getApid(); - if (apid == APID_EXE_SUCCESS) { - return returnvalue::OK; - } else if (apid == APID_EXE_FAILURE) { - printStatusInformation(); - return SupvReturnValuesIF::RECEIVED_EXE_FAILURE; - } else { - sif::warning << "ExecutionReport::checkApid: Invalid apid: 0x" << std::hex << apid - << std::endl; - return SupvReturnValuesIF::INVALID_APID; - }*/ - return OK; + return VerificationReport::parse(); } - - private: - static constexpr char STATUS_PRINTOUT_PREFIX[] = "Supervisor execution failure report status: "; - - enum class StatusCode : uint16_t { - OK = 0x0, - INIT_ERROR = 0x1, - BAD_PARAM = 0x2, - NOT_INITIALIZED = 0x3, - BAD_PERIPH_ID = 0x4, - TIMEOUT = 0x5, - RX_ERROR = 0x6, - TX_ERROR = 0x7, - BUF_EMPTY = 0x8, - BUF_FULL = 0x9, - NAK = 0xA, - ARB_LOST = 0xB, - BUSY = 0xC, - NOT_IMPLEMENTED = 0xD, - ALIGNEMENT_ERROR = 0xE, - PERIPH_ERR = 0xF, - FAILED_LATCH = 0x10, - GPIO_HIGH = 0x11, - GPIO_LOW = 0x12, - TEST_PASSED = 0x13, - TEST_FAILED = 0x14, - NOTHING_TODO = 0x100, - POWER_FAULT = 0x101, - INVALID_LENGTH = 0x102, - OUT_OF_RANGE = 0x103, - OUT_OF_HEAP_MEMORY = 0x104, - INVALID_STATE_TRANSITION = 0x105, - MPSOC_ALREADY_BOOTING = 0x106, - MPSOC_ALREADY_OPERATIONAL = 0x107, - MPSOC_BOOT_FAILED = 0x108, - SP_NOT_AVAILABLE = 0x200, - SP_DATA_INSUFFICIENT = 0x201, - SP_MEMORY_ID_INVALID = 0x202, - MPSOC_NOT_IN_RESET = 0x203, - FLASH_INIT_FAILED = 0x204, - FLASH_ERASE_FAILED = 0x205, - FLASH_WRITE_FAILED = 0x206, - FLASH_VERIFY_FAILED = 0x207, - CANNOT_ACCESS_TM = 0x208, - CANNOT_SEND_TM = 0x209, - PG_LOW = 0x300, - PG_5V_LOW = 0x301, - PG_0V85_LOW = 0x302, - PG_1V8_LOW = 0x303, - PG_MISC_LOW = 0x304, - PG_3V3_LOW = 0x305, - PG_MB_VAIO_LOW = 0x306, - PG_MB_MPSOCIO_LOW = 0x307 - }; - void printStatusInformation() { StatusCode statusCode = static_cast(getStatusCode()); switch (statusCode) { @@ -1520,6 +1451,60 @@ class ExecutionReport : public VerificationReport { break; } } + + private: + static constexpr char STATUS_PRINTOUT_PREFIX[] = "Supervisor execution failure report status: "; + + enum class StatusCode : uint16_t { + OK = 0x0, + INIT_ERROR = 0x1, + BAD_PARAM = 0x2, + NOT_INITIALIZED = 0x3, + BAD_PERIPH_ID = 0x4, + TIMEOUT = 0x5, + RX_ERROR = 0x6, + TX_ERROR = 0x7, + BUF_EMPTY = 0x8, + BUF_FULL = 0x9, + NAK = 0xA, + ARB_LOST = 0xB, + BUSY = 0xC, + NOT_IMPLEMENTED = 0xD, + ALIGNEMENT_ERROR = 0xE, + PERIPH_ERR = 0xF, + FAILED_LATCH = 0x10, + GPIO_HIGH = 0x11, + GPIO_LOW = 0x12, + TEST_PASSED = 0x13, + TEST_FAILED = 0x14, + NOTHING_TODO = 0x100, + POWER_FAULT = 0x101, + INVALID_LENGTH = 0x102, + OUT_OF_RANGE = 0x103, + OUT_OF_HEAP_MEMORY = 0x104, + INVALID_STATE_TRANSITION = 0x105, + MPSOC_ALREADY_BOOTING = 0x106, + MPSOC_ALREADY_OPERATIONAL = 0x107, + MPSOC_BOOT_FAILED = 0x108, + SP_NOT_AVAILABLE = 0x200, + SP_DATA_INSUFFICIENT = 0x201, + SP_MEMORY_ID_INVALID = 0x202, + MPSOC_NOT_IN_RESET = 0x203, + FLASH_INIT_FAILED = 0x204, + FLASH_ERASE_FAILED = 0x205, + FLASH_WRITE_FAILED = 0x206, + FLASH_VERIFY_FAILED = 0x207, + CANNOT_ACCESS_TM = 0x208, + CANNOT_SEND_TM = 0x209, + PG_LOW = 0x300, + PG_5V_LOW = 0x301, + PG_0V85_LOW = 0x302, + PG_1V8_LOW = 0x303, + PG_MISC_LOW = 0x304, + PG_3V3_LOW = 0x305, + PG_MB_VAIO_LOW = 0x306, + PG_MB_MPSOCIO_LOW = 0x307 + }; }; /** diff --git a/linux/devices/ploc/PlocSupervisorHandler.cpp b/linux/devices/ploc/PlocSupervisorHandler.cpp index f71cafe3..f0e56347 100644 --- a/linux/devices/ploc/PlocSupervisorHandler.cpp +++ b/linux/devices/ploc/PlocSupervisorHandler.cpp @@ -60,11 +60,11 @@ 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 = supvHelper->setComIF(uartComIf); + // if (result != returnvalue::OK) { + // return ObjectManagerIF::CHILD_INIT_FAILED; + // } + // supvHelper->setComCookie(comCookie); result = eventSubscription(); if (result != returnvalue::OK) { diff --git a/linux/devices/ploc/PlocSupvUartMan.cpp b/linux/devices/ploc/PlocSupvUartMan.cpp index c9e9ad72..ef571c11 100644 --- a/linux/devices/ploc/PlocSupvUartMan.cpp +++ b/linux/devices/ploc/PlocSupvUartMan.cpp @@ -29,12 +29,13 @@ using namespace supv; PlocSupvHelper::PlocSupvHelper(object_id_t objectId) : SystemObject(objectId), recRingBuf(4096, true), + decodedRingBuf(1200 * MAX_STORED_DECODED_PACKETS, true), ipcRingBuf(1200 * MAX_STORED_DECODED_PACKETS, true) { - spParams.maxSize = sizeof(commandBuffer); resetSpParams(); semaphore = SemaphoreFactory::instance()->createBinarySemaphore(); semaphore->acquire(); lock = MutexFactory::instance()->createMutex(); + ipcLock = MutexFactory::instance()->createMutex(); } PlocSupvHelper::~PlocSupvHelper() = default; @@ -158,14 +159,14 @@ 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; -} +// 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_; } @@ -431,7 +432,8 @@ ReturnValue_t PlocSupvHelper::writeUpdatePackets() { update.bytesWritten); return result; } - result = handlePacketTransmission(packet); + // TODO: Fix + // result = handlePacketTransmission(packet); if (result != returnvalue::OK) { triggerEvent(WRITE_MEMORY_FAILED, buildProgParams1(progPercent, update.sequenceCount), update.bytesWritten); @@ -514,7 +516,7 @@ ReturnValue_t PlocSupvHelper::selectMemory() { if (result != returnvalue::OK) { return result; } - result = handlePacketTransmission(packet); + result = handlePacketTransmissionNoReply(packet); if (result != returnvalue::OK) { return result; } @@ -530,7 +532,7 @@ ReturnValue_t PlocSupvHelper::prepareUpdate() { if (result != returnvalue::OK) { return result; } - result = handlePacketTransmission(packet, PREPARE_UPDATE_EXECUTION_REPORT); + result = handlePacketTransmissionNoReply(packet, PREPARE_UPDATE_EXECUTION_REPORT); if (result != returnvalue::OK) { return result; } @@ -546,140 +548,131 @@ ReturnValue_t PlocSupvHelper::eraseMemory() { if (result != returnvalue::OK) { return result; } - result = handlePacketTransmission(eraseMemory, supv::timeout::ERASE_MEMORY); + result = handlePacketTransmissionNoReply(eraseMemory, supv::timeout::ERASE_MEMORY); if (result != returnvalue::OK) { return result; } return returnvalue::OK; } -ReturnValue_t PlocSupvHelper::handlePacketTransmission(ploc::SpTcBase& packet, - uint32_t timeoutExecutionReport) { +ReturnValue_t PlocSupvHelper::handlePacketTransmissionNoReply(supv::TcBase& packet, + uint32_t timeoutExecutionReport) { ReturnValue_t result = returnvalue::OK; - result = sendCommand(packet); + result = encodeAndSendPacket(packet.getFullPacket(), packet.getFullPacketLen()); if (result != returnvalue::OK) { return result; } - result = handleAck(); - if (result != returnvalue::OK) { - return result; - } - result = handleExe(timeoutExecutionReport); - if (result != returnvalue::OK) { - return result; + Countdown countdown(timeoutExecutionReport); + bool ackReceived = false; + while (true) { + if (not decodedQueue.empty()) { + size_t packetLen = 0; + decodedQueue.retrieve(&packetLen); + decodedRingBuf.readData(decodedBuf.data(), packetLen); + tmReader.setData(decodedBuf.data(), packetLen); + result = checkReceivedTm(); + if (result != returnvalue::OK) { + continue; + } + if (tmReader.getApid() == Apid::TMTC_MAN) { + uint8_t serviceId = tmReader.getServiceId(); + int retval = 0; + if (not ackReceived) { + retval = handleAckReception(packet, serviceId, packetLen); + if (retval == 1) { + ackReceived = true; + } else if (retval == -1) { + return returnvalue::FAILED; + } + } else { + retval = handleExeAckReception(packet, serviceId, packetLen); + if (retval == 1) { + break; + } else if (retval == -1) { + return returnvalue::FAILED; + } + } + } else { + pushIpcData(decodedBuf.data(), packetLen); + decodedRingBuf.deleteData(packetLen); + } + } else { + TaskFactory::delayTask(50); + } + if (countdown.hasTimedOut()) { + return result::NO_REPLY_TIMEOUT; + } } return returnvalue::OK; } -ReturnValue_t PlocSupvHelper::sendCommand(ploc::SpTcBase& packet) { - ReturnValue_t result = returnvalue::OK; - rememberApid = packet.getApid(); - result = uartComIF->sendMessage(comCookie, packet.getFullPacket(), packet.getFullPacketLen()); - if (result != returnvalue::OK) { - sif::warning << "PlocSupvHelper::sendCommand: Failed to send command" << std::endl; - triggerEvent(SUPV_SENDING_COMMAND_FAILED, result, static_cast(state)); - return result; - } - return result; -} - -ReturnValue_t PlocSupvHelper::handleAck() { - ReturnValue_t result = returnvalue::OK; - - // TODO: Fix - // result = handleTmReception(supv::SIZE_ACK_REPORT); - // if (result != returnvalue::OK) { - // triggerEvent(ACK_RECEPTION_FAILURE, result, static_cast(rememberApid)); - // sif::warning << "PlocSupvHelper::handleAck: Error in reception of acknowledgment report" - // << std::endl; - // return result; - // } - // supv::AcknowledgmentReport ackReport(tmBuf.data(), tmBuf.size()); - // result = checkReceivedTm(ackReport); - // if (result != returnvalue::OK) { - // return result; - // } - // result = ackReport.checkApid(); - // if (result != returnvalue::OK) { - // if (result == SupvReturnValuesIF::RECEIVED_ACK_FAILURE) { - // triggerEvent(SUPV_ACK_FAILURE_REPORT, static_cast(ackReport.getRefApid())); - // } else if (result == SupvReturnValuesIF::INVALID_APID) { - // triggerEvent(SUPV_ACK_INVALID_APID, static_cast(rememberApid)); - // } - // return result; - // } - return result; -} - -ReturnValue_t PlocSupvHelper::handleExe(uint32_t timeout) { - ReturnValue_t result = returnvalue::OK; - - result = handleTmReception(supv::SIZE_EXE_REPORT, tmBuf.data(), timeout); - if (result != returnvalue::OK) { - triggerEvent(EXE_RECEPTION_FAILURE, result, static_cast(rememberApid)); - sif::warning << "PlocSupvHelper::handleExe: Error in reception of execution report" - << std::endl; - return result; - } - - return exeReportHandling(); -} - -ReturnValue_t PlocSupvHelper::exeReportHandling() { - // TODO: Fix - // supv::ExecutionReport exeReport(tmBuf.data(), tmBuf.size()); - // - // ReturnValue_t result = checkReceivedTm(exeReport); - // if (result != returnvalue::OK) { - // return result; - // } - // result = exeReport.checkApid(); - // if (result != returnvalue::OK) { - // if (result == SupvReturnValuesIF::RECEIVED_EXE_FAILURE) { - // triggerEvent(SUPV_EXE_FAILURE_REPORT, static_cast(exeReport.getRefApid())); - // } else if (result == SupvReturnValuesIF::INVALID_APID) { - // triggerEvent(SUPV_EXE_INVALID_APID, static_cast(rememberApid)); - // } - // return result; - // } - return OK; -} - -ReturnValue_t PlocSupvHelper::handleTmReception(size_t remainingBytes, uint8_t* readBuf, - uint32_t timeout) { - ReturnValue_t result = returnvalue::OK; - size_t readBytes = 0; - size_t currentBytes = 0; - Countdown countdown(timeout); - if (readBuf == nullptr) { - readBuf = tmBuf.data(); - } - while (!countdown.hasTimedOut()) { - result = receive(readBuf + readBytes, ¤tBytes, remainingBytes); +int PlocSupvHelper::handleAckReception(supv::TcBase& tc, uint8_t serviceId, size_t packetLen) { + if (serviceId == static_cast(supv::tm::TmtcId::ACK) or + serviceId == static_cast(supv::tm::TmtcId::NAK)) { + AcknowledgmentReport ackReport(tmReader); + ReturnValue_t result = ackReport.parse(); if (result != returnvalue::OK) { - return result; + triggerEvent(ACK_RECEPTION_FAILURE); + return returnvalue::FAILED; } - readBytes += currentBytes; - remainingBytes = remainingBytes - currentBytes; - if (remainingBytes == 0) { - break; + if (ackReport.getRefApid() == tc.getApid() and + ackReport.getRefServiceId() == tc.getServiceId()) { + if (serviceId == static_cast(supv::tm::TmtcId::ACK)) { + return 1; + } else if (serviceId == static_cast(supv::tm::TmtcId::NAK)) { + ackReport.printStatusInformation(); + triggerEvent(SUPV_ACK_FAILURE_REPORT, + buildApidServiceParam1(ackReport.getRefApid(), ackReport.getRefServiceId()), + ackReport.getStatusCode()); + return -1; + } + // Should never happen + return -1; + } else { + pushIpcData(decodedBuf.data(), packetLen); + decodedRingBuf.deleteData(packetLen); } } - if (remainingBytes != 0) { - sif::warning << "PlocSupvHelper::handleTmReception: Failed to read " << std::dec - << remainingBytes << " remaining bytes" << std::endl; - return returnvalue::FAILED; - } - return result; + return 0; } -ReturnValue_t PlocSupvHelper::checkReceivedTm(ploc::SpTmReader& reader) { - ReturnValue_t result = reader.checkSize(); +int PlocSupvHelper::handleExeAckReception(supv::TcBase& tc, uint8_t serviceId, size_t packetLen) { + if (serviceId == static_cast(supv::tm::TmtcId::EXEC_ACK) or + serviceId == static_cast(supv::tm::TmtcId::EXEC_NAK)) { + ExecutionReport exeReport(tmReader); + ReturnValue_t result = exeReport.parse(); + if (result != returnvalue::OK) { + triggerEvent(EXE_RECEPTION_FAILURE); + return returnvalue::FAILED; + } + if (exeReport.getRefApid() == tc.getApid() and + exeReport.getRefServiceId() == tc.getServiceId()) { + if (serviceId == static_cast(supv::tm::TmtcId::EXEC_ACK)) { + return 1; + } else if (serviceId == static_cast(supv::tm::TmtcId::EXEC_NAK)) { + exeReport.printStatusInformation(); + triggerEvent(SUPV_EXE_FAILURE_REPORT, + buildApidServiceParam1(exeReport.getRefApid(), exeReport.getRefServiceId()), + exeReport.getStatusCode()); + return -1; + } + // Should never happen + return -1; + } else { + pushIpcData(decodedBuf.data(), packetLen); + decodedRingBuf.deleteData(packetLen); + } + } + return 0; +} + +ReturnValue_t PlocSupvHelper::checkReceivedTm() { + ReturnValue_t result = tmReader.checkSize(); if (result != returnvalue::OK) { triggerEvent(SUPV_REPLY_SIZE_MISSMATCH, rememberApid); return result; } - result = reader.checkCrc(); + result = tmReader.checkCrc(); if (result != returnvalue::OK) { triggerEvent(SUPV_REPLY_CRC_MISSMATCH, rememberApid); return result; @@ -687,30 +680,6 @@ ReturnValue_t PlocSupvHelper::checkReceivedTm(ploc::SpTmReader& reader) { return result; } -ReturnValue_t PlocSupvHelper::receive(uint8_t* data, size_t* readBytes, size_t requestBytes) { - ReturnValue_t result = returnvalue::OK; - uint8_t* buffer = nullptr; - result = uartComIF->requestReceiveMessage(comCookie, requestBytes); - if (result != returnvalue::OK) { - sif::warning << "PlocSupvHelper::receive: Failed to request reply" << std::endl; - triggerEvent(SUPV_HELPER_REQUESTING_REPLY_FAILED, result, - static_cast(static_cast(state))); - return returnvalue::FAILED; - } - result = uartComIF->readReceivedMessage(comCookie, &buffer, readBytes); - if (result != returnvalue::OK) { - sif::warning << "PlocSupvHelper::receive: Failed to read received message" << std::endl; - triggerEvent(SUPV_HELPER_READING_REPLY_FAILED, result, static_cast(state)); - return returnvalue::FAILED; - } - if (*readBytes > 0) { - std::memcpy(data, buffer, *readBytes); - } else { - TaskFactory::delayTask(40); - } - return result; -} - ReturnValue_t PlocSupvHelper::calcImageCrc() { ReturnValue_t result = returnvalue::OK; if (update.fullFileSize == 0) { @@ -760,20 +729,64 @@ ReturnValue_t PlocSupvHelper::calcImageCrc() { ReturnValue_t PlocSupvHelper::handleCheckMemoryCommand() { ReturnValue_t result = returnvalue::OK; // TODO: Fix - // resetSpParams(); - // // Will hold status report for later processing + 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) { - // return result; - // } - // result = sendCommand(packet); - // if (result != returnvalue::OK) { - // return result; - // } + // Verification of update write procedure + supv::CheckMemory packet(spParams); + result = packet.buildPacket(update.memoryId, update.startAddress, update.fullFileSize); + if (result != returnvalue::OK) { + return result; + } + result = encodeAndSendPacket(packet.getFullPacket(), packet.getFullPacketLen()); + if (result != returnvalue::OK) { + return result; + } + Countdown countdown(timeout::CRC_EXECUTION_TIMEOUT); + bool ackReceived = false; + bool checkReplyReceived = false; + while (true) { + if (not decodedQueue.empty()) { + size_t packetLen = 0; + decodedQueue.retrieve(&packetLen); + decodedRingBuf.readData(decodedBuf.data(), packetLen); + tmReader.setData(decodedBuf.data(), packetLen); + result = checkReceivedTm(); + if (result != returnvalue::OK) { + continue; + } + if (tmReader.getApid() == Apid::TMTC_MAN) { + uint8_t serviceId = tmReader.getServiceId(); + int retval = 0; + if (not ackReceived) { + retval = handleAckReception(packet, serviceId, packetLen); + if (retval == 1) { + ackReceived = true; + } else if (retval == -1) { + return returnvalue::FAILED; + } + } else if (not checkReplyReceived) { + // if (serviceId == ) + retval = handleExeAckReception(packet, serviceId, packetLen); + if (retval == 1) { + break; + } else if (retval == -1) { + return returnvalue::FAILED; + } + } + } else { + pushIpcData(decodedBuf.data(), packetLen); + decodedRingBuf.deleteData(packetLen); + } + } else { + TaskFactory::delayTask(50); + } + if (countdown.hasTimedOut()) { + return result::NO_REPLY_TIMEOUT; + } + } + return returnvalue::OK; // result = handleAck(); // if (result != returnvalue::OK) { // return result; @@ -896,7 +909,7 @@ ReturnValue_t PlocSupvHelper::handleEventBufferReception(ploc::SpTmReader& reade return result; } -void PlocSupvHelper::resetSpParams() { spParams.buf = commandBuffer; } +void PlocSupvHelper::resetSpParams() { spParams.buf = cmdBuf.data(); } ReturnValue_t PlocSupvHelper::sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) { @@ -968,8 +981,8 @@ ReturnValue_t PlocSupvHelper::handleRunningLongerRequest() { ReturnValue_t PlocSupvHelper::encodeAndSendPacket(const uint8_t* sendData, size_t sendLen) { size_t encodedLen = 0; - hdlc_add_framing(sendData, sendLen, sendBuf.data(), &encodedLen); - size_t bytesWritten = write(serialPort, sendBuf.data(), encodedLen); + hdlc_add_framing(sendData, sendLen, encodedSendBuf.data(), &encodedLen); + size_t bytesWritten = write(serialPort, encodedSendBuf.data(), encodedLen); if (bytesWritten != encodedLen) { sif::warning << "ScexUartReader::sendMessage: Sending ping command to solar experiment failed" << std::endl; @@ -980,7 +993,7 @@ ReturnValue_t PlocSupvHelper::encodeAndSendPacket(const uint8_t* sendData, size_ ReturnValue_t PlocSupvHelper::readReceivedMessage(CookieIF* cookie, uint8_t** buffer, size_t* size) { - MutexGuard mg(lock); + MutexGuard mg(ipcLock); if (ipcQueue.empty()) { *size = 0; return OK; @@ -999,7 +1012,14 @@ ReturnValue_t PlocSupvHelper::tryHdlcParsing() { ReturnValue_t result = parseRecRingBufForHdlc(bytesRead); if (result == returnvalue::OK) { // Packet found, advance read pointer. - ipcRingBuf.writeData(decodedBuf.data(), bytesRead); + if (state == InternalState::LONGER_REQUEST) { + decodedRingBuf.writeData(decodedBuf.data(), bytesRead); + decodedQueue.insert(bytesRead); + } else { + MutexGuard mg(ipcLock); + ipcRingBuf.writeData(decodedBuf.data(), bytesRead); + ipcQueue.insert(bytesRead); + } recRingBuf.deleteData(bytesRead); } else if (result != NO_PACKET_FOUND) { sif::warning << "ScexUartReader::performOperation: Possible packet loss" << std::endl; @@ -1053,10 +1073,28 @@ ReturnValue_t PlocSupvHelper::parseRecRingBufForHdlc(size_t& readSize) { return NO_PACKET_FOUND; } +void PlocSupvHelper::pushIpcData(const uint8_t* data, size_t len) { + MutexGuard mg(ipcLock); + ipcRingBuf.writeData(data, len); + ipcQueue.insert(len); +} + +uint32_t PlocSupvHelper::buildApidServiceParam1(uint8_t apid, uint8_t serviceId) { + return (apid << 8) | serviceId; +} + void PlocSupvHelper::performUartShutdown() { tcflush(serialPort, TCIOFLUSH); // Clear ring buffers recRingBuf.clear(); + decodedRingBuf.clear(); + while (not decodedQueue.empty()) { + decodedQueue.pop(); + } + MutexGuard mg(ipcLock); ipcRingBuf.clear(); + while (not ipcQueue.empty()) { + ipcQueue.pop(); + } state = InternalState::GO_TO_SLEEP; } diff --git a/linux/devices/ploc/PlocSupvUartMan.h b/linux/devices/ploc/PlocSupvUartMan.h index 9426b2e4..34d8bd2e 100644 --- a/linux/devices/ploc/PlocSupvUartMan.h +++ b/linux/devices/ploc/PlocSupvUartMan.h @@ -121,8 +121,8 @@ class PlocSupvHelper : public DeviceCommunicationIF, ReturnValue_t initialize() override; ReturnValue_t performOperation(uint8_t operationCode = 0) override; - ReturnValue_t setComIF(UartComIF* uartComfIF_); - // void setComCookie(CookieIF* comCookie_); + // ReturnValue_t setComIF(UartComIF* uartComfIF_); + // void setComCookie(CookieIF* comCookie_); /** * @brief Starts update procedure @@ -156,6 +156,7 @@ class PlocSupvHelper : public DeviceCommunicationIF, void stop(); static uint32_t buildProgParams1(uint8_t percent, uint16_t seqCount); + static uint32_t buildApidServiceParam1(uint8_t apid, uint8_t serviceId); private: static constexpr ReturnValue_t REQUEST_DONE = returnvalue::makeCode(1, 0); @@ -171,7 +172,6 @@ class PlocSupvHelper : public DeviceCommunicationIF, static const uint8_t NUM_EVENT_BUFFER_PACKETS = 25; static const size_t SIZE_EVENT_BUFFER_FULL_PACKET = 1024; static const size_t SIZE_EVENT_BUFFER_LAST_PACKET = 200; - static const uint32_t CRC_EXECUTION_TIMEOUT = 60000; static const uint32_t PREPARE_UPDATE_EXECUTION_REPORT = 2000; static constexpr uint8_t MAX_STORED_DECODED_PACKETS = 4; @@ -200,6 +200,8 @@ class PlocSupvHelper : public DeviceCommunicationIF, SemaphoreIF* semaphore; MutexIF* lock; + MutexIF* ipcLock; + supv::TmBase tmReader; int serialPort = 0; struct termios tty = {}; @@ -228,15 +230,17 @@ class PlocSupvHelper : public DeviceCommunicationIF, SdCardManager* sdcMan = nullptr; #endif SimpleRingBuffer recRingBuf; - std::array sendBuf = {}; + std::array cmdBuf = {}; + std::array encodedSendBuf = {}; std::array recBuf = {}; std::array encodedBuf = {}; std::array decodedBuf = {}; std::array ipcBuffer = {}; + SimpleRingBuffer decodedRingBuf; + FIFO decodedQueue; SimpleRingBuffer ipcRingBuf; FIFO ipcQueue; - uint8_t commandBuffer[supv::MAX_COMMAND_SIZE]{}; SpacePacketCreator creator; supv::TcParams spParams = supv::TcParams(creator); @@ -246,9 +250,9 @@ class PlocSupvHelper : public DeviceCommunicationIF, /** * Communication interface responsible for data transactions between OBC and Supervisor. */ - UartComIF* uartComIF = nullptr; - // Communication cookie. Must be set by the supervisor Handler - CookieIF* comCookie = nullptr; + // UartComIF* uartComIF = nullptr; + // Communication cookie. Must be set by the supervisor Handler + // CookieIF* comCookie = nullptr; bool timestamping = true; @@ -268,9 +272,12 @@ class PlocSupvHelper : public DeviceCommunicationIF, ReturnValue_t updateOperation(); ReturnValue_t writeUpdatePackets(); // ReturnValue_t performEventBufferRequest(); - ReturnValue_t handlePacketTransmission(ploc::SpTcBase& packet, - uint32_t timeoutExecutionReport = 60000); - ReturnValue_t sendCommand(ploc::SpTcBase& packet); + ReturnValue_t handlePacketTransmissionNoReply(supv::TcBase& packet, + uint32_t timeoutExecutionReport = 60000); + 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 * @@ -278,7 +285,7 @@ class PlocSupvHelper : public DeviceCommunicationIF, * @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 receive(uint8_t* data, size_t* readBytes, size_t requestBytes); ReturnValue_t handleAck(); ReturnValue_t handleExe(uint32_t timeout = 1000); /** @@ -293,7 +300,7 @@ class PlocSupvHelper : public DeviceCommunicationIF, */ ReturnValue_t handleTmReception(size_t remainingBytes, uint8_t* readBuf = nullptr, uint32_t timeout = 70000); - ReturnValue_t checkReceivedTm(ploc::SpTmReader& reader); + ReturnValue_t checkReceivedTm(); ReturnValue_t selectMemory(); ReturnValue_t prepareUpdate(); @@ -315,6 +322,7 @@ class PlocSupvHelper : public DeviceCommunicationIF, ReturnValue_t handleRemainingExeReport(ploc::SpTmReader& reader); void resetSpParams(); + void pushIpcData(const uint8_t* data, size_t len); /** * @brief Device specific initialization, using the cookie. diff --git a/mission/devices/devicedefinitions/SpBase.h b/mission/devices/devicedefinitions/SpBase.h index f34e921a..22c138b5 100644 --- a/mission/devices/devicedefinitions/SpBase.h +++ b/mission/devices/devicedefinitions/SpBase.h @@ -50,6 +50,8 @@ class SpTcBase { uint16_t getApid() const { return spParams.creator.getApid(); } + uint16_t getSeqCount() const { return spParams.creator.getSequenceCount(); } + ReturnValue_t checkPayloadLen() { if (ccsds::HEADER_LEN + spParams.fullPayloadLen > spParams.maxSize) { return SerializeIF::BUFFER_TOO_SHORT;