From f5f8df61ae2990f8a00e56e8066dcbf6deadeef3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 Aug 2021 11:27:08 +0200 Subject: [PATCH 1/9] bumped subversion --- bsp_q7s/core/obsw.cpp | 2 +- common/config/OBSWVersion.h | 2 +- fsfw | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bsp_q7s/core/obsw.cpp b/bsp_q7s/core/obsw.cpp index 47b7b9d2..e55d5652 100644 --- a/bsp_q7s/core/obsw.cpp +++ b/bsp_q7s/core/obsw.cpp @@ -19,7 +19,7 @@ int obsw::obsw() { #else std::cout << "-- Compiled for Linux (TE0720) --" << std::endl; #endif - std::cout << "-- OBSW " << SW_NAME << " v" << SW_VERSION << "." << SW_SUBVERSION << + std::cout << "-- OBSW v" << SW_VERSION << "." << SW_SUBVERSION << "." << SW_REVISION << ", FSFW v" << FSFW_VERSION << "." << FSFW_SUBVERSION << "." << FSFW_REVISION << "--" << std::endl; std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl; diff --git a/common/config/OBSWVersion.h b/common/config/OBSWVersion.h index 0274b91f..db7cfeb5 100644 --- a/common/config/OBSWVersion.h +++ b/common/config/OBSWVersion.h @@ -4,7 +4,7 @@ const char* const SW_NAME = "eive"; #define SW_VERSION 1 -#define SW_SUBVERSION 5 +#define SW_SUBVERSION 6 #define SW_REVISION 0 #endif /* COMMON_CONFIG_OBSWVERSION_H_ */ diff --git a/fsfw b/fsfw index 3704d2b8..22e29144 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 3704d2b8295152652a4c7836b595223d8fa3767d +Subproject commit 22e29144b6783a824b310204c76fa413eb94f331 From 74dbfae2256d656b6cd46f07c6b9ada68bbab985 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 Aug 2021 14:30:14 +0200 Subject: [PATCH 2/9] tmtc update --- tmtc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmtc b/tmtc index 3e8626bf..3305e1d4 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 3e8626bfafa561510323bf8fe3963bc2860950ed +Subproject commit 3305e1d489c7d3ce401945712a4f374e068175ff From cd7bc466ae7a825fdfb29ce1385752e0a9695437 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 Aug 2021 15:53:48 +0200 Subject: [PATCH 3/9] tmtc update --- tmtc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmtc b/tmtc index 3305e1d4..cc6dbd8e 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 3305e1d489c7d3ce401945712a4f374e068175ff +Subproject commit cc6dbd8ef9d5bd028835f37a24a5617224569862 From 1d714ff85eb0e50e224574245e8d5202d77af8e7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 Aug 2021 16:30:59 +0200 Subject: [PATCH 4/9] Moved PLOC components to q7s folder --- bsp_hosted/CMakeLists.txt | 2 - bsp_hosted/ObjectFactory.cpp | 4 +- bsp_q7s/CMakeLists.txt | 1 + bsp_q7s/core/CoreController.cpp | 4 +- bsp_q7s/core/ObjectFactory.cpp | 3 +- bsp_q7s/devices/CMakeLists.txt | 4 + .../devices/PlocSupervisorHandler.cpp | 0 .../devices/PlocSupervisorHandler.h | 0 bsp_q7s/devices/PlocUpdater.cpp | 397 ++++++++++++++++++ bsp_q7s/devices/PlocUpdater.h | 171 ++++++++ common/config/commonClassIds.h | 2 + fsfw | 2 +- linux/fsfwconfig/returnvalues/classIds.h | 1 - mission/devices/CMakeLists.txt | 1 - tmtc | 2 +- 15 files changed, 583 insertions(+), 11 deletions(-) create mode 100644 bsp_q7s/devices/CMakeLists.txt rename {mission => bsp_q7s}/devices/PlocSupervisorHandler.cpp (100%) rename {mission => bsp_q7s}/devices/PlocSupervisorHandler.h (100%) create mode 100644 bsp_q7s/devices/PlocUpdater.cpp create mode 100644 bsp_q7s/devices/PlocUpdater.h diff --git a/bsp_hosted/CMakeLists.txt b/bsp_hosted/CMakeLists.txt index 7171d9d7..b8a09a88 100644 --- a/bsp_hosted/CMakeLists.txt +++ b/bsp_hosted/CMakeLists.txt @@ -6,5 +6,3 @@ target_sources(${TARGET_NAME} PUBLIC add_subdirectory(fsfwconfig) add_subdirectory(boardconfig) - - diff --git a/bsp_hosted/ObjectFactory.cpp b/bsp_hosted/ObjectFactory.cpp index 9ea97fd1..2c431fb8 100644 --- a/bsp_hosted/ObjectFactory.cpp +++ b/bsp_hosted/ObjectFactory.cpp @@ -46,12 +46,12 @@ void ObjectFactory::produce(void* args){ #if OBSW_USE_TMTC_TCP_BRIDGE == 0 sif::info << "Setting up UDP TMTC bridge with listener port " << - UdpTmTcBridge::DEFAULT_SERVER_PORT << std::endl; + UdpTmTcBridge::DEFAULT_UDP_SERVER_PORT << std::endl; new UdpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); new UdpTcPollingTask(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); #else sif::info << "Setting up TCP TMTC bridge with listener port " << - TcpTmTcBridge::DEFAULT_SERVER_PORT << std::endl; + TcpTmTcBridge::DEFAULT_TCP_SERVER_PORT << std::endl; new TcpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); new TcpTmTcServer(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); #endif diff --git a/bsp_q7s/CMakeLists.txt b/bsp_q7s/CMakeLists.txt index 3bc9aa4e..408d58c1 100644 --- a/bsp_q7s/CMakeLists.txt +++ b/bsp_q7s/CMakeLists.txt @@ -13,4 +13,5 @@ else() add_subdirectory(core) add_subdirectory(memory) add_subdirectory(spiCallbacks) + add_subdirectory(devices) endif() diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 606646bf..2b16dd3c 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -782,10 +782,10 @@ void CoreController::initPrint() { #if OBSW_VERBOSE_LEVEL >= 1 #if OBSW_USE_TMTC_TCP_BRIDGE == 0 sif::info << "Created UDP server for TMTC commanding with listener port " << - UdpTmTcBridge::DEFAULT_SERVER_PORT << std::endl; + UdpTmTcBridge::DEFAULT_UDP_SERVER_PORT << std::endl; #else sif::info << "Created TCP server for TMTC commanding with listener port " << - TcpTmTcBridge::DEFAULT_SERVER_PORT << std::endl; + TcpTmTcBridge::DEFAULT_TCP_SERVER_PORT << std::endl; #endif if(watchdogFifoFd > 0) { diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index a5e045cb..f57b3fc9 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -12,6 +12,8 @@ #include "bsp_q7s/spiCallbacks/rwSpiCallback.h" #include "bsp_q7s/boardtest/Q7STestTask.h" #include "bsp_q7s/memory/FileSystemHandler.h" +#include "bsp_q7s/devices/PlocSupervisorHandler.h" +#include "bsp_q7s/devices/PlocUpdater.h" #include "linux/devices/HeaterHandler.h" #include "linux/devices/SolarArrayDeploymentHandler.h" @@ -33,7 +35,6 @@ #include "mission/devices/MGMHandlerLIS3MDL.h" #include "mission/devices/MGMHandlerRM3100.h" #include "mission/devices/PlocMPSoCHandler.h" -#include "mission/devices/PlocSupervisorHandler.h" #include "mission/devices/RadiationSensorHandler.h" #include "mission/devices/RwHandler.h" #include "mission/devices/StarTrackerHandler.h" diff --git a/bsp_q7s/devices/CMakeLists.txt b/bsp_q7s/devices/CMakeLists.txt new file mode 100644 index 00000000..80e1b1e5 --- /dev/null +++ b/bsp_q7s/devices/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources(${TARGET_NAME} PRIVATE + PlocSupervisorHandler.cpp + PlocUpdater.cpp +) \ No newline at end of file diff --git a/mission/devices/PlocSupervisorHandler.cpp b/bsp_q7s/devices/PlocSupervisorHandler.cpp similarity index 100% rename from mission/devices/PlocSupervisorHandler.cpp rename to bsp_q7s/devices/PlocSupervisorHandler.cpp diff --git a/mission/devices/PlocSupervisorHandler.h b/bsp_q7s/devices/PlocSupervisorHandler.h similarity index 100% rename from mission/devices/PlocSupervisorHandler.h rename to bsp_q7s/devices/PlocSupervisorHandler.h diff --git a/bsp_q7s/devices/PlocUpdater.cpp b/bsp_q7s/devices/PlocUpdater.cpp new file mode 100644 index 00000000..4a6085a2 --- /dev/null +++ b/bsp_q7s/devices/PlocUpdater.cpp @@ -0,0 +1,397 @@ +#include "fsfw/ipc/QueueFactory.h" +#include "PlocUpdater.h" + +#include +#include +#include + +PlocUpdater::PlocUpdater(object_id_t objectId) : + SystemObject(objectId), commandActionHelper(this), actionHelper(this, nullptr) { + commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE); +} + +PlocUpdater::~PlocUpdater() { +} + +ReturnValue_t PlocUpdater::initialize() { + sdcMan = SdCardManager::instance(); + + ReturnValue_t result = SystemObject::initialize(); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = commandActionHelper.initialize(); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = actionHelper.initialize(commandQueue); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t PlocUpdater::performOperation(uint8_t operationCode) { + readCommandQueue(); + doStateMachine(); + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t PlocUpdater::executeAction(ActionId_t actionId, + MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { + ReturnValue_t result = RETURN_FAILED; + + if (state != State::IDLE) { + return IS_BUSY; + } + + if (size > MAX_PLOC_UPDATE_PATH) { + return NAME_TOO_LONG; + } + + switch (actionId) { + case UPDATE_NVM0_A: + updatePartition = Partition::A; + updateMemory = Memory::NVM0; + break; + case UPDATE_NVM0_B: + updatePartition = Partition::B; + updateMemory = Memory::NVM0; + break; + case UPDATE_NVM1_A: + updatePartition = Partition::A; + updateMemory = Memory::NVM1; + break; + case UPDATE_NVM1_B: + updatePartition = Partition::B; + updateMemory = Memory::NVM1; + break; + default: + return INVALID_ACTION_ID; + } + + result = getImageLocation(data, size); + + if (result != RETURN_OK) { + return result; + } + + state = State::UPDATE_AVAILABLE; + + return EXECUTION_FINISHED; +} + +MessageQueueId_t PlocUpdater::getCommandQueue() const { + return commandQueue->getId(); +} + +MessageQueueIF* PlocUpdater::getCommandQueuePtr() { + return commandQueue; +} + +void PlocUpdater::readCommandQueue() { + CommandMessage message; + ReturnValue_t result; + + for (result = commandQueue->receiveMessage(&message); result == HasReturnvaluesIF::RETURN_OK; + result = commandQueue->receiveMessage(&message)) { + if (result != RETURN_OK) { + continue; + } + result = actionHelper.handleActionMessage(&message); + if (result == HasReturnvaluesIF::RETURN_OK) { + continue; + } + + result = commandActionHelper.handleReply(&message); + if (result == HasReturnvaluesIF::RETURN_OK) { + continue; + } + + sif::debug << "PlocUpdater::readCommandQueue: Received message with invalid format" + << std::endl; + } +} + +void PlocUpdater::doStateMachine() { + switch (state) { + case State::IDLE: + break; + case State::UPDATE_AVAILABLE: + commandUpdateAvailable(); + break; + case State::UPDATE_TRANSFER: + commandUpdatePacket(); + break; + case State::UPDATE_VERIFY: + commandUpdateVerify(); + break; + case State::COMMAND_EXECUTING: + break; + default: + sif::debug << "PlocUpdater::doStateMachine: Invalid state" << std::endl; + break; + } +} + +ReturnValue_t PlocUpdater::checkNameLength(size_t size) { + if (size > MAX_PLOC_UPDATE_PATH) { + return NAME_TOO_LONG; + } + return RETURN_OK; +} + +ReturnValue_t PlocUpdater::getImageLocation(const uint8_t* data, size_t size) { + ReturnValue_t result = checkNameLength(size); + if (result != RETURN_OK) { + return result; + } + + // Check if file is stored on SD card and if associated SD card is mounted + if (std::string(reinterpret_cast(data), SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_0_MOUNT_POINT)) { + if (!isSdCardMounted(sd::SLOT_0)) { + sif::warning << "PlocUpdater::prepareNvm0AUpdate: SD card 0 not mounted" << std::endl; + return SD_NOT_MOUNTED; + } + } + else if (std::string(reinterpret_cast(data), SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_1_MOUNT_POINT)) { + if (!isSdCardMounted(sd::SLOT_0)) { + sif::warning << "PlocUpdater::prepareNvm0AUpdate: SD card 1 not mounted" << std::endl; + return SD_NOT_MOUNTED; + } + } + else { + //update image not stored on SD card + } + + updateFile = std::string(reinterpret_cast(data), size); + + // Check if file exists + if(not std::filesystem::exists(updateFile)) { + return FILE_NOT_EXISTS; + } + return RETURN_OK; +} + +bool PlocUpdater::isSdCardMounted(sd::SdCard sdCard) { + SdCardManager::SdStatePair active; + ReturnValue_t result = sdcMan->getSdCardActiveStatus(active); + if (result != RETURN_OK) { + sif::debug << "PlocUpdater::isSdCardMounted: Failed to get SD card active state"; + return false; + } + if (sdCard == sd::SLOT_0) { + if (active.first == sd::MOUNTED) { + return true; + } + else { + return false; + } + } + else if (sdCard == sd::SLOT_1) { + if (active.second == sd::MOUNTED) { + return true; + } + else { + return false; + } + } + else { + sif::debug << "PlocUpdater::isSdCardMounted: Unknown SD card specified" << std::endl; + } + return false; +} + +void PlocUpdater::stepSuccessfulReceived(ActionId_t actionId, + uint8_t step) { +} + +void PlocUpdater::stepFailedReceived(ActionId_t actionId, uint8_t step, + ReturnValue_t returnCode) { +} + +void PlocUpdater::dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) { + +} + +void PlocUpdater::completionSuccessfulReceived(ActionId_t actionId) { + switch (pendingCommand) { + case (PLOC_SPV::UPDATE_AVAILABLE): + state = State::UPDATE_TRANSFER; + break; + case (PLOC_SPV::UPDATE_IMAGE_DATA): + if (remainingPackets == 0) { + packetsSent = 0; // Reset packets sent variable for next update sequence + state = State::UPDATE_VERIFY; + } + else { + state = State::UPDATE_TRANSFER; + } + break; + case (PLOC_SPV::UPDATE_VERIFY): + triggerEvent(UPDATE_FINISHED); + state = State::IDLE; + pendingCommand = PLOC_SPV::NONE; + break; + default: + sif::debug << "PlocUpdater::completionSuccessfulReceived: Invalid pending command" + << std::endl; + state = State::IDLE; + break; + } +} + +void PlocUpdater::completionFailedReceived(ActionId_t actionId, + ReturnValue_t returnCode) { + switch(pendingCommand) { + case(PLOC_SPV::UPDATE_AVAILABLE): { + triggerEvent(UPDATE_AVAILABLE_FAILED); + break; + } + case(PLOC_SPV::UPDATE_IMAGE_DATA): { + triggerEvent(UPDATE_TRANSFER_FAILED, packetsSent); + break; + } + case(PLOC_SPV::UPDATE_VERIFY): { + triggerEvent(UPDATE_VERIFY_FAILED); + break; + } + default: + sif::debug << "PlocUpdater::completionFailedReceived: Invalid pending command " + << std::endl; + break; + } + state = State::IDLE; +} + +void PlocUpdater::commandUpdateAvailable() { + ReturnValue_t result = RETURN_OK; + + if (not std::filesystem::exists(updateFile)) { + triggerEvent(UPDATE_FILE_NOT_EXISTS, static_cast(state)); + state = State::IDLE; + return; + } + + std::ifstream file(updateFile, std::ifstream::binary); + file.seekg(0, file.end); + imageSize = static_cast(file.tellg()); + file.close(); + + numOfUpdatePackets = imageSize / MAX_SP_DATA ; + if (imageSize % MAX_SP_DATA) { + numOfUpdatePackets++; + } + + remainingPackets = numOfUpdatePackets; + packetsSent = 0; + + uint32_t imageCrc = makeCrc(); + + PLOC_SPV::UpdateInfo packet(PLOC_SPV::APID_UPDATE_AVAILABLE, static_cast(updateMemory), + static_cast(updatePartition), imageSize, imageCrc, numOfUpdatePackets); + + result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER, + PLOC_SPV::UPDATE_AVAILABLE, packet.getWholeData(), packet.getFullSize()); + if (result != RETURN_OK) { + sif::warning << "PlocUpdater::commandUpdateAvailable: Failed to send update available" + << " packet to supervisor handler" << std::endl; + triggerEvent(ACTION_COMMANDING_FAILED, result, PLOC_SPV::UPDATE_AVAILABLE); + state = State::IDLE; + pendingCommand = PLOC_SPV::NONE; + return; + } + + pendingCommand = PLOC_SPV::UPDATE_AVAILABLE; + state = State::COMMAND_EXECUTING; + return; +} + +void PlocUpdater::commandUpdatePacket() { + ReturnValue_t result = RETURN_OK; + uint16_t payloadLength = 0; + + if (not std::filesystem::exists(updateFile)) { + triggerEvent(UPDATE_FILE_NOT_EXISTS, static_cast(state), packetsSent); + state = State::IDLE; + return; + } + + std::ifstream file(updateFile, std::ifstream::binary); + file.seekg(packetsSent * MAX_SP_DATA, file.beg); + + if (remainingPackets == 1) { + payloadLength = imageSize - static_cast(file.tellg()); + } + else { + payloadLength = MAX_SP_DATA; + } + + PLOC_SPV::UpdatePacket packet(payloadLength); + file.read(reinterpret_cast(packet.getDataFieldPointer()), payloadLength); + file.close(); + // sequence count of first packet is 1 + packet.setPacketSequenceCount((packetsSent + 1) & PLOC_SPV::SEQUENCE_COUNT_MASK); + if (numOfUpdatePackets > 0) { + adjustSequenceFlags(packet); + } + packet.makeCrc(); + + result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER, + PLOC_SPV::UPDATE_IMAGE_DATA, packet.getWholeData(), packet.getFullSize()); + + if (result != RETURN_OK) { + sif::warning << "PlocUpdater::commandUpdateAvailable: Failed to send update" + << " packet to supervisor handler" << std::endl; + triggerEvent(ACTION_COMMANDING_FAILED, result, PLOC_SPV::UPDATE_IMAGE_DATA); + state = State::IDLE; + pendingCommand = PLOC_SPV::NONE; + return; + } + + remainingPackets--; + packetsSent++; + + pendingCommand = PLOC_SPV::UPDATE_IMAGE_DATA; + state = State::COMMAND_EXECUTING; +} + +void PlocUpdater::commandUpdateVerify() { + ReturnValue_t result = RETURN_OK; + + PLOC_SPV::UpdateInfo packet(PLOC_SPV::APID_UPDATE_VERIFY, static_cast(updateMemory), + static_cast(updatePartition), imageSize, imageCrc, numOfUpdatePackets); + + result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER, + PLOC_SPV::UPDATE_VERIFY, packet.getWholeData(), packet.getFullSize()); + if (result != RETURN_OK) { + sif::warning << "PlocUpdater::commandUpdateAvailable: Failed to send update available" + << " packet to supervisor handler" << std::endl; + triggerEvent(ACTION_COMMANDING_FAILED, result, PLOC_SPV::UPDATE_VERIFY); + state = State::IDLE; + pendingCommand = PLOC_SPV::NONE; + return; + } + state = State::COMMAND_EXECUTING; + pendingCommand = PLOC_SPV::UPDATE_VERIFY; + return; +} + +ReturnValue_t PlocUpdater::makeCrc() { + //TODO: Waiting on input from TAS about the CRC to use + return 0; +} + +void PlocUpdater::adjustSequenceFlags(PLOC_SPV::UpdatePacket& packet) { + if (packetsSent == 0) { + packet.setSequenceFlags(static_cast(PLOC_SPV::SequenceFlags::FIRST_PKT)); + } + else if (remainingPackets == 1) { + packet.setSequenceFlags(static_cast(PLOC_SPV::SequenceFlags::LAST_PKT)); + } + else { + packet.setSequenceFlags(static_cast(PLOC_SPV::SequenceFlags::CONTINUED_PKT)); + } +} + diff --git a/bsp_q7s/devices/PlocUpdater.h b/bsp_q7s/devices/PlocUpdater.h new file mode 100644 index 00000000..eee5453a --- /dev/null +++ b/bsp_q7s/devices/PlocUpdater.h @@ -0,0 +1,171 @@ +#ifndef MISSION_DEVICES_PLOCUPDATER_H_ +#define MISSION_DEVICES_PLOCUPDATER_H_ + +#include "fsfw/action/CommandActionHelper.h" +#include "fsfw/action/ActionHelper.h" +#include "fsfw/action/HasActionsIF.h" +#include "fsfw/action/CommandsActionsIF.h" +#include "fsfw/returnvalues/HasReturnvaluesIF.h" +#include "fsfw/tasks/ExecutableObjectIF.h" +#include "fsfw/objectmanager/SystemObject.h" +#include "bsp_q7s/memory/SdCardManager.h" +#include "linux/fsfwconfig/objects/systemObjectList.h" +#include "fsfw/tmtcpacket/SpacePacket.h" +#include "OBSWConfig.h" +#include + +/** + * @brief An object of this class can be used to perform the software updates of the PLOC. The + * software update will be read from one of the SD cards, split into multiple space + * packets and sent to the PlocSupervisorHandler. + * + * @details The MPSoC has two boot memories (NVM0 and NVM1) where each stores two images (Partition A + * and Partition B) + * + * @author J. Meier + */ +class PlocUpdater : public SystemObject, + public HasActionsIF, + public ExecutableObjectIF, + public HasReturnvaluesIF, + public CommandsActionsIF { +public: + + static const ActionId_t UPDATE_NVM0_A = 0; + static const ActionId_t UPDATE_NVM0_B = 1; + static const ActionId_t UPDATE_NVM1_A = 2; + static const ActionId_t UPDATE_NVM1_B = 3; + + PlocUpdater(object_id_t objectId); + virtual ~PlocUpdater(); + + ReturnValue_t performOperation(uint8_t operationCode = 0) override; + ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, + const uint8_t* data, size_t size); + MessageQueueId_t getCommandQueue() const; + ReturnValue_t initialize() override; + MessageQueueIF* getCommandQueuePtr() override; + void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) override; + void stepFailedReceived(ActionId_t actionId, uint8_t step, ReturnValue_t returnCode) override; + void dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) override; + void completionSuccessfulReceived(ActionId_t actionId) override; + void completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) override; + +private: + + static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_UPDATER; + + //! [EXPORT] : [COMMENT] Updater is already performing an update + static const ReturnValue_t UPDATER_BUSY = MAKE_RETURN_CODE(0xA0); + //! [EXPORT] : [COMMENT] Received update command with invalid path string (too long). + static const ReturnValue_t NAME_TOO_LONG = MAKE_RETURN_CODE(0xA1); + //! [EXPORT] : [COMMENT] Received command to initiate update but SD card with update image not mounted. + static const ReturnValue_t SD_NOT_MOUNTED = MAKE_RETURN_CODE(0xA2); + //! [EXPORT] : [COMMENT] Update file received with update command does not exist. + static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xA3); + + static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_UPDATER; + + //! [EXPORT] : [COMMENT] Try to read update file but the file does not exist. + //! P1: Indicates in which state the file read fails + //! P2: During the update transfer the second parameter gives information about the number of already sent packets + static const Event UPDATE_FILE_NOT_EXISTS = MAKE_EVENT(0, severity::LOW); + //! [EXPORT] : [COMMENT] Failed to send command to supervisor handler + //! P1: Return value of CommandActionHelper::commandAction + //! P2: Action ID of command to send + static const Event ACTION_COMMANDING_FAILED = MAKE_EVENT(1, severity::LOW); + //! [EXPORT] : [COMMENT] Supervisor handler replied action message indicating a command execution failure of the update available command + static const Event UPDATE_AVAILABLE_FAILED = MAKE_EVENT(2, severity::LOW); + //! [EXPORT] : [COMMENT] Supervisor handler failed to transfer an update space packet. + //! P1: Parameter holds the number of update packets already sent (inclusive the failed packet) + static const Event UPDATE_TRANSFER_FAILED = MAKE_EVENT(3, severity::LOW); + //! [EXPORT] : [COMMENT] Supervisor failed to execute the update verify command. + static const Event UPDATE_VERIFY_FAILED = MAKE_EVENT(4, severity::LOW); + //! [EXPORT] : [COMMENT] MPSoC update successful completed + static const Event UPDATE_FINISHED = MAKE_EVENT(5, severity::INFO); + + static const uint32_t QUEUE_SIZE = config::PLOC_UPDATER_QUEUE_SIZE; + static const size_t MAX_PLOC_UPDATE_PATH = 50; + static const size_t SD_PREFIX_LENGTH = 8; + // Maximum size of update payload data per space packet (max size of space packet is 1024 bytes) + static const size_t MAX_SP_DATA = 1016; + + MessageQueueIF* commandQueue = nullptr; + + SdCardManager* sdcMan = nullptr; + + CommandActionHelper commandActionHelper; + + ActionHelper actionHelper; + + enum class State: uint8_t { + IDLE, + UPDATE_AVAILABLE, + UPDATE_TRANSFER, + UPDATE_VERIFY, + COMMAND_EXECUTING + }; + + State state = State::IDLE; + + ActionId_t pendingCommand = PLOC_SPV::NONE; + + enum class Memory: uint8_t { + NVM0, + NVM1 + }; + + Memory updateMemory = Memory::NVM0; + + enum class Partition: uint8_t { + A, + B + }; + + Partition updatePartition = Partition::A; + + uint32_t packetsSent = 0; + uint32_t remainingPackets = 0; + // Number of packets required to transfer the update image + uint32_t numOfUpdatePackets = 0; + + std::string updateFile; + uint32_t imageSize = 0; + uint32_t imageCrc = 0; + + void readCommandQueue(); + void doStateMachine(); + + /** + * @brief Extracts the path and name of the update image from the service 8 command data. + */ + ReturnValue_t getImageLocation(const uint8_t* data, size_t size); + + ReturnValue_t checkNameLength(size_t size); + + /** + * @brief Prepares and sends update available command to PLOC supervisor handler. + */ + void commandUpdateAvailable(); + + /** + * @brief Prepares and sends and update packet to the PLOC supervisor handler. + */ + void commandUpdatePacket(); + + /** + * @brief Prepares and sends the update verification packet to the PLOC supervisor handler. + */ + void commandUpdateVerify(); + + /** + * @brief Checks whether the SD card to read from is mounted or not. + */ + bool isSdCardMounted(sd::SdCard sdCard); + + ReturnValue_t makeCrc(); + + void adjustSequenceFlags(PLOC_SPV::UpdatePacket& packet); +}; + +#endif /* MISSION_DEVICES_PLOCUPDATER_H_ */ diff --git a/common/config/commonClassIds.h b/common/config/commonClassIds.h index 6a27c286..8f751df1 100644 --- a/common/config/commonClassIds.h +++ b/common/config/commonClassIds.h @@ -19,6 +19,8 @@ enum commonClassIds: uint8_t { PLOC_SUPERVISOR_HANDLER, //PLSV SUS_HANDLER, //SUSS CCSDS_IP_CORE_BRIDGE, //IPCI + PLOC_UPDATER, //PLUD + GOM_SPACE_HANDLER, //GOMS COMMON_CLASS_ID_END // [EXPORT] : [END] }; diff --git a/fsfw b/fsfw index 22e29144..5a6c8113 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 22e29144b6783a824b310204c76fa413eb94f331 +Subproject commit 5a6c81130d3a16595ccead6133a7d9b8a968e49d diff --git a/linux/fsfwconfig/returnvalues/classIds.h b/linux/fsfwconfig/returnvalues/classIds.h index e7c2ae74..b98801e2 100644 --- a/linux/fsfwconfig/returnvalues/classIds.h +++ b/linux/fsfwconfig/returnvalues/classIds.h @@ -12,7 +12,6 @@ namespace CLASS_ID { enum { CLASS_ID_START = COMMON_CLASS_ID_END, - GOM_SPACE_HANDLER, //GOMS SA_DEPL_HANDLER, //SADPL SD_CARD_MANAGER, //SDMA SCRATCH_BUFFER, //SCBU diff --git a/mission/devices/CMakeLists.txt b/mission/devices/CMakeLists.txt index 63b417e9..4ed60dfd 100644 --- a/mission/devices/CMakeLists.txt +++ b/mission/devices/CMakeLists.txt @@ -13,7 +13,6 @@ target_sources(${TARGET_NAME} PUBLIC Max31865PT1000Handler.cpp IMTQHandler.cpp PlocMPSoCHandler.cpp - PlocSupervisorHandler.cpp RadiationSensorHandler.cpp GyroADIS16507Handler.cpp RwHandler.cpp diff --git a/tmtc b/tmtc index 3e8626bf..cc6dbd8e 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 3e8626bfafa561510323bf8fe3963bc2860950ed +Subproject commit cc6dbd8ef9d5bd028835f37a24a5617224569862 From 03510e5de9a58927243780ad3425ed7e1ba725f7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 Aug 2021 16:34:06 +0200 Subject: [PATCH 5/9] updated TCP port --- README.md | 2 +- scripts/q7s-port-tcp.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a5947a93..2e2c8b96 100644 --- a/README.md +++ b/README.md @@ -262,7 +262,7 @@ This forwards UDP TMTC packets on port `1536` of localhost to the TMTC reception For TCP, you can use ```sh -ssh -L 1537:192.168.133.10:7303 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash +ssh -L 1537:192.168.133.10:7301 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash ``` This forwards TCP TMTC packets on port `1537` of localhost to the TMTC reception port of the Q7S. diff --git a/scripts/q7s-port-tcp.sh b/scripts/q7s-port-tcp.sh index 9d370670..4d0aef4a 100755 --- a/scripts/q7s-port-tcp.sh +++ b/scripts/q7s-port-tcp.sh @@ -6,6 +6,6 @@ echo "-L 1537:192.168.133.10:7303 to TMTC commanding using TCP" ssh -L 1534:192.168.133.10:1534 \ -L 1535:192.168.133.10:22 \ - -L 1537:192.168.133.10:7303 \ + -L 1537:192.168.133.10:7301 \ eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ -t 'CONSOLE_PREFIX="[Q7S Tunnel]" /bin/bash' From e92af98f34d4fa387923ba11e554ca3ddf7a641d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 Aug 2021 17:19:10 +0200 Subject: [PATCH 6/9] moved q7s specific code to q7s folder --- bsp_hosted/ObjectFactory.cpp | 2 +- bsp_q7s/core/CoreController.cpp | 6 +- bsp_q7s/core/ObjectFactory.cpp | 2 - bsp_q7s/devices/PlocSupervisorHandler.h | 7 +- bsp_q7s/devices/PlocUpdater.h | 6 +- .../PlocSupervisorDefinitions.h | 0 common/config/commonConfig.h.in | 2 +- fsfw | 2 +- mission/devices/CMakeLists.txt | 1 - mission/devices/PlocUpdater.cpp | 396 ------------------ mission/devices/PlocUpdater.h | 171 -------- 11 files changed, 14 insertions(+), 581 deletions(-) rename {mission => bsp_q7s}/devices/devicedefinitions/PlocSupervisorDefinitions.h (100%) delete mode 100644 mission/devices/PlocUpdater.cpp delete mode 100644 mission/devices/PlocUpdater.h diff --git a/bsp_hosted/ObjectFactory.cpp b/bsp_hosted/ObjectFactory.cpp index 2c431fb8..cf4805c2 100644 --- a/bsp_hosted/ObjectFactory.cpp +++ b/bsp_hosted/ObjectFactory.cpp @@ -51,7 +51,7 @@ void ObjectFactory::produce(void* args){ new UdpTcPollingTask(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); #else sif::info << "Setting up TCP TMTC bridge with listener port " << - TcpTmTcBridge::DEFAULT_TCP_SERVER_PORT << std::endl; + TcpTmTcBridge::DEFAULT_SERVER_PORT << std::endl; new TcpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); new TcpTmTcServer(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); #endif diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 2b16dd3c..bb699d8b 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -10,7 +10,7 @@ #if OBSW_USE_TMTC_TCP_BRIDGE == 0 #include "fsfw/osal/common/UdpTmTcBridge.h" #else -#include "fsfw/osal/common/TcpTmTcBridge.h" +#include "fsfw/osal/common/TcpTmTcServer.h" #endif #include "bsp_q7s/memory/scratchApi.h" @@ -782,10 +782,10 @@ void CoreController::initPrint() { #if OBSW_VERBOSE_LEVEL >= 1 #if OBSW_USE_TMTC_TCP_BRIDGE == 0 sif::info << "Created UDP server for TMTC commanding with listener port " << - UdpTmTcBridge::DEFAULT_UDP_SERVER_PORT << std::endl; + UdpTmTcBridge::DEFAULT_SERVER_PORT << std::endl; #else sif::info << "Created TCP server for TMTC commanding with listener port " << - TcpTmTcBridge::DEFAULT_TCP_SERVER_PORT << std::endl; + TcpTmTcServer::DEFAULT_SERVER_PORT << std::endl; #endif if(watchdogFifoFd > 0) { diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index b6fb4b0f..31e244ab 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -38,11 +38,9 @@ #include "mission/devices/RadiationSensorHandler.h" #include "mission/devices/RwHandler.h" #include "mission/devices/StarTrackerHandler.h" -#include "mission/devices/PlocUpdater.h" #include "mission/devices/devicedefinitions/GomspaceDefinitions.h" #include "mission/devices/devicedefinitions/SyrlinksDefinitions.h" #include "mission/devices/devicedefinitions/PlocMPSoCDefinitions.h" -#include "mission/devices/devicedefinitions/PlocSupervisorDefinitions.h" #include "mission/devices/devicedefinitions/RadSensorDefinitions.h" #include "mission/devices/devicedefinitions/Max31865Definitions.h" #include "mission/devices/devicedefinitions/RwDefinitions.h" diff --git a/bsp_q7s/devices/PlocSupervisorHandler.h b/bsp_q7s/devices/PlocSupervisorHandler.h index 950ac894..176578e4 100644 --- a/bsp_q7s/devices/PlocSupervisorHandler.h +++ b/bsp_q7s/devices/PlocSupervisorHandler.h @@ -1,11 +1,12 @@ #ifndef MISSION_DEVICES_PLOCSUPERVISORHANDLER_H_ #define MISSION_DEVICES_PLOCSUPERVISORHANDLER_H_ -#include -#include -#include +#include "devicedefinitions/PlocSupervisorDefinitions.h" #include +#include +#include + /** * @brief This is the device handler for the supervisor of the PLOC which is programmed by * Thales. diff --git a/bsp_q7s/devices/PlocUpdater.h b/bsp_q7s/devices/PlocUpdater.h index eee5453a..fac8b7c2 100644 --- a/bsp_q7s/devices/PlocUpdater.h +++ b/bsp_q7s/devices/PlocUpdater.h @@ -1,6 +1,9 @@ #ifndef MISSION_DEVICES_PLOCUPDATER_H_ #define MISSION_DEVICES_PLOCUPDATER_H_ +#include "OBSWConfig.h" +#include "devicedefinitions/PlocSupervisorDefinitions.h" + #include "fsfw/action/CommandActionHelper.h" #include "fsfw/action/ActionHelper.h" #include "fsfw/action/HasActionsIF.h" @@ -11,8 +14,7 @@ #include "bsp_q7s/memory/SdCardManager.h" #include "linux/fsfwconfig/objects/systemObjectList.h" #include "fsfw/tmtcpacket/SpacePacket.h" -#include "OBSWConfig.h" -#include + /** * @brief An object of this class can be used to perform the software updates of the PLOC. The diff --git a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h b/bsp_q7s/devices/devicedefinitions/PlocSupervisorDefinitions.h similarity index 100% rename from mission/devices/devicedefinitions/PlocSupervisorDefinitions.h rename to bsp_q7s/devices/devicedefinitions/PlocSupervisorDefinitions.h diff --git a/common/config/commonConfig.h.in b/common/config/commonConfig.h.in index 2b0590c8..52b5dd45 100644 --- a/common/config/commonConfig.h.in +++ b/common/config/commonConfig.h.in @@ -5,6 +5,6 @@ // Use TCP instead of UDP for the TMTC bridge. This allows using the TMTC client locally // because UDP packets are not allowed in the VPN -#define OBSW_USE_TMTC_TCP_BRIDGE 0 +#define OBSW_USE_TMTC_TCP_BRIDGE 1 #endif /* COMMON_CONFIG_COMMONCONFIG_H_ */ diff --git a/fsfw b/fsfw index 82bcb695..ba5e2ad8 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 82bcb695b76956b4709de634097795cf771df481 +Subproject commit ba5e2ad8bb97faf22702fa9aaaf47931db7ca6bb diff --git a/mission/devices/CMakeLists.txt b/mission/devices/CMakeLists.txt index fd37a30a..4ed60dfd 100644 --- a/mission/devices/CMakeLists.txt +++ b/mission/devices/CMakeLists.txt @@ -17,7 +17,6 @@ target_sources(${TARGET_NAME} PUBLIC GyroADIS16507Handler.cpp RwHandler.cpp StarTrackerHandler.cpp - PlocUpdater.cpp ) diff --git a/mission/devices/PlocUpdater.cpp b/mission/devices/PlocUpdater.cpp deleted file mode 100644 index f890c239..00000000 --- a/mission/devices/PlocUpdater.cpp +++ /dev/null @@ -1,396 +0,0 @@ -#include "fsfw/ipc/QueueFactory.h" -#include -#include -#include -#include - -PlocUpdater::PlocUpdater(object_id_t objectId) : - SystemObject(objectId), commandActionHelper(this), actionHelper(this, nullptr) { - commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE); -} - -PlocUpdater::~PlocUpdater() { -} - -ReturnValue_t PlocUpdater::initialize() { - sdcMan = SdCardManager::instance(); - - ReturnValue_t result = SystemObject::initialize(); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - result = commandActionHelper.initialize(); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - result = actionHelper.initialize(commandQueue); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - - return HasReturnvaluesIF::RETURN_OK; -} - -ReturnValue_t PlocUpdater::performOperation(uint8_t operationCode) { - readCommandQueue(); - doStateMachine(); - return HasReturnvaluesIF::RETURN_OK; -} - -ReturnValue_t PlocUpdater::executeAction(ActionId_t actionId, - MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { - ReturnValue_t result = RETURN_FAILED; - - if (state != State::IDLE) { - return IS_BUSY; - } - - if (size > MAX_PLOC_UPDATE_PATH) { - return NAME_TOO_LONG; - } - - switch (actionId) { - case UPDATE_NVM0_A: - updatePartition = Partition::A; - updateMemory = Memory::NVM0; - break; - case UPDATE_NVM0_B: - updatePartition = Partition::B; - updateMemory = Memory::NVM0; - break; - case UPDATE_NVM1_A: - updatePartition = Partition::A; - updateMemory = Memory::NVM1; - break; - case UPDATE_NVM1_B: - updatePartition = Partition::B; - updateMemory = Memory::NVM1; - break; - default: - return INVALID_ACTION_ID; - } - - result = getImageLocation(data, size); - - if (result != RETURN_OK) { - return result; - } - - state = State::UPDATE_AVAILABLE; - - return EXECUTION_FINISHED; -} - -MessageQueueId_t PlocUpdater::getCommandQueue() const { - return commandQueue->getId(); -} - -MessageQueueIF* PlocUpdater::getCommandQueuePtr() { - return commandQueue; -} - -void PlocUpdater::readCommandQueue() { - CommandMessage message; - ReturnValue_t result; - - for (result = commandQueue->receiveMessage(&message); result == HasReturnvaluesIF::RETURN_OK; - result = commandQueue->receiveMessage(&message)) { - if (result != RETURN_OK) { - continue; - } - result = actionHelper.handleActionMessage(&message); - if (result == HasReturnvaluesIF::RETURN_OK) { - continue; - } - - result = commandActionHelper.handleReply(&message); - if (result == HasReturnvaluesIF::RETURN_OK) { - continue; - } - - sif::debug << "PlocUpdater::readCommandQueue: Received message with invalid format" - << std::endl; - } -} - -void PlocUpdater::doStateMachine() { - switch (state) { - case State::IDLE: - break; - case State::UPDATE_AVAILABLE: - commandUpdateAvailable(); - break; - case State::UPDATE_TRANSFER: - commandUpdatePacket(); - break; - case State::UPDATE_VERIFY: - commandUpdateVerify(); - break; - case State::COMMAND_EXECUTING: - break; - default: - sif::debug << "PlocUpdater::doStateMachine: Invalid state" << std::endl; - break; - } -} - -ReturnValue_t PlocUpdater::checkNameLength(size_t size) { - if (size > MAX_PLOC_UPDATE_PATH) { - return NAME_TOO_LONG; - } - return RETURN_OK; -} - -ReturnValue_t PlocUpdater::getImageLocation(const uint8_t* data, size_t size) { - ReturnValue_t result = checkNameLength(size); - if (result != RETURN_OK) { - return result; - } - - // Check if file is stored on SD card and if associated SD card is mounted - if (std::string(reinterpret_cast(data), SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_0_MOUNT_POINT)) { - if (!isSdCardMounted(sd::SLOT_0)) { - sif::warning << "PlocUpdater::prepareNvm0AUpdate: SD card 0 not mounted" << std::endl; - return SD_NOT_MOUNTED; - } - } - else if (std::string(reinterpret_cast(data), SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_1_MOUNT_POINT)) { - if (!isSdCardMounted(sd::SLOT_0)) { - sif::warning << "PlocUpdater::prepareNvm0AUpdate: SD card 1 not mounted" << std::endl; - return SD_NOT_MOUNTED; - } - } - else { - //update image not stored on SD card - } - - updateFile = std::string(reinterpret_cast(data), size); - - // Check if file exists - if(not std::filesystem::exists(updateFile)) { - return FILE_NOT_EXISTS; - } - return RETURN_OK; -} - -bool PlocUpdater::isSdCardMounted(sd::SdCard sdCard) { - SdCardManager::SdStatePair active; - ReturnValue_t result = sdcMan->getSdCardActiveStatus(active); - if (result != RETURN_OK) { - sif::debug << "PlocUpdater::isSdCardMounted: Failed to get SD card active state"; - return false; - } - if (sdCard == sd::SLOT_0) { - if (active.first == sd::MOUNTED) { - return true; - } - else { - return false; - } - } - else if (sdCard == sd::SLOT_1) { - if (active.second == sd::MOUNTED) { - return true; - } - else { - return false; - } - } - else { - sif::debug << "PlocUpdater::isSdCardMounted: Unknown SD card specified" << std::endl; - } - return false; -} - -void PlocUpdater::stepSuccessfulReceived(ActionId_t actionId, - uint8_t step) { -} - -void PlocUpdater::stepFailedReceived(ActionId_t actionId, uint8_t step, - ReturnValue_t returnCode) { -} - -void PlocUpdater::dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) { - -} - -void PlocUpdater::completionSuccessfulReceived(ActionId_t actionId) { - switch (pendingCommand) { - case (PLOC_SPV::UPDATE_AVAILABLE): - state = State::UPDATE_TRANSFER; - break; - case (PLOC_SPV::UPDATE_IMAGE_DATA): - if (remainingPackets == 0) { - packetsSent = 0; // Reset packets sent variable for next update sequence - state = State::UPDATE_VERIFY; - } - else { - state = State::UPDATE_TRANSFER; - } - break; - case (PLOC_SPV::UPDATE_VERIFY): - triggerEvent(UPDATE_FINISHED); - state = State::IDLE; - pendingCommand = PLOC_SPV::NONE; - break; - default: - sif::debug << "PlocUpdater::completionSuccessfulReceived: Invalid pending command" - << std::endl; - state = State::IDLE; - break; - } -} - -void PlocUpdater::completionFailedReceived(ActionId_t actionId, - ReturnValue_t returnCode) { - switch(pendingCommand) { - case(PLOC_SPV::UPDATE_AVAILABLE): { - triggerEvent(UPDATE_AVAILABLE_FAILED); - break; - } - case(PLOC_SPV::UPDATE_IMAGE_DATA): { - triggerEvent(UPDATE_TRANSFER_FAILED, packetsSent); - break; - } - case(PLOC_SPV::UPDATE_VERIFY): { - triggerEvent(UPDATE_VERIFY_FAILED); - break; - } - default: - sif::debug << "PlocUpdater::completionFailedReceived: Invalid pending command " - << std::endl; - break; - } - state = State::IDLE; -} - -void PlocUpdater::commandUpdateAvailable() { - ReturnValue_t result = RETURN_OK; - - if (not std::filesystem::exists(updateFile)) { - triggerEvent(UPDATE_FILE_NOT_EXISTS, static_cast(state)); - state = State::IDLE; - return; - } - - std::ifstream file(updateFile, std::ifstream::binary); - file.seekg(0, file.end); - imageSize = static_cast(file.tellg()); - file.close(); - - numOfUpdatePackets = imageSize / MAX_SP_DATA ; - if (imageSize % MAX_SP_DATA) { - numOfUpdatePackets++; - } - - remainingPackets = numOfUpdatePackets; - packetsSent = 0; - - uint32_t imageCrc = makeCrc(); - - PLOC_SPV::UpdateInfo packet(PLOC_SPV::APID_UPDATE_AVAILABLE, static_cast(updateMemory), - static_cast(updatePartition), imageSize, imageCrc, numOfUpdatePackets); - - result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER, - PLOC_SPV::UPDATE_AVAILABLE, packet.getWholeData(), packet.getFullSize()); - if (result != RETURN_OK) { - sif::warning << "PlocUpdater::commandUpdateAvailable: Failed to send update available" - << " packet to supervisor handler" << std::endl; - triggerEvent(ACTION_COMMANDING_FAILED, result, PLOC_SPV::UPDATE_AVAILABLE); - state = State::IDLE; - pendingCommand = PLOC_SPV::NONE; - return; - } - - pendingCommand = PLOC_SPV::UPDATE_AVAILABLE; - state = State::COMMAND_EXECUTING; - return; -} - -void PlocUpdater::commandUpdatePacket() { - ReturnValue_t result = RETURN_OK; - uint16_t payloadLength = 0; - - if (not std::filesystem::exists(updateFile)) { - triggerEvent(UPDATE_FILE_NOT_EXISTS, static_cast(state), packetsSent); - state = State::IDLE; - return; - } - - std::ifstream file(updateFile, std::ifstream::binary); - file.seekg(packetsSent * MAX_SP_DATA, file.beg); - - if (remainingPackets == 1) { - payloadLength = imageSize - static_cast(file.tellg()); - } - else { - payloadLength = MAX_SP_DATA; - } - - PLOC_SPV::UpdatePacket packet(payloadLength); - file.read(reinterpret_cast(packet.getDataFieldPointer()), payloadLength); - file.close(); - // sequence count of first packet is 1 - packet.setPacketSequenceCount((packetsSent + 1) & PLOC_SPV::SEQUENCE_COUNT_MASK); - if (numOfUpdatePackets > 0) { - adjustSequenceFlags(packet); - } - packet.makeCrc(); - - result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER, - PLOC_SPV::UPDATE_IMAGE_DATA, packet.getWholeData(), packet.getFullSize()); - - if (result != RETURN_OK) { - sif::warning << "PlocUpdater::commandUpdateAvailable: Failed to send update" - << " packet to supervisor handler" << std::endl; - triggerEvent(ACTION_COMMANDING_FAILED, result, PLOC_SPV::UPDATE_IMAGE_DATA); - state = State::IDLE; - pendingCommand = PLOC_SPV::NONE; - return; - } - - remainingPackets--; - packetsSent++; - - pendingCommand = PLOC_SPV::UPDATE_IMAGE_DATA; - state = State::COMMAND_EXECUTING; -} - -void PlocUpdater::commandUpdateVerify() { - ReturnValue_t result = RETURN_OK; - - PLOC_SPV::UpdateInfo packet(PLOC_SPV::APID_UPDATE_VERIFY, static_cast(updateMemory), - static_cast(updatePartition), imageSize, imageCrc, numOfUpdatePackets); - - result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER, - PLOC_SPV::UPDATE_VERIFY, packet.getWholeData(), packet.getFullSize()); - if (result != RETURN_OK) { - sif::warning << "PlocUpdater::commandUpdateAvailable: Failed to send update available" - << " packet to supervisor handler" << std::endl; - triggerEvent(ACTION_COMMANDING_FAILED, result, PLOC_SPV::UPDATE_VERIFY); - state = State::IDLE; - pendingCommand = PLOC_SPV::NONE; - return; - } - state = State::COMMAND_EXECUTING; - pendingCommand = PLOC_SPV::UPDATE_VERIFY; - return; -} - -ReturnValue_t PlocUpdater::makeCrc() { - //TODO: Waiting on input from TAS about the CRC to use - return 0; -} - -void PlocUpdater::adjustSequenceFlags(PLOC_SPV::UpdatePacket& packet) { - if (packetsSent == 0) { - packet.setSequenceFlags(static_cast(PLOC_SPV::SequenceFlags::FIRST_PKT)); - } - else if (remainingPackets == 1) { - packet.setSequenceFlags(static_cast(PLOC_SPV::SequenceFlags::LAST_PKT)); - } - else { - packet.setSequenceFlags(static_cast(PLOC_SPV::SequenceFlags::CONTINUED_PKT)); - } -} - diff --git a/mission/devices/PlocUpdater.h b/mission/devices/PlocUpdater.h deleted file mode 100644 index eee5453a..00000000 --- a/mission/devices/PlocUpdater.h +++ /dev/null @@ -1,171 +0,0 @@ -#ifndef MISSION_DEVICES_PLOCUPDATER_H_ -#define MISSION_DEVICES_PLOCUPDATER_H_ - -#include "fsfw/action/CommandActionHelper.h" -#include "fsfw/action/ActionHelper.h" -#include "fsfw/action/HasActionsIF.h" -#include "fsfw/action/CommandsActionsIF.h" -#include "fsfw/returnvalues/HasReturnvaluesIF.h" -#include "fsfw/tasks/ExecutableObjectIF.h" -#include "fsfw/objectmanager/SystemObject.h" -#include "bsp_q7s/memory/SdCardManager.h" -#include "linux/fsfwconfig/objects/systemObjectList.h" -#include "fsfw/tmtcpacket/SpacePacket.h" -#include "OBSWConfig.h" -#include - -/** - * @brief An object of this class can be used to perform the software updates of the PLOC. The - * software update will be read from one of the SD cards, split into multiple space - * packets and sent to the PlocSupervisorHandler. - * - * @details The MPSoC has two boot memories (NVM0 and NVM1) where each stores two images (Partition A - * and Partition B) - * - * @author J. Meier - */ -class PlocUpdater : public SystemObject, - public HasActionsIF, - public ExecutableObjectIF, - public HasReturnvaluesIF, - public CommandsActionsIF { -public: - - static const ActionId_t UPDATE_NVM0_A = 0; - static const ActionId_t UPDATE_NVM0_B = 1; - static const ActionId_t UPDATE_NVM1_A = 2; - static const ActionId_t UPDATE_NVM1_B = 3; - - PlocUpdater(object_id_t objectId); - virtual ~PlocUpdater(); - - ReturnValue_t performOperation(uint8_t operationCode = 0) override; - ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, - const uint8_t* data, size_t size); - MessageQueueId_t getCommandQueue() const; - ReturnValue_t initialize() override; - MessageQueueIF* getCommandQueuePtr() override; - void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) override; - void stepFailedReceived(ActionId_t actionId, uint8_t step, ReturnValue_t returnCode) override; - void dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) override; - void completionSuccessfulReceived(ActionId_t actionId) override; - void completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) override; - -private: - - static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_UPDATER; - - //! [EXPORT] : [COMMENT] Updater is already performing an update - static const ReturnValue_t UPDATER_BUSY = MAKE_RETURN_CODE(0xA0); - //! [EXPORT] : [COMMENT] Received update command with invalid path string (too long). - static const ReturnValue_t NAME_TOO_LONG = MAKE_RETURN_CODE(0xA1); - //! [EXPORT] : [COMMENT] Received command to initiate update but SD card with update image not mounted. - static const ReturnValue_t SD_NOT_MOUNTED = MAKE_RETURN_CODE(0xA2); - //! [EXPORT] : [COMMENT] Update file received with update command does not exist. - static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xA3); - - static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_UPDATER; - - //! [EXPORT] : [COMMENT] Try to read update file but the file does not exist. - //! P1: Indicates in which state the file read fails - //! P2: During the update transfer the second parameter gives information about the number of already sent packets - static const Event UPDATE_FILE_NOT_EXISTS = MAKE_EVENT(0, severity::LOW); - //! [EXPORT] : [COMMENT] Failed to send command to supervisor handler - //! P1: Return value of CommandActionHelper::commandAction - //! P2: Action ID of command to send - static const Event ACTION_COMMANDING_FAILED = MAKE_EVENT(1, severity::LOW); - //! [EXPORT] : [COMMENT] Supervisor handler replied action message indicating a command execution failure of the update available command - static const Event UPDATE_AVAILABLE_FAILED = MAKE_EVENT(2, severity::LOW); - //! [EXPORT] : [COMMENT] Supervisor handler failed to transfer an update space packet. - //! P1: Parameter holds the number of update packets already sent (inclusive the failed packet) - static const Event UPDATE_TRANSFER_FAILED = MAKE_EVENT(3, severity::LOW); - //! [EXPORT] : [COMMENT] Supervisor failed to execute the update verify command. - static const Event UPDATE_VERIFY_FAILED = MAKE_EVENT(4, severity::LOW); - //! [EXPORT] : [COMMENT] MPSoC update successful completed - static const Event UPDATE_FINISHED = MAKE_EVENT(5, severity::INFO); - - static const uint32_t QUEUE_SIZE = config::PLOC_UPDATER_QUEUE_SIZE; - static const size_t MAX_PLOC_UPDATE_PATH = 50; - static const size_t SD_PREFIX_LENGTH = 8; - // Maximum size of update payload data per space packet (max size of space packet is 1024 bytes) - static const size_t MAX_SP_DATA = 1016; - - MessageQueueIF* commandQueue = nullptr; - - SdCardManager* sdcMan = nullptr; - - CommandActionHelper commandActionHelper; - - ActionHelper actionHelper; - - enum class State: uint8_t { - IDLE, - UPDATE_AVAILABLE, - UPDATE_TRANSFER, - UPDATE_VERIFY, - COMMAND_EXECUTING - }; - - State state = State::IDLE; - - ActionId_t pendingCommand = PLOC_SPV::NONE; - - enum class Memory: uint8_t { - NVM0, - NVM1 - }; - - Memory updateMemory = Memory::NVM0; - - enum class Partition: uint8_t { - A, - B - }; - - Partition updatePartition = Partition::A; - - uint32_t packetsSent = 0; - uint32_t remainingPackets = 0; - // Number of packets required to transfer the update image - uint32_t numOfUpdatePackets = 0; - - std::string updateFile; - uint32_t imageSize = 0; - uint32_t imageCrc = 0; - - void readCommandQueue(); - void doStateMachine(); - - /** - * @brief Extracts the path and name of the update image from the service 8 command data. - */ - ReturnValue_t getImageLocation(const uint8_t* data, size_t size); - - ReturnValue_t checkNameLength(size_t size); - - /** - * @brief Prepares and sends update available command to PLOC supervisor handler. - */ - void commandUpdateAvailable(); - - /** - * @brief Prepares and sends and update packet to the PLOC supervisor handler. - */ - void commandUpdatePacket(); - - /** - * @brief Prepares and sends the update verification packet to the PLOC supervisor handler. - */ - void commandUpdateVerify(); - - /** - * @brief Checks whether the SD card to read from is mounted or not. - */ - bool isSdCardMounted(sd::SdCard sdCard); - - ReturnValue_t makeCrc(); - - void adjustSequenceFlags(PLOC_SPV::UpdatePacket& packet); -}; - -#endif /* MISSION_DEVICES_PLOCUPDATER_H_ */ From d604f8d3d18a83e7c7e0adcfd44cf9bffc68be57 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 Aug 2021 18:23:18 +0200 Subject: [PATCH 7/9] one port is okay --- README.md | 12 ++---------- bsp_q7s/core/CoreController.cpp | 8 -------- bsp_q7s/core/ObjectFactory.cpp | 8 ++++++-- fsfw | 2 +- scripts/q7s-port-tcp.sh | 11 ----------- scripts/{q7s-port-udp.sh => q7s-port.sh} | 2 +- 6 files changed, 10 insertions(+), 33 deletions(-) delete mode 100755 scripts/q7s-port-tcp.sh rename scripts/{q7s-port-udp.sh => q7s-port.sh} (84%) diff --git a/README.md b/README.md index 2e2c8b96..def12cf0 100644 --- a/README.md +++ b/README.md @@ -251,21 +251,13 @@ You then need to run `scp` with the `-P 1535` flag with `localhost` as the targe ## Port forwarding for TMTC commanding -If you are using the UDP communication interface, you can use: +You can enable port forwarding for TMTC commanding with the following command: ```sh ssh -L 1536:192.168.133.10:7301 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash ``` -This forwards UDP TMTC packets on port `1536` of localhost to the TMTC reception port of the Q7S. - -For TCP, you can use - -```sh -ssh -L 1537:192.168.133.10:7301 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash -``` - -This forwards TCP TMTC packets on port `1537` of localhost to the TMTC reception port of the Q7S. +This forwards TMTC packets on port `1536` of localhost to the TMTC reception port of the Q7S. ## Set up all port forwarding at once diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index bb699d8b..b7394cb9 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -780,14 +780,6 @@ ReturnValue_t CoreController::initWatchdogFifo() { void CoreController::initPrint() { #if OBSW_VERBOSE_LEVEL >= 1 -#if OBSW_USE_TMTC_TCP_BRIDGE == 0 - sif::info << "Created UDP server for TMTC commanding with listener port " << - UdpTmTcBridge::DEFAULT_SERVER_PORT << std::endl; -#else - sif::info << "Created TCP server for TMTC commanding with listener port " << - TcpTmTcServer::DEFAULT_SERVER_PORT << std::endl; -#endif - if(watchdogFifoFd > 0) { sif::info << "Opened watchdog FIFO successfully.." << std::endl; } diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 31e244ab..5d083741 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -139,11 +139,15 @@ void ObjectFactory::produce(void* args){ #endif /* TE7020 != 0 */ #if OBSW_USE_TMTC_TCP_BRIDGE == 0 - new UdpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); + auto udpBridge = new UdpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); new UdpTcPollingTask(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); + sif::info << "Created UDP server for TMTC commanding with listener port " << + udpBridge->getUdpPort() << std::endl; #else new TcpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); - new TcpTmTcServer(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); + auto tcpServer = new TcpTmTcServer(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); + sif::info << "Created TCP server for TMTC commanding with listener port " << + tcpServer->getTcpPort() << std::endl; #endif /* Test Task */ diff --git a/fsfw b/fsfw index ba5e2ad8..1ac372cb 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit ba5e2ad8bb97faf22702fa9aaaf47931db7ca6bb +Subproject commit 1ac372cb89fabc868aa9cc6ef024f822c744eaed diff --git a/scripts/q7s-port-tcp.sh b/scripts/q7s-port-tcp.sh deleted file mode 100755 index 4d0aef4a..00000000 --- a/scripts/q7s-port-tcp.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -echo "Setting up all Q7S ports" -echo "-L 1534:192.168.133.10:1534 for connection to TCF agent" -echo "-L 1535:192.168.133.10:22 for file transfers" -echo "-L 1537:192.168.133.10:7303 to TMTC commanding using TCP" - -ssh -L 1534:192.168.133.10:1534 \ - -L 1535:192.168.133.10:22 \ - -L 1537:192.168.133.10:7301 \ - eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ - -t 'CONSOLE_PREFIX="[Q7S Tunnel]" /bin/bash' diff --git a/scripts/q7s-port-udp.sh b/scripts/q7s-port.sh similarity index 84% rename from scripts/q7s-port-udp.sh rename to scripts/q7s-port.sh index 21393083..e475e8b7 100755 --- a/scripts/q7s-port-udp.sh +++ b/scripts/q7s-port.sh @@ -2,7 +2,7 @@ echo "Setting up all Q7S ports" echo "-L 1534:192.168.133.10:1534 for connection to TCF agent" echo "-L 1535:192.168.133.10:22 for file transfers" -echo "-L 1536:192.168.133.10:7301 to TMTC commanding using UDP" +echo "-L 1536:192.168.133.10:7301 for TMTC commanding" ssh -L 1534:192.168.133.10:1534 \ -L 1535:192.168.133.10:22 \ From bda8550ef9fd744ca724e8272ecb3e624c1f1b18 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 Aug 2021 18:26:34 +0200 Subject: [PATCH 8/9] fixes for hosted --- bsp_hosted/ObjectFactory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bsp_hosted/ObjectFactory.cpp b/bsp_hosted/ObjectFactory.cpp index cf4805c2..d7878e46 100644 --- a/bsp_hosted/ObjectFactory.cpp +++ b/bsp_hosted/ObjectFactory.cpp @@ -46,12 +46,12 @@ void ObjectFactory::produce(void* args){ #if OBSW_USE_TMTC_TCP_BRIDGE == 0 sif::info << "Setting up UDP TMTC bridge with listener port " << - UdpTmTcBridge::DEFAULT_UDP_SERVER_PORT << std::endl; + UdpTmTcBridge::DEFAULT_SERVER_PORT << std::endl; new UdpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); new UdpTcPollingTask(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); #else sif::info << "Setting up TCP TMTC bridge with listener port " << - TcpTmTcBridge::DEFAULT_SERVER_PORT << std::endl; + TcpTmTcServer::DEFAULT_SERVER_PORT << std::endl; new TcpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); new TcpTmTcServer(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); #endif From d714f84df8fb41b468ddece7b1a701db20719029 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 Aug 2021 18:30:20 +0200 Subject: [PATCH 9/9] bumped revision --- common/config/OBSWVersion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/config/OBSWVersion.h b/common/config/OBSWVersion.h index db7cfeb5..1656eda0 100644 --- a/common/config/OBSWVersion.h +++ b/common/config/OBSWVersion.h @@ -5,6 +5,6 @@ const char* const SW_NAME = "eive"; #define SW_VERSION 1 #define SW_SUBVERSION 6 -#define SW_REVISION 0 +#define SW_REVISION 1 #endif /* COMMON_CONFIG_OBSWVERSION_H_ */