From bd4449d7dd8d9b663597473603a1fd95fa06196c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 14 Nov 2023 11:49:13 +0100 Subject: [PATCH] Fresh Supv handler --- fsfw | 2 +- linux/payload/FreshSupvHandler.cpp | 394 +++++++++++++++++++++++++---- linux/payload/FreshSupvHandler.h | 15 +- 3 files changed, 359 insertions(+), 52 deletions(-) diff --git a/fsfw b/fsfw index d554062b..91b194d8 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit d554062b86999fd4d94ce9c3fe0341b73984d1ce +Subproject commit 91b194d8ebd79352ad358f955274d49f15dd3e6d diff --git a/linux/payload/FreshSupvHandler.cpp b/linux/payload/FreshSupvHandler.cpp index 06b2eac9..b0846dd2 100644 --- a/linux/payload/FreshSupvHandler.cpp +++ b/linux/payload/FreshSupvHandler.cpp @@ -10,6 +10,7 @@ #include "fsfw/ipc/MessageQueueIF.h" #include "fsfw/ipc/QueueFactory.h" #include "fsfw/returnvalues/returnvalue.h" +#include "linux/payload/plocSupvDefs.h" using namespace supv; using namespace returnvalue; @@ -77,7 +78,7 @@ void FreshSupvHandler::performDeviceOperation(uint8_t opCode) { hkRequestCmdInfo.cmdCountdown.resetTimer(); hkRequestCmdInfo.ackExeRecv = false; hkRequestCmdInfo.ackRecv = false; - sendEmptyCmd(Apid::HK, static_cast(tc::HkId::GET_REPORT)); + sendEmptyCmd(Apid::HK, static_cast(tc::HkId::GET_REPORT), true); } } } @@ -245,19 +246,19 @@ ReturnValue_t FreshSupvHandler::executeAction(ActionId_t actionId, MessageQueueI spParams.buf = commandBuffer.data(); switch (actionId) { case GET_HK_REPORT: { - sendEmptyCmd(Apid::HK, static_cast(tc::HkId::GET_REPORT)); + sendEmptyCmd(Apid::HK, static_cast(tc::HkId::GET_REPORT), true); result = returnvalue::OK; break; } case START_MPSOC: { sif::info << "PLOC SUPV: Starting MPSoC" << std::endl; - sendEmptyCmd(Apid::BOOT_MAN, static_cast(tc::BootManId::START_MPSOC)); + sendEmptyCmd(Apid::BOOT_MAN, static_cast(tc::BootManId::START_MPSOC), false); result = returnvalue::OK; break; } case SHUTDOWN_MPSOC: { sif::info << "PLOC SUPV: Shutting down MPSoC" << std::endl; - sendEmptyCmd(Apid::BOOT_MAN, static_cast(tc::BootManId::SHUTDOWN_MPSOC)); + sendEmptyCmd(Apid::BOOT_MAN, static_cast(tc::BootManId::SHUTDOWN_MPSOC), false); result = returnvalue::OK; break; } @@ -268,7 +269,7 @@ ReturnValue_t FreshSupvHandler::executeAction(ActionId_t actionId, MessageQueueI } case RESET_MPSOC: { sif::info << "PLOC SUPV: Resetting MPSoC" << std::endl; - sendEmptyCmd(Apid::BOOT_MAN, static_cast(tc::BootManId::RESET_MPSOC)); + sendEmptyCmd(Apid::BOOT_MAN, static_cast(tc::BootManId::RESET_MPSOC), false); result = returnvalue::OK; break; } @@ -292,7 +293,8 @@ ReturnValue_t FreshSupvHandler::executeAction(ActionId_t actionId, MessageQueueI break; } case GET_BOOT_STATUS_REPORT: { - sendEmptyCmd(Apid::BOOT_MAN, static_cast(tc::BootManId::GET_BOOT_STATUS_REPORT)); + sendEmptyCmd(Apid::BOOT_MAN, static_cast(tc::BootManId::GET_BOOT_STATUS_REPORT), + true); result = returnvalue::OK; break; } @@ -309,7 +311,8 @@ ReturnValue_t FreshSupvHandler::executeAction(ActionId_t actionId, MessageQueueI break; } case GET_LATCHUP_STATUS_REPORT: { - sendEmptyCmd(Apid::LATCHUP_MON, static_cast(tc::LatchupMonId::GET_STATUS_REPORT)); + sendEmptyCmd(Apid::LATCHUP_MON, static_cast(tc::LatchupMonId::GET_STATUS_REPORT), + true); result = returnvalue::OK; break; } @@ -331,12 +334,12 @@ ReturnValue_t FreshSupvHandler::executeAction(ActionId_t actionId, MessageQueueI break; } case FACTORY_FLASH: { - sendEmptyCmd(Apid::BOOT_MAN, static_cast(tc::BootManId::FACTORY_FLASH)); + sendEmptyCmd(Apid::BOOT_MAN, static_cast(tc::BootManId::FACTORY_FLASH), false); result = returnvalue::OK; break; } case RESET_PL: { - sendEmptyCmd(Apid::BOOT_MAN, static_cast(tc::BootManId::RESET_PL)); + sendEmptyCmd(Apid::BOOT_MAN, static_cast(tc::BootManId::RESET_PL), false); result = returnvalue::OK; break; } @@ -360,13 +363,13 @@ ReturnValue_t FreshSupvHandler::executeAction(ActionId_t actionId, MessageQueueI break; } case REQUEST_ADC_REPORT: { - sendEmptyCmd(Apid::ADC_MON, static_cast(tc::AdcMonId::REQUEST_ADC_SAMPLE)); + sendEmptyCmd(Apid::ADC_MON, static_cast(tc::AdcMonId::REQUEST_ADC_SAMPLE), true); result = returnvalue::OK; break; } case REQUEST_LOGGING_COUNTERS: { sendEmptyCmd(Apid::DATA_LOGGER, - static_cast(tc::DataLoggerServiceId::REQUEST_COUNTERS)); + static_cast(tc::DataLoggerServiceId::REQUEST_COUNTERS), true); result = returnvalue::OK; break; } @@ -392,7 +395,7 @@ ReturnValue_t FreshSupvHandler::prepareSetTimeRefCmd() { if (result != returnvalue::OK) { return result; } - sendCommand(packet); + sendCommand(packet, false); return returnvalue::OK; } @@ -427,7 +430,7 @@ ReturnValue_t FreshSupvHandler::prepareSelBootImageCmd(const uint8_t* commandDat if (result != returnvalue::OK) { return result; } - sendCommand(packet); + sendCommand(packet, false); return returnvalue::OK; } @@ -453,17 +456,21 @@ void FreshSupvHandler::handleTransitionToOn() { bootTimeout.resetTimer(); startupState = StartupState::POWER_SWITCHING; switchIF.sendSwitchCommand(switchId, PowerSwitchIF::SWITCH_ON); - } else { - if (modeHelper.isTimedOut()) { - targetMode = MODE_OFF; - shutdownState = ShutdownState::IDLE; - handleTransitionToOff(); - return; - } + switchTimeout.resetTimer(); + } else if (modeHelper.isTimedOut()) { + targetMode = MODE_OFF; + shutdownState = ShutdownState::IDLE; + handleTransitionToOff(); + return; } if (startupState == StartupState::POWER_SWITCHING) { if (switchIF.getSwitchState(switchId) == PowerSwitchIF::SWITCH_ON) { startupState = StartupState::BOOTING; + } else if (switchTimeout.hasTimedOut()) { + targetMode = MODE_OFF; + shutdownState = ShutdownState::IDLE; + handleTransitionToOff(); + return; } } if (startupState == StartupState::BOOTING) { @@ -505,7 +512,8 @@ void FreshSupvHandler::handleTransitionToOff() { } } -ReturnValue_t FreshSupvHandler::sendCommand(TcBase& tc, uint32_t cmdCountdownMs) { +ReturnValue_t FreshSupvHandler::sendCommand(TcBase& tc, bool replyExpected, + uint32_t cmdCountdownMs) { if (DEBUG_PLOC_SUPV) { sif::debug << "PLOC SUPV: SEND PACKET Size " << tc.getFullPacketLen() << " Module APID " << (int)tc.getModuleApid() << " Service ID " << (int)tc.getServiceId() << std::endl; @@ -523,6 +531,8 @@ ReturnValue_t FreshSupvHandler::sendCommand(TcBase& tc, uint32_t cmdCountdownMs) activeCmdIter->second.isPending = true; activeCmdIter->second.ackRecv = false; activeCmdIter->second.ackExeRecv = false; + activeCmdIter->second.replyPacketExpected = replyExpected; + activeCmdIter->second.replyPacketReceived = false; activeCmdIter->second.cmdCountdown.setTimeout(cmdCountdownMs); activeCmdIter->second.cmdCountdown.resetTimer(); } @@ -539,13 +549,13 @@ ReturnValue_t FreshSupvHandler::initialize() { return FreshDeviceHandlerBase::initialize(); } -ReturnValue_t FreshSupvHandler::sendEmptyCmd(uint16_t apid, uint8_t serviceId) { +ReturnValue_t FreshSupvHandler::sendEmptyCmd(uint16_t apid, uint8_t serviceId, bool replyExpected) { supv::NoPayloadPacket packet(spParams, apid, serviceId); ReturnValue_t result = packet.buildPacket(); if (result != returnvalue::OK) { return result; } - sendCommand(packet); + sendCommand(packet, replyExpected); return returnvalue::OK; } @@ -561,7 +571,7 @@ ReturnValue_t FreshSupvHandler::prepareSetBootTimeoutCmd(const uint8_t* commandD if (result != returnvalue::OK) { return result; } - sendCommand(packet); + sendCommand(packet, false); return returnvalue::OK; } @@ -576,7 +586,7 @@ ReturnValue_t FreshSupvHandler::prepareRestartTriesCmd(const uint8_t* commandDat if (result != returnvalue::OK) { return result; } - sendCommand(packet); + sendCommand(packet, false); return returnvalue::OK; } @@ -586,7 +596,7 @@ ReturnValue_t FreshSupvHandler::prepareDisableHk() { if (result != returnvalue::OK) { return result; } - sendCommand(packet); + sendCommand(packet, false); return returnvalue::OK; } @@ -608,7 +618,7 @@ ReturnValue_t FreshSupvHandler::prepareLatchupConfigCmd(const uint8_t* commandDa if (result != returnvalue::OK) { return result; } - sendCommand(packet); + sendCommand(packet, false); break; } case (supv::DISABLE_LATCHUP_ALERT): { @@ -617,7 +627,7 @@ ReturnValue_t FreshSupvHandler::prepareLatchupConfigCmd(const uint8_t* commandDa if (result != returnvalue::OK) { return result; } - sendCommand(packet); + sendCommand(packet, false); break; } default: { @@ -648,7 +658,7 @@ ReturnValue_t FreshSupvHandler::prepareSetAlertLimitCmd(const uint8_t* commandDa if (result != returnvalue::OK) { return result; } - sendCommand(packet); + sendCommand(packet, false); return returnvalue::OK; } @@ -673,7 +683,7 @@ ReturnValue_t FreshSupvHandler::prepareSetShutdownTimeoutCmd(const uint8_t* comm if (result != returnvalue::OK) { return result; } - sendCommand(packet); + sendCommand(packet, false); return returnvalue::OK; } @@ -690,7 +700,7 @@ ReturnValue_t FreshSupvHandler::prepareSetGpioCmd(const uint8_t* commandData, if (result != returnvalue::OK) { return result; } - sendCommand(packet); + sendCommand(packet, false); return returnvalue::OK; } @@ -706,7 +716,7 @@ ReturnValue_t FreshSupvHandler::prepareReadGpioCmd(const uint8_t* commandData, if (result != returnvalue::OK) { return result; } - sendCommand(packet); + sendCommand(packet, false); return returnvalue::OK; } @@ -719,7 +729,7 @@ ReturnValue_t FreshSupvHandler::prepareFactoryResetCmd(const uint8_t* commandDat if (result != returnvalue::OK) { return result; } - sendCommand(resetCmd); + sendCommand(resetCmd, false); return returnvalue::OK; } @@ -730,7 +740,7 @@ ReturnValue_t FreshSupvHandler::prepareSetAdcEnabledChannelsCmd(const uint8_t* c if (result != returnvalue::OK) { return result; } - sendCommand(packet); + sendCommand(packet, false); return returnvalue::OK; } @@ -744,7 +754,7 @@ ReturnValue_t FreshSupvHandler::prepareSetAdcWindowAndStrideCmd(const uint8_t* c if (result != returnvalue::OK) { return result; } - sendCommand(packet); + sendCommand(packet, false); return returnvalue::OK; } @@ -756,7 +766,7 @@ ReturnValue_t FreshSupvHandler::prepareSetAdcThresholdCmd(const uint8_t* command if (result != returnvalue::OK) { return result; } - sendCommand(packet); + sendCommand(packet, false); return returnvalue::OK; } @@ -777,7 +787,7 @@ ReturnValue_t FreshSupvHandler::prepareWipeMramCmd(const uint8_t* commandData, s if (result != returnvalue::OK) { return result; } - sendCommand(packet); + sendCommand(packet, false); return returnvalue::OK; } @@ -812,8 +822,8 @@ ReturnValue_t FreshSupvHandler::parseTmPackets() { } case (Apid::HK): { if (tmReader.getServiceId() == static_cast(supv::tm::HkId::REPORT)) { - // TODO: Handle HK report. - return OK; + handleHkReport(receivedData); + continue; } else if (tmReader.getServiceId() == static_cast(supv::tm::HkId::HARDFAULTS)) { handleBadApidServiceCombination(SUPV_UNINIMPLEMENTED_TM, apid, tmReader.getServiceId()); return INVALID_DATA; @@ -823,14 +833,15 @@ ReturnValue_t FreshSupvHandler::parseTmPackets() { case (Apid::BOOT_MAN): { if (tmReader.getServiceId() == static_cast(supv::tm::BootManId::BOOT_STATUS_REPORT)) { - // TODO: Handle boot status report. + handleBootStatusReport(receivedData); continue; } break; } case (Apid::ADC_MON): { if (tmReader.getServiceId() == static_cast(supv::tm::AdcMonId::ADC_REPORT)) { - // TODO: Handle ADC report. + genericHandleTm("ADC", receivedData, adcReport, supv::Apid::ADC_MON, + static_cast(supv::tc::AdcMonId::REQUEST_ADC_SAMPLE)); continue; } break; @@ -838,7 +849,10 @@ ReturnValue_t FreshSupvHandler::parseTmPackets() { case (Apid::MEM_MAN): { if (tmReader.getServiceId() == static_cast(supv::tm::MemManId::UPDATE_STATUS_REPORT)) { - // TODO: Handle update status report. + sif::warning << "FreshSupvHandler: Update status report parsing not implemented" + << std::endl; + // confirmReplyPacketReceived(supv::Apid::MEM_MAN, + // supv::tc::MemManId::UPDATE_STATUS_REPORT); continue; } break; @@ -846,7 +860,8 @@ ReturnValue_t FreshSupvHandler::parseTmPackets() { case (Apid::DATA_LOGGER): { if (tmReader.getServiceId() == static_cast(supv::tm::DataLoggerId::COUNTERS_REPORT)) { - // TODO: Handle counters report. + genericHandleTm("COUNTERS", receivedData, countersReport, supv::Apid::DATA_LOGGER, + static_cast(supv::tc::DataLoggerServiceId::REQUEST_COUNTERS)); continue; } } @@ -1100,11 +1115,16 @@ ReturnValue_t FreshSupvHandler::handleAckReport(const uint8_t* data) { return returnvalue::OK; } info.ackRecv = true; - if (info.ackRecv and info.ackExeRecv) { + performCommandCompletionHandling(info); + return result; +} + +void FreshSupvHandler::performCommandCompletionHandling(ActiveCmdInfo& info) { + if (info.ackRecv and info.ackExeRecv and + (not info.replyPacketExpected or info.replyPacketReceived)) { actionHelper.finish(true, info.commandedBy, info.commandId, returnvalue::OK); info.isPending = false; } - return result; } void FreshSupvHandler::printAckFailureInfo(uint16_t statusCode, DeviceCommandId_t commandId) { @@ -1150,10 +1170,7 @@ ReturnValue_t FreshSupvHandler::handleExecutionReport(const uint8_t* data) { return returnvalue::OK; } info.ackExeRecv = true; - if (info.ackRecv and info.ackExeRecv) { - actionHelper.finish(true, info.commandedBy, info.commandId, returnvalue::OK); - info.isPending = false; - } + performCommandCompletionHandling(info); return result; } @@ -1205,3 +1222,282 @@ void FreshSupvHandler::handleExecutionFailureReport(ActiveCmdInfo& info, Executi } info.isPending = false; } + +void FreshSupvHandler::confirmReplyPacketReceived(supv::Apid apid, uint8_t serviceId) { + auto infoIter = activeActionCmds.find( + buildActiveCmdKey(supv::Apid::HK, static_cast(supv::tc::HkId::GET_REPORT))); + if (infoIter != activeActionCmds.end()) { + ActiveCmdInfo& info = infoIter->second; + info.replyPacketReceived = true; + performCommandCompletionHandling(info); + } +} + +ReturnValue_t FreshSupvHandler::handleHkReport(const uint8_t* data) { + ReturnValue_t result = returnvalue::OK; + + result = verifyPacket(data, tmReader.getFullPacketLen()); + + if (result == result::CRC_FAILURE) { + sif::error << "PlocSupervisorHandler::handleHkReport: Hk report has invalid crc" << std::endl; + return result; + } + + uint16_t offset = supv::PAYLOAD_OFFSET; + hkSet.tempPs = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8 | + *(data + offset + 3); + offset += 4; + hkSet.tempPl = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8 | + *(data + offset + 3); + offset += 4; + hkSet.tempSup = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8 | + *(data + offset + 3); + offset += 4; + size_t size = sizeof(hkSet.uptime.value); + result = SerializeAdapter::deSerialize(&hkSet.uptime, data + offset, &size, + SerializeIF::Endianness::BIG); + offset += 8; + hkSet.cpuLoad = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8 | + *(data + offset + 3); + offset += 4; + hkSet.availableHeap = *(data + offset) << 24 | *(data + offset + 1) << 16 | + *(data + offset + 2) << 8 | *(data + offset + 3); + offset += 4; + hkSet.numTcs = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8 | + *(data + offset + 3); + offset += 4; + hkSet.numTms = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8 | + *(data + offset + 3); + offset += 4; + hkSet.socState = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8 | + *(data + offset + 3); + offset += 4; + hkSet.nvm0_1_state = *(data + offset); + offset += 1; + hkSet.nvm3_state = *(data + offset); + offset += 1; + hkSet.missionIoState = *(data + offset); + offset += 1; + hkSet.fmcState = *(data + offset); + offset += 1; + + hkSet.setValidity(true, true); + confirmReplyPacketReceived(supv::Apid::HK, static_cast(supv::tc::HkId::GET_REPORT)); + +#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PLOC_SUPERVISOR == 1 + sif::info << "PlocSupervisorHandler::handleHkReport: temp_ps: " << hkSet.tempPs << std::endl; + sif::info << "PlocSupervisorHandler::handleHkReport: temp_pl: " << hkSet.tempPl << std::endl; + sif::info << "PlocSupervisorHandler::handleHkReport: temp_sup: " << hkSet.tempSup << std::endl; + sif::info << "PlocSupervisorHandler::handleHkReport: uptime: " << hkSet.uptime << std::endl; + sif::info << "PlocSupervisorHandler::handleHkReport: cpu_load: " << hkSet.cpuLoad << std::endl; + sif::info << "PlocSupervisorHandler::handleHkReport: available_heap: " << hkSet.availableHeap + << std::endl; + sif::info << "PlocSupervisorHandler::handleHkReport: num_tcs: " << hkSet.numTcs << std::endl; + sif::info << "PlocSupervisorHandler::handleHkReport: num_tms: " << hkSet.numTms << std::endl; + sif::info << "PlocSupervisorHandler::handleHkReport: soc_state: " << hkSet.socState << std::endl; + sif::info << "PlocSupervisorHandler::handleHkReport: nvm0_1_state: " + << static_cast(hkSet.nvm0_1_state.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleHkReport: nvm3_state: " + << static_cast(hkSet.nvm3_state.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleHkReport: mission_io_state: " + << static_cast(hkSet.missionIoState.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleHkReport: fmc_state: " + << static_cast(hkSet.fmcState.value) << std::endl; + +#endif + + return result; +} + +ReturnValue_t FreshSupvHandler::verifyPacket(const uint8_t* start, size_t foundLen) { + if (CRC::crc16ccitt(start, foundLen) != 0) { + return result::CRC_FAILURE; + } + return returnvalue::OK; +} + +ReturnValue_t FreshSupvHandler::handleBootStatusReport(const uint8_t* data) { + ReturnValue_t result = returnvalue::OK; + + result = verifyPacket(data, tmReader.getFullPacketLen()); + + if (result == result::CRC_FAILURE) { + sif::error << "PlocSupervisorHandler::handleBootStatusReport: Boot status report has invalid" + " crc" + << std::endl; + return result; + } + + const uint8_t* payloadStart = tmReader.getPayloadStart(); + uint16_t offset = 0; + bootStatusReport.socState = payloadStart[0]; + offset += 1; + bootStatusReport.powerCycles = payloadStart[1]; + offset += 1; + bootStatusReport.bootAfterMs = *(payloadStart + offset) << 24 | + *(payloadStart + offset + 1) << 16 | + *(payloadStart + offset + 2) << 8 | *(payloadStart + offset + 3); + offset += 4; + bootStatusReport.bootTimeoutMs = *(payloadStart + offset) << 24 | + *(payloadStart + offset + 1) << 16 | + *(payloadStart + offset + 2) << 8 | *(payloadStart + offset + 3); + offset += 4; + bootStatusReport.activeNvm = *(payloadStart + offset); + offset += 1; + bootStatusReport.bp0State = *(payloadStart + offset); + offset += 1; + bootStatusReport.bp1State = *(payloadStart + offset); + offset += 1; + bootStatusReport.bp2State = *(payloadStart + offset); + offset += 1; + bootStatusReport.bootState = *(payloadStart + offset); + offset += 1; + bootStatusReport.bootCycles = *(payloadStart + offset); + + bootStatusReport.setValidity(true, true); + confirmReplyPacketReceived(supv::Apid::BOOT_MAN, + static_cast(supv::tc::BootManId::GET_BOOT_STATUS_REPORT)); + +#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PLOC_SUPERVISOR == 1 + sif::info << "PlocSupervisorHandler::handleBootStatusReport: SoC State (0 - off, 1 - booting, 2 " + "- Update, 3 " + "- operating, 4 - Shutdown, 5 - Reset): " + << static_cast(bootStatusReport.socState.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleBootStatusReport: Power Cycles: " + << static_cast(bootStatusReport.powerCycles.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleBootStatusReport: BootAfterMs: " + << bootStatusReport.bootAfterMs << " ms" << std::endl; + sif::info << "PlocSupervisorHandler::handleBootStatusReport: BootTimeoutMs: " << std::dec + << bootStatusReport.bootTimeoutMs << " ms" << std::endl; + sif::info << "PlocSupervisorHandler::handleBootStatusReport: Active NVM: " + << static_cast(bootStatusReport.activeNvm.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleBootStatusReport: BP0: " + << static_cast(bootStatusReport.bp0State.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleBootStatusReport: BP1: " + << static_cast(bootStatusReport.bp1State.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleBootStatusReport: BP2: " + << static_cast(bootStatusReport.bp2State.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleBootStatusReport: Boot state: " + << static_cast(bootStatusReport.bootState.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleBootStatusReport: Boot cycles: " + << static_cast(bootStatusReport.bootCycles.value) << std::endl; +#endif + + return result; +} + +ReturnValue_t FreshSupvHandler::handleLatchupStatusReport(const uint8_t* data) { + ReturnValue_t result = returnvalue::OK; + + result = verifyPacket(data, tmReader.getFullPacketLen()); + + if (result == result::CRC_FAILURE) { + sif::error << "PlocSupervisorHandler::handleLatchupStatusReport: Latchup status report has " + << "invalid crc" << std::endl; + return result; + } + + const uint8_t* payloadData = tmReader.getPayloadStart(); + uint16_t offset = 0; + latchupStatusReport.id = *(payloadData + offset); + offset += 1; + latchupStatusReport.cnt0 = *(payloadData + offset) << 8 | *(payloadData + offset + 1); + offset += 2; + latchupStatusReport.cnt1 = *(payloadData + offset) << 8 | *(payloadData + offset + 1); + offset += 2; + latchupStatusReport.cnt2 = *(payloadData + offset) << 8 | *(payloadData + offset + 1); + offset += 2; + latchupStatusReport.cnt3 = *(payloadData + offset) << 8 | *(payloadData + offset + 1); + offset += 2; + latchupStatusReport.cnt4 = *(payloadData + offset) << 8 | *(payloadData + offset + 1); + offset += 2; + latchupStatusReport.cnt5 = *(payloadData + offset) << 8 | *(payloadData + offset + 1); + offset += 2; + latchupStatusReport.cnt6 = *(payloadData + offset) << 8 | *(data + offset + 1); + offset += 2; + uint16_t msec = *(payloadData + offset) << 8 | *(payloadData + offset + 1); + latchupStatusReport.isSet = msec >> supv::LatchupStatusReport::IS_SET_BIT_POS; + latchupStatusReport.timeMsec = msec & (~(1 << latchupStatusReport.IS_SET_BIT_POS)); + offset += 2; + latchupStatusReport.timeSec = *(payloadData + offset); + offset += 1; + latchupStatusReport.timeMin = *(payloadData + offset); + offset += 1; + latchupStatusReport.timeHour = *(payloadData + offset); + offset += 1; + latchupStatusReport.timeDay = *(payloadData + offset); + offset += 1; + latchupStatusReport.timeMon = *(payloadData + offset); + offset += 1; + latchupStatusReport.timeYear = *(payloadData + offset); + + latchupStatusReport.setValidity(true, true); + confirmReplyPacketReceived(supv::Apid::LATCHUP_MON, + static_cast(supv::tc::LatchupMonId::GET_STATUS_REPORT)); +#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PLOC_SUPERVISOR == 1 + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Latchup ID: " + << static_cast(latchupStatusReport.id.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: CNT0: " + << latchupStatusReport.cnt0 << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: CNT1: " + << latchupStatusReport.cnt1 << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: CNT2: " + << latchupStatusReport.cnt2 << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: CNT3: " + << latchupStatusReport.cnt3 << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: CNT4: " + << latchupStatusReport.cnt4 << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: CNT5: " + << latchupStatusReport.cnt5 << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: CNT6: " + << latchupStatusReport.cnt6 << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Sec: " + << static_cast(latchupStatusReport.timeSec.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Min: " + << static_cast(latchupStatusReport.timeMin.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Hour: " + << static_cast(latchupStatusReport.timeHour.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Day: " + << static_cast(latchupStatusReport.timeDay.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Mon: " + << static_cast(latchupStatusReport.timeMon.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Year: " + << static_cast(latchupStatusReport.timeYear.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Msec: " + << static_cast(latchupStatusReport.timeMsec.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: isSet: " + << static_cast(latchupStatusReport.isSet.value) << std::endl; +#endif + + return result; +} + +ReturnValue_t FreshSupvHandler::genericHandleTm(const char* contextString, const uint8_t* data, + LocalPoolDataSetBase& set, supv::Apid apid, + uint8_t serviceId) { + ReturnValue_t result = returnvalue::OK; + + result = verifyPacket(data, tmReader.getFullPacketLen()); + + if (result == result::CRC_FAILURE) { + sif::warning << "PlocSupervisorHandler: " << contextString << " report has " + << "invalid CRC" << std::endl; + return result; + } + + const uint8_t* dataField = data + supv::PAYLOAD_OFFSET; + PoolReadGuard pg(&set); + if (pg.getReadResult() != returnvalue::OK) { + return result; + } + set.setValidityBufferGeneration(false); + size_t size = set.getSerializedSize(); + result = set.deSerialize(&dataField, &size, SerializeIF::Endianness::BIG); + if (result != returnvalue::OK) { + sif::warning << "PlocSupervisorHandler: Deserialization failed" << std::endl; + } + set.setValidityBufferGeneration(true); + set.setValidity(true, true); + confirmReplyPacketReceived(apid, serviceId); + return result; +} diff --git a/linux/payload/FreshSupvHandler.h b/linux/payload/FreshSupvHandler.h index 1296d32c..6f7d7af2 100644 --- a/linux/payload/FreshSupvHandler.h +++ b/linux/payload/FreshSupvHandler.h @@ -99,6 +99,7 @@ class FreshSupvHandler : public FreshDeviceHandlerBase { Mode_t targetMode = HasModesIF::MODE_INVALID; Submode_t targetSubmode = 0; + Countdown switchTimeout = Countdown(2000); // Vorago nees some time to boot properly Countdown bootTimeout = Countdown(supv::BOOT_TIMEOUT_MS); @@ -119,6 +120,8 @@ class FreshSupvHandler : public FreshDeviceHandlerBase { bool isPending = false; bool ackRecv = false; bool ackExeRecv = false; + bool replyPacketExpected = false; + bool replyPacketReceived = false; MessageQueueId_t commandedBy = MessageQueueIF::NO_QUEUE; bool requiresActionReply = false; Countdown cmdCountdown; @@ -137,8 +140,8 @@ class FreshSupvHandler : public FreshDeviceHandlerBase { ReturnValue_t parseTmPackets(); - ReturnValue_t sendCommand(TcBase& tc, uint32_t cmdCountdownMs = 1000); - ReturnValue_t sendEmptyCmd(uint16_t apid, uint8_t serviceId); + ReturnValue_t sendCommand(TcBase& tc, bool replyPacketExpected, uint32_t cmdCountdownMs = 1000); + ReturnValue_t sendEmptyCmd(uint16_t apid, uint8_t serviceId, bool replyPacketExpected); ReturnValue_t prepareSelBootImageCmd(const uint8_t* commandData); ReturnValue_t prepareSetTimeRefCmd(); ReturnValue_t prepareSetBootTimeoutCmd(const uint8_t* commandData, size_t cmdDataLen); @@ -170,6 +173,14 @@ class FreshSupvHandler : public FreshDeviceHandlerBase { ReturnValue_t handleExecutionReport(const uint8_t* data); ReturnValue_t handleExecutionSuccessReport(ActiveCmdInfo& info, supv::ExecutionReport& report); void handleExecutionFailureReport(ActiveCmdInfo& info, supv::ExecutionReport& report); + ReturnValue_t handleHkReport(const uint8_t* data); + ReturnValue_t verifyPacket(const uint8_t* start, size_t foundLen); + void confirmReplyPacketReceived(supv::Apid apid, uint8_t serviceId); + void performCommandCompletionHandling(ActiveCmdInfo& info); + ReturnValue_t handleBootStatusReport(const uint8_t* data); + ReturnValue_t genericHandleTm(const char* contextString, const uint8_t* data, + LocalPoolDataSetBase& set, supv::Apid apid, uint8_t serviceId); + ReturnValue_t handleLatchupStatusReport(const uint8_t* data); }; #endif /* LINUX_PAYLOAD_FRESHSUPVHANDLER_H_ */