From c54eccfe432a9c1cc0db8cc20bff4018ff94b291 Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" Date: Thu, 22 Apr 2021 17:32:39 +0200 Subject: [PATCH] tc mem write and tc mem read implemented --- linux/uart/UartComIF.cpp | 3 + mission/devices/PlocHandler.cpp | 470 ++++++++++++------ mission/devices/PlocHandler.h | 91 +++- .../devicedefinitions/PlocDefinitions.h | 31 +- 4 files changed, 401 insertions(+), 194 deletions(-) diff --git a/linux/uart/UartComIF.cpp b/linux/uart/UartComIF.cpp index 79470a45..8d9a15c3 100644 --- a/linux/uart/UartComIF.cpp +++ b/linux/uart/UartComIF.cpp @@ -363,6 +363,9 @@ ReturnValue_t UartComIF::readReceivedMessage(CookieIF *cookie, *buffer = uartDeviceMapIter->second.replyBuffer.data(); *size = uartDeviceMapIter->second.replyLen; + /* Length is reset to 0 to prevent reading the same data twice */ + uartDeviceMapIter->second.replyLen = 0; + return RETURN_OK; } diff --git a/mission/devices/PlocHandler.cpp b/mission/devices/PlocHandler.cpp index 38c835dc..f1444488 100644 --- a/mission/devices/PlocHandler.cpp +++ b/mission/devices/PlocHandler.cpp @@ -53,6 +53,98 @@ ReturnValue_t PlocHandler::buildCommandFromCommand( return HasReturnvaluesIF::RETURN_FAILED; } +void PlocHandler::fillCommandAndReplyMap() { + this->insertInCommandMap(PLOC::TC_MEM_WRITE); + this->insertInCommandMap(PLOC::TC_MEM_READ); + this->insertInReplyMap(PLOC::ACK_REPORT, 1, nullptr, PLOC::SIZE_ACK_REPORT); + this->insertInReplyMap(PLOC::EXE_REPORT, 3, nullptr, PLOC::SIZE_EXE_REPORT); + this->insertInReplyMap(PLOC::TM_MEMORY_READ_REPORT, 2, nullptr, PLOC::SIZE_TM_MEM_READ_REPORT); +} + +ReturnValue_t PlocHandler::scanForReply(const uint8_t *start, + size_t remainingSize, DeviceCommandId_t *foundId, size_t *foundLen) { + + ReturnValue_t result = RETURN_OK; + + uint16_t apid = (*(start) << 8 | *(start + 1)) & APID_MASK; + + switch(apid) { + case(PLOC::APID_ACK_SUCCESS): + *foundLen = PLOC::SIZE_ACK_REPORT; + *foundId = PLOC::ACK_REPORT; + break; + case(PLOC::APID_ACK_FAILURE): + *foundLen = PLOC::SIZE_ACK_REPORT; + *foundId = PLOC::ACK_REPORT; + break; + case(PLOC::APID_TM_MEMORY_READ_REPORT): + *foundLen = PLOC::SIZE_TM_MEM_READ_REPORT; + *foundId = PLOC::TM_MEMORY_READ_REPORT; + break; + case(PLOC::APID_EXE_SUCCESS): + *foundLen = PLOC::SIZE_EXE_REPORT; + *foundId = PLOC::EXE_REPORT; + break; + case(PLOC::APID_EXE_FAILURE): + *foundLen = PLOC::SIZE_EXE_REPORT; + *foundId = PLOC::EXE_REPORT; + break; + default: { + sif::debug << "PlocHandler::scanForReply: Reply has invalid apid" << std::endl; + *foundLen = remainingSize; + result = INVALID_APID; + break; + } + } + + return result; +} + +ReturnValue_t PlocHandler::interpretDeviceReply(DeviceCommandId_t id, + const uint8_t *packet) { + + ReturnValue_t result = RETURN_OK; + + switch (id) { + case PLOC::ACK_REPORT: { + result = handleAckReport(packet); + break; + } + case (PLOC::TM_MEMORY_READ_REPORT): { + result = handleMemoryReadReport(packet); + break; + } + case (PLOC::EXE_REPORT): { + result = handleExecutionReport(packet); + break; + } + default: { + sif::debug << "PlocHandler::interpretDeviceReply: Unknown device reply id" << std::endl; + return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; + } + } + + return result; +} + +void PlocHandler::setNormalDatapoolEntriesInvalid(){ + +} + +uint32_t PlocHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo){ + return 500; +} + +ReturnValue_t PlocHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, + LocalDataPoolManager& poolManager) { + + return HasReturnvaluesIF::RETURN_OK; +} + +void PlocHandler::setModeNormal() { + mode = MODE_NORMAL; +} + ReturnValue_t PlocHandler::prepareTcMemWriteCommand(const uint8_t * commandData, size_t commandDataLen) { const uint32_t memoryAddress = *(commandData) << 24 | *(commandData + 1) << 16 @@ -67,7 +159,7 @@ ReturnValue_t PlocHandler::prepareTcMemWriteCommand(const uint8_t * commandData, memcpy(commandBuffer, tcMemWrite.getWholeData(), tcMemWrite.getFullSize()); rawPacket = commandBuffer; rawPacketLen = tcMemWrite.getFullSize(); - rememberCommandId = PLOC::TC_MEM_WRITE; + nextReplyId = PLOC::ACK_REPORT; return RETURN_OK; } @@ -83,53 +175,10 @@ ReturnValue_t PlocHandler::prepareTcMemReadCommand(const uint8_t * commandData, memcpy(commandBuffer, tcMemRead.getWholeData(), tcMemRead.getFullSize()); rawPacket = commandBuffer; rawPacketLen = tcMemRead.getFullSize(); - rememberCommandId = PLOC::TC_MEM_READ; + nextReplyId = PLOC::ACK_REPORT; return RETURN_OK; } -void PlocHandler::fillCommandAndReplyMap() { - this->insertInCommandAndReplyMap(PLOC::TC_MEM_WRITE, 1, nullptr, PLOC::SIZE_ACK_REPORT); - this->insertInCommandAndReplyMap(PLOC::TC_MEM_READ, 1, nullptr, PLOC::SIZE_TC_MEM_READ_REPLY); -} - -ReturnValue_t PlocHandler::scanForReply(const uint8_t *start, - size_t remainingSize, DeviceCommandId_t *foundId, size_t *foundLen) { - - ReturnValue_t result = RETURN_OK; - - uint16_t apid = (*(start) << 8 | *(start + 1)) & APID_MASK; - - switch(apid) { - case(PLOC::APID_ACK_SUCCESS): - *foundLen = PLOC::SIZE_ACK_REPORT; - *foundId = rememberCommandId; - break; - case(PLOC::APID_ACK_FAILURE): - *foundLen = PLOC::SIZE_ACK_REPORT; -<<<<<<< Updated upstream - *foundId = rememberCommandId; - break; -======= - break; - case(PLOC::TM_READ_REPORT): - *foundLen = PLOC::SIZE_ACK_REPORT; - break; - case(PLOC::EXE_SUCCESS): - *foundLen = PLOC::SIZE_EXE_REPORT; - break; - case(PLOC::EXE_FAILURE): - *foundLen = PLOC::SIZE_EXE_REPORT; - break; ->>>>>>> Stashed changes - default: - sif::debug << "PlocHandler::scanForReply: Reply has invalid apid" << std::endl; - return IGNORE_REPLY_DATA; - break; - } - - return result; -} - ReturnValue_t PlocHandler::verifyPacket(const uint8_t* start, size_t foundLen) { uint16_t receivedCrc = *(start + foundLen - 2) << 8 | *(start + foundLen - 1); @@ -137,137 +186,202 @@ ReturnValue_t PlocHandler::verifyPacket(const uint8_t* start, size_t foundLen) { uint16_t recalculatedCrc = CRC::crc16ccitt(start, foundLen - 2, 0); if (receivedCrc != recalculatedCrc) { - sif::debug << "PlocHandler::verifyPacket: CRC failure of ACK reply" << std::endl; return CRC_FAILURE; } return RETURN_OK; } -ReturnValue_t PlocHandler::interpretDeviceReply(DeviceCommandId_t id, - const uint8_t *packet) { - - uint16_t apid = (*(packet) << 8 | *(packet + 1)) & APID_MASK; - - if (apid == PLOC::APID_ACK_FAILURE) { - sif::error << "PlocHandler::interpretDeviceReply: Received ACK failure reply" << std::endl; - triggerEvent(ACK_FAILURE, id); - replyRawData(packet, PLOC::SIZE_ACK_REPORT, defaultRawReceiver); - return RETURN_OK; - } - - if (verifyPacket(packet, PLOC::SIZE_ACK_REPORT) == CRC_FAILURE) { - sif::error << "PlocHandler::interpretDeviceReply: CRC failure in Ack reply" << std::endl; - replyRawData(packet, PLOC::SIZE_ACK_REPORT, defaultRawReceiver); - triggerEvent(CRC_FAILURE_IN_ACK_REPLY, id); - return RETURN_OK; - } - - switch (id) { - case (PLOC::TC_MEM_WRITE): - receiveExecutionReport(); - break; - case (PLOC::TC_MEM_READ): - receiveTmMemoryReadReport(); - receiveExecutionReport(); - break; - default: - sif::debug << "PlocHandler::interpretDeviceReply: Unknown device reply id" << std::endl; - return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; - } - - rememberCommandId = PLOC::NONE; - return RETURN_OK; -} - -ReturnValue_t PlocHandler::receiveExecutionReport() { - - size_t receivedDataLen = 0; - uint8_t *receivedData = nullptr; +ReturnValue_t PlocHandler::handleAckReport(const uint8_t* data) { ReturnValue_t result = RETURN_OK; - result = communicationInterface->requestReceiveMessage(comCookie, PLOC::SIZE_EXE_REPORT); - if (result != RETURN_OK) { - sif::error << "PlocHandler::receiveExecutionReport: Failed to request execution report" - << std::endl; - return result; - } - result = communicationInterface->readReceivedMessage(comCookie, &receivedData, &receivedDataLen); - if (result != RETURN_OK) { - sif::error << "PlocHandler::receiveExecutionReport: Failed to read execution report" - << std::endl; - return result; + result = verifyPacket(data, PLOC::SIZE_ACK_REPORT); + if(result == CRC_FAILURE) { + sif::error << "PlocHandler::handleAckReport: CRC failure" << std::endl; + nextReplyId = PLOC::NONE; + replyRawReplyIfnotWiretapped(data, PLOC::SIZE_ACK_REPORT); + triggerEvent(CRC_FAILURE_EVENT); + sendFailureReport(PLOC::ACK_REPORT, CRC_FAILURE); + disableAllReplies(); + return IGNORE_REPLY_DATA; } - if(verifyPacket(receivedData, receivedDataLen) == CRC_FAILURE) { - replyRawData(receivedData, receivedDataLen, defaultRawReceiver); - triggerEvent(EXE_RPT_INVALID_CRC); - sif::error << "PlocHandler::receiveExecutionReport: Execution report has invalid crc" - << std::endl; - return result; - } + uint16_t apid = (*(data) << 8 | *(data + 1)) & APID_MASK; - result = handleExecutionReport(receivedData, receivedDataLen); + switch(apid) { + case PLOC::APID_ACK_FAILURE: { + //TODO: Interpretation of status field in acknowledgment report + sif::debug << "PlocHandler::handleAckReport: Received Ack failure report" << std::endl; + DeviceCommandId_t commandId = getPendingCommand(); + if (commandId != DeviceHandlerIF::NO_COMMAND_ID) { + triggerEvent(ACK_FAILURE, commandId); + } + sendFailureReport(PLOC::ACK_REPORT, RECEIVED_ACK_FAILURE); + disableAllReplies(); + nextReplyId = PLOC::NONE; + result = IGNORE_REPLY_DATA; + break; + } + case PLOC::APID_ACK_SUCCESS: { + setNextReplyId(); + break; + } + default: { + sif::debug << "PlocHandler::handleAckReport: Invalid APID in Ack report" << std::endl; + result = RETURN_FAILED; + break; + } + } + + return result; } -ReturnValue_t PlocHandler::handleExecutionReport(const uint8_t* receivedData, size_t receivedDataLen) { +ReturnValue_t PlocHandler::handleExecutionReport(const uint8_t* data) { - uint16_t apid = (*(receivedData) << 8 | *(receivedData + 1)) & APID_MASK; + ReturnValue_t result = RETURN_OK; + + result = verifyPacket(data, PLOC::SIZE_EXE_REPORT); + if(result == CRC_FAILURE) { + sif::error << "PlocHandler::handleExecutionReport: CRC failure" << std::endl; + nextReplyId = PLOC::NONE; + return result; + } + + uint16_t apid = (*(data) << 8 | *(data + 1)) & APID_MASK; switch (apid) { case (PLOC::APID_EXE_SUCCESS): { - return; + break; } case (PLOC::APID_EXE_FAILURE): { //TODO: Interpretation of status field in execution report sif::error << "PlocHandler::handleExecutionReport: Received execution failure report" << std::endl; - triggerEvent(EXE_FAILURE, rememberCommandId); - return EXE_REPLY_CRC_FAILURE; + DeviceCommandId_t commandId = getPendingCommand(); + if (commandId != DeviceHandlerIF::NO_COMMAND_ID) { + triggerEvent(EXE_FAILURE, commandId); + } + else { + sif::debug << "PlocHandler::handleExecutionReport: Unknown command id" << std::endl; + } + sendFailureReport(PLOC::EXE_REPORT, RECEIVED_EXE_FAILURE); + disableExeReportReply(); + result = IGNORE_REPLY_DATA; + break; + } + default: { + sif::error << "PlocHandler::handleExecutionReport: Unknown APID" << std::endl; + result = RETURN_FAILED; + break; } } + + nextReplyId = PLOC::NONE; + + return result; +} + +ReturnValue_t PlocHandler::handleMemoryReadReport(const uint8_t* data) { + + ReturnValue_t result = RETURN_OK; + + result = verifyPacket(data, PLOC::SIZE_TM_MEM_READ_REPORT); + + if(result == CRC_FAILURE) { + sif::error << "PlocHandler::handleMemoryReadReport: Memory read report has invalid crc" + << std::endl; + } + /** Send data to commanding queue */ + handleDeviceTM(data + PLOC::DATA_FIELD_OFFSET, PLOC::SIZE_MEM_READ_REPORT_DATA, + PLOC::TM_MEMORY_READ_REPORT); + + nextReplyId = PLOC::EXE_REPORT; + + return result; +} + +ReturnValue_t PlocHandler::enableReplyInReplyMap(DeviceCommandMap::iterator command, + uint8_t expectedReplies, bool useAlternateId, + DeviceCommandId_t alternateReplyID) { + + ReturnValue_t result = RETURN_OK; + + uint8_t enabledReplies = 0; + + switch (command->first) { + case PLOC::TC_MEM_WRITE: + enabledReplies = 2; + break; + case PLOC::TC_MEM_READ: { + enabledReplies = 3; + result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, + PLOC::TM_MEMORY_READ_REPORT); + if (result != RETURN_OK) { + sif::debug << "PlocHandler::enableReplyInReplyMap: Reply with id " + << PLOC::TM_MEMORY_READ_REPORT << " not in replyMap" << std::endl; + } + break; + } + default: + sif::debug << "PlocHandler::enableReplyInReplyMap: Unknown command id" << std::endl; + break; + } + + /** + * Every command causes at least one acknowledgment and one execution report. Therefore both + * replies will be enabled here. + */ + result = DeviceHandlerBase::enableReplyInReplyMap(command, + enabledReplies, true, PLOC::ACK_REPORT); + if (result != RETURN_OK) { + sif::debug << "PlocHandler::enableReplyInReplyMap: Reply with id " << PLOC::ACK_REPORT + << " not in replyMap" << std::endl; + } + + result = DeviceHandlerBase::enableReplyInReplyMap(command, + enabledReplies, true, PLOC::EXE_REPORT); + if (result != RETURN_OK) { + sif::debug << "PlocHandler::enableReplyInReplyMap: Reply with id " << PLOC::EXE_REPORT + << " not in replyMap" << std::endl; + } + return RETURN_OK; } -void PlocHandler::receiveTmMemoryReadReport() { - - size_t receivedDataLen = 0; - uint8_t *receivedData = nullptr; - - /* Receiving the telemetry packet */ - ReturnValue_t result = communicationInterface->requestReceiveMessage(comCookie, - PLOC::SIZE_TM_MEM_READ_REPORT); - if (result != RETURN_OK) { - sif::error << "PlocHandler::receiveExecutionReport: Failed to request memory read telemetry " - << std::endl; - triggerEvent(REQUESTING_TM_READ_REPORT_FAILED, result); - return; +void PlocHandler::setNextReplyId() { + switch(getPendingCommand()) { + case PLOC::TC_MEM_READ: + nextReplyId = PLOC::TM_MEMORY_READ_REPORT; + break; + default: + /* If no telemetry is expected the next reply is always the execution report */ + nextReplyId = PLOC::EXE_REPORT; + break; } - result = communicationInterface->readReceivedMessage(comCookie, &receivedData, &receivedDataLen); - if (result != RETURN_OK) { - sif::error << "PlocHandler::receiveExecutionReport: Failed to request memory read telemetry " - << std::endl; - return; +} +size_t PlocHandler::getNextReplyLength(DeviceCommandId_t commandId){ + + size_t replyLen = 0; + + if (nextReplyId == PLOC::NONE) { + return replyLen; } - uint16_t apid = (*(receivedData) << 8 | *(receivedData + 1)) & APID_MASK; - if (apid != PLOC::APID_TM_READ_REPORT) { - sif::error << "PlocHandler::receiveTmReadReport: Tm read report has invalid apid" - << std::endl; - return; + DeviceReplyIter iter = deviceReplyMap.find(nextReplyId); + if (iter != deviceReplyMap.end()) { + if (iter->second.delayCycles == 0) { + /* Reply inactive */ + return replyLen; + } + replyLen = iter->second.replyLen; + } + else { + sif::debug << "PlocHandler::getNextReplyLength: No entry for reply with reply id " + << std::hex << nextReplyId << " in deviceReplyMap" << std::endl; } - if(verifyPacket(receivedData, receivedDataLen) == CRC_FAILURE) { - replyRawData(receivedData, receivedDataLen, defaultRawReceiver); - triggerEvent(TM_READ_RPT_INVALID_CRC); - sif::error << "PlocHandler::receiveTmReadReport: TM read report has invalid crc" - << std::endl; - return; - } - - handleDeviceTM(receivedData, receivedDataLen, PLOC::TC_MEM_READ); - + return replyLen; } void PlocHandler::handleDeviceTM(const uint8_t* data, size_t dataSize, DeviceCommandId_t replyId) { @@ -291,21 +405,67 @@ void PlocHandler::handleDeviceTM(const uint8_t* data, size_t dataSize, DeviceCom } } -void PlocHandler::setNormalDatapoolEntriesInvalid(){ +void PlocHandler::disableAllReplies() { + DeviceReplyMap::iterator iter; + + /* Disable ack reply */ + iter = deviceReplyMap.find(PLOC::ACK_REPORT); + DeviceReplyInfo *info = &(iter->second); + info->delayCycles = 0; + info->command = deviceCommandMap.end(); + + DeviceCommandId_t commandId = getPendingCommand(); + + /* If the command expects a telemetry packet the appropriate tm reply will be disabled here */ + switch (commandId) { + case PLOC::TC_MEM_WRITE: + break; + case PLOC::TC_MEM_READ: { + iter = deviceReplyMap.find(PLOC::TM_MEMORY_READ_REPORT); + info = &(iter->second); + info->delayCycles = 0; + info->command = deviceCommandMap.end(); + break; + } + default: { + sif::debug << "PlocHandler::disableAllReplies: Unknown command id" << commandId + << std::endl; + break; + } + } + + /* We must always disable the execution report reply here */ + disableExeReportReply(); } -uint32_t PlocHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo){ - return 500; +void PlocHandler::sendFailureReport(DeviceCommandId_t replyId, ReturnValue_t status) { + + DeviceReplyIter iter = deviceReplyMap.find(replyId); + + if (iter == deviceReplyMap.end()) { + sif::debug << "PlocHandler::sendFailureReport: Reply not in reply map" << std::endl; + return; + } + + DeviceCommandInfo* info = &(iter->second.command->second); + + if (info == nullptr) { + sif::debug << "PlocHandler::sendFailureReport: Reply has no active command" << std::endl; + return; + } + + if (info->sendReplyTo != NO_COMMANDER) { + actionHelper.finish(false, info->sendReplyTo, iter->first, status); + } + info->isExecuting = false; } -ReturnValue_t PlocHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, - LocalDataPoolManager& poolManager) { - - return HasReturnvaluesIF::RETURN_OK; +void PlocHandler::disableExeReportReply() { + DeviceReplyIter iter = deviceReplyMap.find(PLOC::EXE_REPORT); + DeviceReplyInfo *info = &(iter->second); + info->delayCycles = 0; + info->command = deviceCommandMap.end(); + /* Expected replies is set to one here. The value will set to 0 in replyToReply() */ + info->command->second.expectedReplies = 0; } - -void PlocHandler::setModeNormal() { - mode = MODE_NORMAL; -} - diff --git a/mission/devices/PlocHandler.h b/mission/devices/PlocHandler.h index 0c0bf7d8..b241c838 100644 --- a/mission/devices/PlocHandler.h +++ b/mission/devices/PlocHandler.h @@ -6,7 +6,10 @@ #include /** - * @brief This is the device handler for the ISIS Magnetorquer iMTQ. + * @brief This is the device handler for the PLOC. + * + * @details The PLOC uses the space packet protocol for communication. On each command the PLOC + * answers at least with one acknowledgment and one execution report. * * @author J. Meier */ @@ -37,30 +40,38 @@ protected: uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override; ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) override; + ReturnValue_t enableReplyInReplyMap(DeviceCommandMap::iterator command, + uint8_t expectedReplies = 1, bool useAlternateId = false, + DeviceCommandId_t alternateReplyID = 0) override; + size_t getNextReplyLength(DeviceCommandId_t deviceCommand) override; private: static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_HANDLER; - static const ReturnValue_t TC_ACK_FAILURE = MAKE_RETURN_CODE(0xA0); - static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA1); - static const ReturnValue_t EXE_REPLY_CRC_FAILURE = MAKE_RETURN_CODE(0xA1); + static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA0); //!> Space Packet received from PLOC has invalid CRC + static const ReturnValue_t RECEIVED_ACK_FAILURE = MAKE_RETURN_CODE(0xA1); //!> Received ACK failure reply from PLOC + static const ReturnValue_t RECEIVED_EXE_FAILURE = MAKE_RETURN_CODE(0xA2); //!> Received execution failure reply from PLOC + static const ReturnValue_t INVALID_APID = MAKE_RETURN_CODE(0xA3); //!> Received space packet with invalid APID from PLOC static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_HANDLER; - static const Event REQUESTING_TM_READ_REPORT_FAILED = MAKE_EVENT(0, severity::LOW); - static const Event TM_READ_RPT_INVALID_CRC = MAKE_EVENT(1, severity::LOW); - static const Event ACK_FAILURE = MAKE_EVENT(2, severity::LOW); - static const Event CRC_FAILURE_IN_ACK_REPLY = MAKE_EVENT(2, severity::LOW); - static const Event EXE_FAILURE = MAKE_EVENT(3, severity::LOW); - static const Event EXE_RPT_INVALID_CRC = MAKE_EVENT(4, severity::LOW); + static const Event MEMORY_READ_RPT_CRC_FAILURE = MAKE_EVENT(1, severity::LOW); //!> PLOC crc failure in telemetry packet + static const Event ACK_FAILURE = MAKE_EVENT(2, severity::LOW); //!> PLOC receive acknowledgment failure report + static const Event EXE_FAILURE = MAKE_EVENT(3, severity::LOW); //!> PLOC receive execution failure report + static const Event CRC_FAILURE_EVENT = MAKE_EVENT(4, severity::LOW); //!> PLOC reply has invalid crc static const uint16_t APID_MASK = 0x7FF; - DeviceCommandId_t rememberCommandId = PLOC::NONE; - uint8_t commandBuffer[PLOC::MAX_COMMAND_SIZE]; + /** + * This variable is used to store the id of the next reply to receive. This is necessary + * because the PLOC sends as reply to each command at least one acknowledgment and execution + * report. + */ + DeviceCommandId_t nextReplyId = PLOC::NONE; + /** * @brief This function fills the commandBuffer to initiate the write memory command. * @@ -92,39 +103,71 @@ private: ReturnValue_t verifyPacket(const uint8_t* start, size_t foundLen); /** - * @brief This function reads and handles the execution reply. - * @param RETURN_OK if reading and handling of reply successful, otherwise failure value. + * @brief This function handles the acknowledgment report. + * + * @param data Pointer to the data holding the acknowledgment report. + * + * @return RETURN_OK if successful, otherwise an error code. */ - ReturnValue_t receiveExecutionReport(); + ReturnValue_t handleAckReport(const uint8_t* data); /** * @brief This function handles the data of a execution report. * - * @param receivedData Pointer to the received data - * @param receivedDataLen Size in bytes of the received data + * @param data Pointer to the received data packet. * * @return RETURN_OK if successful, otherwise an error code. */ - void handleExecutionReport(const uint8_t* receivedData, size_t receivedDataLen); + ReturnValue_t handleExecutionReport(const uint8_t* data); /** - * @brief This function reads and handles the memory read report telemetry packet received - * after requesting the packet with the TC_MEM_READ command. + * @brief This function handles the memory read report. * - * @details In case of a valid packet the received memory content will be forwarded to the - * commanding object via an action message. + * @param data Pointer to the data buffer holding the memory read report. + * + * @return RETURN_OK if successful, otherwise an error code. */ - ReturnValue_t receiveTmMemoryReadReport(); + ReturnValue_t handleMemoryReadReport(const uint8_t* data); + + /** + * @brief Depending on the current active command, this function sets the reply id of the + * next reply after a successful acknowledgment report has been received. This is + * required by the function getNextReplyLength() to identify the length of the next + * reply to read. + */ + void setNextReplyId(); /** * @brief This function handles action message replies in case the telemetry has been * requested by another object. * - * @param data Pointer to the telemtry data. + * @param data Pointer to the telemetry data. * @param dataSize Size of telemetry in bytes. * @param replyId Id of the reply. This will be added to the ActionMessage. */ void handleDeviceTM(const uint8_t* data, size_t dataSize, DeviceCommandId_t replyId); + + /** + * @brief In case an acknowledgment failure reply has been received this function disables + * all previously enabled commands and resets the exepected replies variable of an + * active command. + */ + void disableAllReplies(); + + /** + * @brief This function sends a failure report if the active action was commanded by an other + * object. + * + * @param replyId The id of the reply which signals a failure. + * @param status A status byte which gives information about the failure type. + */ + void sendFailureReport(DeviceCommandId_t replyId, ReturnValue_t status); + + /** + * @brief This function disables the execution report reply. Within this function also the + * the variable expectedReplies of an active command will be set to 0. + */ + void disableExeReportReply(); }; #endif /* MISSION_DEVICES_PLOCHANDLER_H_ */ diff --git a/mission/devices/devicedefinitions/PlocDefinitions.h b/mission/devices/devicedefinitions/PlocDefinitions.h index fdcae741..b7378a8a 100644 --- a/mission/devices/devicedefinitions/PlocDefinitions.h +++ b/mission/devices/devicedefinitions/PlocDefinitions.h @@ -8,35 +8,36 @@ namespace PLOC { static const DeviceCommandId_t NONE = 0x0; - static const DeviceCommandId_t TC_MEM_WRITE = 0x714; - static const DeviceCommandId_t TC_MEM_READ = 0x715; -<<<<<<< Updated upstream -======= - static const DeviceCommandId_t ACK_SUCCESS = 0x400; - static const DeviceCommandId_t ACK_FAILURE = 0x401; - static const DeviceCommandId_t EXE_SUCCESS = 0x402; - static const DeviceCommandId_t EXE_FAILURE = 0x403; - static const DeviceCommandId_t TM_READ_REPORT = 0x404; ->>>>>>> Stashed changes + static const DeviceCommandId_t TC_MEM_WRITE = 0x1; + static const DeviceCommandId_t TC_MEM_READ = 0x2; + static const DeviceCommandId_t ACK_REPORT = 0x3; + static const DeviceCommandId_t EXE_REPORT = 0x5; + static const DeviceCommandId_t TM_MEMORY_READ_REPORT = 0x6; static const uint16_t SIZE_ACK_REPORT = 14; static const uint16_t SIZE_EXE_REPORT = 14; static const uint16_t SIZE_TM_MEM_READ_REPORT = 18; - /** Reply comprises one ack report, the telemetry packet and the execution report */ - static const uint16_t SIZE_TC_MEM_READ_REPLY = 49; - /** * SpacePacket apids of PLOC telecommands and telemetry. */ static const uint16_t APID_TC_MEM_WRITE = 0x714; static const uint16_t APID_TC_MEM_READ = 0x715; - static const uint16_t APID_TM_READ_REPORT = 0x404; + static const uint16_t APID_TM_MEMORY_READ_REPORT = 0x404; static const uint16_t APID_ACK_SUCCESS = 0x400; static const uint16_t APID_ACK_FAILURE = 0x401; static const uint16_t APID_EXE_SUCCESS = 0x402; static const uint16_t APID_EXE_FAILURE = 0x403; + /** Offset from first byte in Space packet to first byte of data field */ + static const uint8_t DATA_FIELD_OFFSET = 6; + + /** + * The size of payload data which will be forwarded to the requesting object. e.g. PUS Service + * 8. + */ + static const uint8_t SIZE_MEM_READ_REPORT_DATA = 10; + /** * PLOC space packet length for fixed size packets. This is the size of the whole packet data * field. For the length field in the space packet this size will be substracted by one. @@ -44,7 +45,7 @@ namespace PLOC { static const uint16_t LENGTH_TC_MEM_WRITE = 12; static const uint16_t LENGTH_TC_MEM_READ = 8; - static const size_t MAX_REPLY_SIZE = SIZE_TC_MEM_READ_REPLY; + static const size_t MAX_REPLY_SIZE = SIZE_TM_MEM_READ_REPORT; static const size_t MAX_COMMAND_SIZE = 18; /**