From 21899d663ea9c953de4211225c18720bdc0fd77c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 9 Mar 2023 01:32:27 +0100 Subject: [PATCH] start groundwork for new TM downlink arch --- bsp_q7s/boardconfig/busConf.h | 4 ++ bsp_q7s/core/ObjectFactory.cpp | 58 +++++++++---------- bsp_q7s/core/ObjectFactory.h | 4 +- bsp_q7s/fmObjectFactory.cpp | 7 ++- common/config/eive/objects.h | 4 ++ linux/ObjectFactory.cpp | 6 +- linux/ipcore/Ptme.h | 11 ++-- mission/core/GenericFactory.cpp | 11 ++++ mission/core/GenericFactory.h | 1 + mission/tmtc/CMakeLists.txt | 3 + mission/tmtc/CcsdsIpCoreHandler.cpp | 88 +++++++++++++---------------- mission/tmtc/CcsdsIpCoreHandler.h | 15 ++--- mission/tmtc/PersistentTmStore.cpp | 60 -------------------- mission/tmtc/PersistentTmStore.h | 16 +----- mission/tmtc/PusPacketFilter.cpp | 64 +++++++++++++++++++++ mission/tmtc/PusPacketFilter.h | 24 ++++++++ mission/tmtc/PusTmFunnel.cpp | 88 ++++++++++------------------- mission/tmtc/PusTmFunnel.h | 9 +-- mission/tmtc/TmStoreRouter.cpp | 19 +++++++ mission/tmtc/TmStoreRouter.h | 18 ++++++ mission/tmtc/VirtualChannel.cpp | 60 ++++++++++---------- mission/tmtc/VirtualChannel.h | 10 ++-- mission/tmtc/tmFilters.cpp | 51 +++++++++++++++++ mission/tmtc/tmFilters.h | 14 +++++ 24 files changed, 379 insertions(+), 266 deletions(-) create mode 100644 mission/tmtc/PusPacketFilter.cpp create mode 100644 mission/tmtc/PusPacketFilter.h create mode 100644 mission/tmtc/TmStoreRouter.cpp create mode 100644 mission/tmtc/TmStoreRouter.h create mode 100644 mission/tmtc/tmFilters.cpp create mode 100644 mission/tmtc/tmFilters.h diff --git a/bsp_q7s/boardconfig/busConf.h b/bsp_q7s/boardconfig/busConf.h index a094c029..4c142644 100644 --- a/bsp_q7s/boardconfig/busConf.h +++ b/bsp_q7s/boardconfig/busConf.h @@ -28,9 +28,13 @@ static constexpr char UIO_PDEC_IRQ[] = "/dev/uio_pdec_irq"; static constexpr int MAP_ID_PTME_CONFIG = 3; namespace uiomapids { +// Live TM static const int PTME_VC0 = 0; +// OK/NOK/MISC Store static const int PTME_VC1 = 1; +// HK store static const int PTME_VC2 = 2; +// CFDP static const int PTME_VC3 = 3; static const int PTME_CONFIG = 4; } // namespace uiomapids diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index d078916f..ee58b109 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -62,6 +62,7 @@ #include "mission/system/tree/comModeTree.h" #include "mission/system/tree/payloadModeTree.h" #include "mission/system/tree/tcsModeTree.h" +#include "mission/tmtc/tmFilters.h" #include "mission/utility/GlobalConfigHandler.h" #include "tmtc/pusIds.h" #if OBSW_TEST_LIBGPIOD == 1 @@ -715,39 +716,27 @@ void ObjectFactory::createReactionWheelComponents(LinuxLibgpioIF* gpioComIF, } ReturnValue_t ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF, + PusTmFunnel& pusFunnel, CcsdsIpCoreHandler** ipCoreHandler) { using namespace gpio; // GPIO definitions of signals connected to the virtual channel interfaces of the PTME IP Core GpioCookie* gpioCookiePtmeIp = new GpioCookie; GpiodRegularByLineName* gpio = nullptr; - std::stringstream consumer; - consumer.str("PAPB VC0"); - gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC0, consumer.str()); + gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC0, "PAPB VC0"); gpioCookiePtmeIp->addGpio(gpioIds::VC0_PAPB_BUSY, gpio); - consumer.str("PAPB VC0"); - gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC0, consumer.str()); + gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC0, "PAPB VC0"); gpioCookiePtmeIp->addGpio(gpioIds::VC0_PAPB_EMPTY, gpio); - consumer.str("PAPB VC 1"); - gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC1, consumer.str()); + gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC1, "PAPB VC1"); gpioCookiePtmeIp->addGpio(gpioIds::VC1_PAPB_BUSY, gpio); - consumer.str(""); - consumer.str("PAPB VC 1"); + gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC1, "PAPB VC1"); gpioCookiePtmeIp->addGpio(gpioIds::VC1_PAPB_EMPTY, gpio); - consumer.str(""); - consumer.str("PAPB VC 2"); - gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC2, consumer.str()); + gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC2, "PAPB VC2"); gpioCookiePtmeIp->addGpio(gpioIds::VC2_PAPB_BUSY, gpio); - consumer.str(""); - consumer.str("PAPB VC 2"); - gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC2, consumer.str()); + gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC2, "PAPB VC2"); gpioCookiePtmeIp->addGpio(gpioIds::VC2_PAPB_EMPTY, gpio); - consumer.str(""); - consumer.str("PAPB VC 3"); - gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC3, consumer.str()); + gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC3, "PAPB VC3"); gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_BUSY, gpio); - consumer.str(""); - consumer.str("PAPB VC 3"); - gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC3, consumer.str()); + gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC3, "PAPB VC3"); gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_EMPTY, gpio); gpioChecker(gpioComIF->addGpios(gpioCookiePtmeIp), "PTME PAPB VCs"); // Creating virtual channel interfaces @@ -773,17 +762,26 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF, new AxiPtmeConfig(objects::AXI_PTME_CONFIG, q7s::UIO_PTME, q7s::uiomapids::PTME_CONFIG); PtmeConfig* ptmeConfig = new PtmeConfig(objects::PTME_CONFIG, axiPtmeConfig); - *ipCoreHandler = new CcsdsIpCoreHandler(objects::CCSDS_HANDLER, objects::PTME, - objects::CCSDS_PACKET_DISTRIBUTOR, ptmeConfig, gpioComIF, - gpioIds::RS485_EN_TX_CLOCK, gpioIds::RS485_EN_TX_DATA); + *ipCoreHandler = new CcsdsIpCoreHandler(objects::CCSDS_HANDLER, objects::CCSDS_PACKET_DISTRIBUTOR, + *ptme, *ptmeConfig, gpioComIF, gpioIds::RS485_EN_TX_CLOCK, + gpioIds::RS485_EN_TX_DATA); VirtualChannel* vc = nullptr; - vc = new VirtualChannel(ccsds::VC0, config::VC0_QUEUE_SIZE, objects::CCSDS_HANDLER); + vc = new VirtualChannel(objects::PTME_VC0_LIVE_TM, ccsds::VC0, "PTME VC0 LIVE TM", + config::VC0_QUEUE_SIZE); (*ipCoreHandler)->addVirtualChannel(ccsds::VC0, vc); - vc = new VirtualChannel(ccsds::VC1, config::VC1_QUEUE_SIZE, objects::CCSDS_HANDLER); + vc = new VirtualChannel(objects::PTME_VC1_LOG_TM, ccsds::VC1, "PTME VC1 LOG TM", + config::VC1_QUEUE_SIZE); + pusFunnel.addPersistentTmStoreRouting(filters::okFilter(), vc->getReportReceptionQueue()); + pusFunnel.addPersistentTmStoreRouting(filters::notOkFilter(), vc->getReportReceptionQueue()); + pusFunnel.addPersistentTmStoreRouting(filters::miscFilter(), vc->getReportReceptionQueue()); (*ipCoreHandler)->addVirtualChannel(ccsds::VC1, vc); - vc = new VirtualChannel(ccsds::VC2, config::VC2_QUEUE_SIZE, objects::CCSDS_HANDLER); + vc = new VirtualChannel(objects::PTME_VC2_HK_TM, ccsds::VC2, "PTME VC2 HK TM", + config::VC2_QUEUE_SIZE); + pusFunnel.addPersistentTmStoreRouting(filters::hkFilter(), vc->getReportReceptionQueue()); (*ipCoreHandler)->addVirtualChannel(ccsds::VC2, vc); - vc = new VirtualChannel(ccsds::VC3, config::VC3_QUEUE_SIZE, objects::CCSDS_HANDLER); + vc = new VirtualChannel(objects::PTME_VC3_CFDP_TM, ccsds::VC3, "PTME VC3 CFDP TM", + config::VC3_QUEUE_SIZE); + // TODO: Set VC destination in CFDP funnel. (*ipCoreHandler)->addVirtualChannel(ccsds::VC3, vc); ReturnValue_t result = (*ipCoreHandler)->connectModeTreeParent(satsystem::com::SUBSYSTEM); @@ -794,10 +792,8 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF, } GpioCookie* gpioCookiePdec = new GpioCookie; - consumer.str(""); - consumer << "0x" << std::hex << objects::PDEC_HANDLER; // GPIO also low after linux boot (specified by device-tree) - gpio = new GpiodRegularByLineName(q7s::gpioNames::PDEC_RESET, consumer.str(), Direction::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::PDEC_RESET, "PDEC Handler", Direction::OUT, Levels::LOW); gpioCookiePdec->addGpio(gpioIds::PDEC_RESET, gpio); gpioChecker(gpioComIF->addGpios(gpioCookiePdec), "PDEC"); diff --git a/bsp_q7s/core/ObjectFactory.h b/bsp_q7s/core/ObjectFactory.h index 7ec6c871..0a43b336 100644 --- a/bsp_q7s/core/ObjectFactory.h +++ b/bsp_q7s/core/ObjectFactory.h @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -43,7 +44,8 @@ void createSolarArrayDeploymentComponents(PowerSwitchIF& pwrSwitcher, GpioIF& gp void createSyrlinksComponents(PowerSwitchIF* pwrSwitcher); void createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF& pwrSwitcher); void createReactionWheelComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF* pwrSwitcher); -ReturnValue_t createCcsdsComponents(LinuxLibgpioIF* gpioComIF, CcsdsIpCoreHandler** ipCoreHandler); +ReturnValue_t createCcsdsComponents(LinuxLibgpioIF* gpioComIF, PusTmFunnel& pusFunnel, + CcsdsIpCoreHandler** ipCoreHandler); void createMiscComponents(); void createTestComponents(LinuxLibgpioIF* gpioComIF); diff --git a/bsp_q7s/fmObjectFactory.cpp b/bsp_q7s/fmObjectFactory.cpp index e05e8098..c8760478 100644 --- a/bsp_q7s/fmObjectFactory.cpp +++ b/bsp_q7s/fmObjectFactory.cpp @@ -12,12 +12,14 @@ #include "linux/callbacks/gpioCallbacks.h" #include "mission/core/GenericFactory.h" #include "mission/system/tree/system.h" +#include "mission/tmtc/tmFilters.h" void ObjectFactory::produce(void* args) { ObjectFactory::setStatics(); HealthTableIF* healthTable = nullptr; PusTmFunnel* pusFunnel = nullptr; CfdpTmFunnel* cfdpFunnel = nullptr; + ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel, *SdCardManager::instance()); @@ -72,9 +74,10 @@ void ObjectFactory::produce(void* args) { #endif /* OBSW_ADD_STAR_TRACKER == 1 */ #if OBSW_ADD_CCSDS_IP_CORES == 1 CcsdsIpCoreHandler* ipCoreHandler = nullptr; - createCcsdsComponents(gpioComIF, &ipCoreHandler); + createCcsdsComponents(gpioComIF, *pusFunnel, &ipCoreHandler); #if OBSW_TM_TO_PTME == 1 - addTmtcIpCoresToFunnels(*ipCoreHandler, *pusFunnel, *cfdpFunnel); + // TODO: Remove this if not needed anymore + // addTmtcIpCoresToFunnels(*ipCoreHandler, *pusFunnel, *cfdpFunnel); #endif #endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */ diff --git a/common/config/eive/objects.h b/common/config/eive/objects.h index cb468ef2..bbab8a0a 100644 --- a/common/config/eive/objects.h +++ b/common/config/eive/objects.h @@ -66,6 +66,10 @@ enum commonObjects : uint32_t { PLOC_MPSOC_HELPER = 0x44330003, AXI_PTME_CONFIG = 0x44330004, PTME_CONFIG = 0x44330005, + PTME_VC0_LIVE_TM = 0x44330006, + PTME_VC1_LOG_TM = 0x44330007, + PTME_VC2_HK_TM = 0x44330008, + PTME_VC3_CFDP_TM = 0x44330009, PLOC_MPSOC_HANDLER = 0x44330015, PLOC_SUPERVISOR_HANDLER = 0x44330016, PLOC_SUPERVISOR_HELPER = 0x44330017, diff --git a/linux/ObjectFactory.cpp b/linux/ObjectFactory.cpp index e9154ba1..43ea9e70 100644 --- a/linux/ObjectFactory.cpp +++ b/linux/ObjectFactory.cpp @@ -344,6 +344,8 @@ void ObjectFactory::gpioChecker(ReturnValue_t result, std::string output) { void ObjectFactory::addTmtcIpCoresToFunnels(CcsdsIpCoreHandler& ipCoreHandler, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel) { - cfdpFunnel.addDestination("PTME IP Core", ipCoreHandler, config::LIVE_TM); - pusFunnel.addDestination("PTME IP Core", ipCoreHandler, config::LIVE_TM); + // TODO: Consider removing this, the only additional object in the dest list will + // be the live VC + // cfdpFunnel.addDestination("PTME IP Core", ipCoreHandler, config::LIVE_TM); + // pusFunnel.addDestination("PTME IP Core", ipCoreHandler, config::LIVE_TM); } diff --git a/linux/ipcore/Ptme.h b/linux/ipcore/Ptme.h index 2de85a38..d826ac57 100644 --- a/linux/ipcore/Ptme.h +++ b/linux/ipcore/Ptme.h @@ -13,10 +13,13 @@ #include "linux/ipcore/VcInterfaceIF.h" /** - * @brief This class handles the interfacing to the telemetry (PTME) IP core responsible for the - * encoding of telemetry packets according to the CCSDS standards CCSDS 131.0-B-3 (TM - * Synchro- nization and channel coding) and CCSDS 132.0-B-2 (TM Space Data Link Protocoll). The IP - * cores are implemented on the programmable logic and are accessible through the linux UIO driver. + * @brief This class handles the interfacing to the telemetry (PTME) IP core. + * + * @details + * This module is responsible for the encoding of telemetry packets according to the CCSDS + * standards CCSDS 131.0-B-3 (TM Synchronization and channel coding) and CCSDS 132.0-B-2 + * (TM Space Data Link Protocoll). The IP cores are implemented on the programmable logic and are + * accessible through the linux UIO driver. */ class Ptme : public PtmeIF, public SystemObject { public: diff --git a/mission/core/GenericFactory.cpp b/mission/core/GenericFactory.cpp index b6119eda..01871ff2 100644 --- a/mission/core/GenericFactory.cpp +++ b/mission/core/GenericFactory.cpp @@ -33,8 +33,11 @@ #include #include #include +#include +#include #include #include +#include #include "OBSWConfig.h" #include "devices/gpioIds.h" @@ -144,6 +147,14 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun PusTmFunnel::FunnelCfg cfdpFunnelCfg(objects::CFDP_TM_FUNNEL, "CfdpTmFunnel", *tmStore, *ipcStore, 50); *cfdpFunnel = new CfdpTmFunnel(cfdpFunnelCfg, config::EIVE_CFDP_APID); + auto* miscStore = new PersistentTmStore(objects::MISC_TM_STORE, "tm", "misc", + RolloverInterval::HOURLY, 2, *tmStore, sdcMan); + auto* okStore = new PersistentTmStore(objects::OK_TM_STORE, "tm", "ok", + RolloverInterval::MINUTELY, 30, *tmStore, sdcMan); + auto* notOkStore = new PersistentTmStore(objects::NOT_OK_TM_STORE, "tm", "nok", + RolloverInterval::MINUTELY, 30, *tmStore, sdcMan); + auto* hkStore = new PersistentTmStore(objects::HK_TM_STORE, "tm", "hk", + RolloverInterval::MINUTELY, 15, *tmStore, sdcMan); PusTmFunnel::FunnelCfg pusFunnelCfg(objects::PUS_TM_FUNNEL, "PusTmFunnel", *tmStore, *ipcStore, config::MAX_PUS_FUNNEL_QUEUE_DEPTH); *pusFunnel = new PusTmFunnel(pusFunnelCfg, *timeStamper, sdcMan); diff --git a/mission/core/GenericFactory.h b/mission/core/GenericFactory.h index 5902ff7b..8663d696 100644 --- a/mission/core/GenericFactory.h +++ b/mission/core/GenericFactory.h @@ -3,6 +3,7 @@ #include #include +#include #include "fsfw/objectmanager/SystemObjectIF.h" #include "fsfw/power/PowerSwitchIF.h" diff --git a/mission/tmtc/CMakeLists.txt b/mission/tmtc/CMakeLists.txt index c4c93ab6..ef97002c 100644 --- a/mission/tmtc/CMakeLists.txt +++ b/mission/tmtc/CMakeLists.txt @@ -5,6 +5,9 @@ target_sources( TmFunnelHandler.cpp TmFunnelBase.cpp CfdpTmFunnel.cpp + tmFilters.cpp + PusPacketFilter.cpp + TmStoreRouter.cpp Service15TmStorage.cpp PersistentTmStore.cpp PusTmFunnel.cpp) diff --git a/mission/tmtc/CcsdsIpCoreHandler.cpp b/mission/tmtc/CcsdsIpCoreHandler.cpp index b462f236..a0cb8d28 100644 --- a/mission/tmtc/CcsdsIpCoreHandler.cpp +++ b/mission/tmtc/CcsdsIpCoreHandler.cpp @@ -12,11 +12,11 @@ #include "fsfw/serviceinterface/serviceInterfaceDefintions.h" #include "mission/devices/devicedefinitions/SyrlinksDefinitions.h" -CcsdsIpCoreHandler::CcsdsIpCoreHandler(object_id_t objectId, object_id_t ptmeId, - object_id_t tcDestination, PtmeConfig* ptmeConfig, - GpioIF* gpioIF, gpioId_t enTxClock, gpioId_t enTxData) +CcsdsIpCoreHandler::CcsdsIpCoreHandler(object_id_t objectId, object_id_t tcDestination, + PtmeIF& ptme, PtmeConfig& ptmeConfig, GpioIF* gpioIF, + gpioId_t enTxClock, gpioId_t enTxData) : SystemObject(objectId), - ptmeId(ptmeId), + ptme(ptme), tcDestination(tcDestination), parameterHelper(this), actionHelper(this, nullptr), @@ -35,28 +35,20 @@ CcsdsIpCoreHandler::~CcsdsIpCoreHandler() {} ReturnValue_t CcsdsIpCoreHandler::performOperation(uint8_t operationCode) { readCommandQueue(); - handleTelemetry(); - handleTelecommands(); + // handleTelemetry(); return returnvalue::OK; } -void CcsdsIpCoreHandler::handleTelemetry() { - VirtualChannelMapIter iter; - for (iter = virtualChannelMap.begin(); iter != virtualChannelMap.end(); iter++) { - iter->second->performOperation(); - } -} - -void CcsdsIpCoreHandler::handleTelecommands() {} +// TODO: TM is sent to the respective VCs directly. +// void CcsdsIpCoreHandler::handleTelemetry() { +// VirtualChannelMapIter iter; +// for (iter = virtualChannelMap.begin(); iter != virtualChannelMap.end(); iter++) { +// iter->second->performOperation(); +// } +//} ReturnValue_t CcsdsIpCoreHandler::initialize() { ReturnValue_t result = returnvalue::OK; - PtmeIF* ptme = ObjectManager::instance()->get(ptmeId); - if (ptme == nullptr) { - sif::warning << "Invalid PTME object" << std::endl; - return ObjectManagerIF::CHILD_INIT_FAILED; - } - AcceptsTelecommandsIF* tcDistributor = ObjectManager::instance()->get(tcDestination); if (tcDistributor == nullptr) { @@ -89,10 +81,10 @@ ReturnValue_t CcsdsIpCoreHandler::initialize() { if (result != returnvalue::OK) { return result; } - iter->second->setPtmeObject(ptme); + iter->second->setPtmeObject(&ptme); } - result = ptmeConfig->initialize(); + result = ptmeConfig.initialize(); if (result != returnvalue::OK) { return ObjectManagerIF::CHILD_INIT_FAILED; } @@ -155,22 +147,22 @@ void CcsdsIpCoreHandler::addVirtualChannel(VcId_t vcId, VirtualChannel* virtualC } } -MessageQueueId_t CcsdsIpCoreHandler::getReportReceptionQueue(uint8_t virtualChannel) const { - if (virtualChannel < config::NUMBER_OF_VIRTUAL_CHANNELS) { - auto iter = virtualChannelMap.find(virtualChannel); - if (iter != virtualChannelMap.end()) { - return iter->second->getReportReceptionQueue(); - } else { - sif::warning << "CcsdsHandler::getReportReceptionQueue: Virtual channel with ID " - << static_cast(virtualChannel) << " not in virtual channel map" - << std::endl; - return MessageQueueIF::NO_QUEUE; - } - } else { - sif::debug << "CcsdsHandler::getReportReceptionQueue: Invalid virtual channel requested"; - } - return MessageQueueIF::NO_QUEUE; -} +// MessageQueueId_t CcsdsIpCoreHandler::getReportReceptionQueue(uint8_t virtualChannel) const { +// if (virtualChannel < config::NUMBER_OF_VIRTUAL_CHANNELS) { +// auto iter = virtualChannelMap.find(virtualChannel); +// if (iter != virtualChannelMap.end()) { +// return iter->second->getReportReceptionQueue(); +// } else { +// sif::warning << "CcsdsHandler::getReportReceptionQueue: Virtual channel with ID " +// << static_cast(virtualChannel) << " not in virtual channel map" +// << std::endl; +// return MessageQueueIF::NO_QUEUE; +// } +// } else { +// sif::debug << "CcsdsHandler::getReportReceptionQueue: Invalid virtual channel requested"; +// } +// return MessageQueueIF::NO_QUEUE; +// } ReturnValue_t CcsdsIpCoreHandler::getParameter(uint8_t domainId, uint8_t uniqueIdentifier, ParameterWrapper* parameterWrapper, @@ -182,7 +174,7 @@ ReturnValue_t CcsdsIpCoreHandler::getParameter(uint8_t domainId, uint8_t uniqueI uint32_t CcsdsIpCoreHandler::getIdentifier() const { return 0; } MessageQueueId_t CcsdsIpCoreHandler::getRequestQueue() const { - // Forward packets directly to TC distributor + // Forward packets directly to the CCSDS TC distributor return tcDistributorQueueId; } @@ -192,18 +184,18 @@ ReturnValue_t CcsdsIpCoreHandler::executeAction(ActionId_t actionId, MessageQueu switch (actionId) { case SET_LOW_RATE: { submode = static_cast(com::CcsdsSubmode::DATARATE_LOW); - result = ptmeConfig->setRate(RATE_100KBPS); + result = ptmeConfig.setRate(RATE_100KBPS); break; } case SET_HIGH_RATE: { submode = static_cast(com::CcsdsSubmode::DATARATE_HIGH); - result = ptmeConfig->setRate(RATE_500KBPS); + result = ptmeConfig.setRate(RATE_500KBPS); break; } case ARBITRARY_RATE: { uint32_t bitrate = 0; SerializeAdapter::deSerialize(&bitrate, &data, &size, SerializeIF::Endianness::BIG); - result = ptmeConfig->setRate(bitrate); + result = ptmeConfig.setRate(bitrate); break; } case EN_TRANSMITTER: { @@ -221,19 +213,19 @@ ReturnValue_t CcsdsIpCoreHandler::executeAction(ActionId_t actionId, MessageQueu return EXECUTION_FINISHED; } case ENABLE_TX_CLK_MANIPULATOR: { - result = ptmeConfig->configTxManipulator(true); + result = ptmeConfig.configTxManipulator(true); break; } case DISABLE_TX_CLK_MANIPULATOR: { - result = ptmeConfig->configTxManipulator(false); + result = ptmeConfig.configTxManipulator(false); break; } case UPDATE_ON_RISING_EDGE: { - result = ptmeConfig->invertTxClock(false); + result = ptmeConfig.invertTxClock(false); break; } case UPDATE_ON_FALLING_EDGE: { - result = ptmeConfig->invertTxClock(true); + result = ptmeConfig.invertTxClock(true); break; } default: @@ -283,13 +275,13 @@ ReturnValue_t CcsdsIpCoreHandler::checkModeCommand(Mode_t mode, Submode_t submod void CcsdsIpCoreHandler::startTransition(Mode_t mode, Submode_t submode) { auto rateHigh = [&]() { - ReturnValue_t result = ptmeConfig->setRate(RATE_500KBPS); + ReturnValue_t result = ptmeConfig.setRate(RATE_500KBPS); if (result == returnvalue::OK) { this->mode = HasModesIF::MODE_ON; } }; auto rateLow = [&]() { - ReturnValue_t result = ptmeConfig->setRate(RATE_100KBPS); + ReturnValue_t result = ptmeConfig.setRate(RATE_100KBPS); if (result == returnvalue::OK) { this->mode = HasModesIF::MODE_ON; } diff --git a/mission/tmtc/CcsdsIpCoreHandler.h b/mission/tmtc/CcsdsIpCoreHandler.h index 356c2f8d..f82e28fd 100644 --- a/mission/tmtc/CcsdsIpCoreHandler.h +++ b/mission/tmtc/CcsdsIpCoreHandler.h @@ -39,7 +39,7 @@ class CcsdsIpCoreHandler : public SystemObject, public ModeTreeChildIF, public ModeTreeConnectionIF, public HasModesIF, - public AcceptsTelemetryIF, + // public AcceptsTelemetryIF, public AcceptsTelecommandsIF, public ReceivesParameterMessagesIF, public HasActionsIF { @@ -58,8 +58,8 @@ class CcsdsIpCoreHandler : public SystemObject, * @param enTxClock GPIO ID of RS485 tx clock enable * @param enTxData GPIO ID of RS485 tx data enable */ - CcsdsIpCoreHandler(object_id_t objectId, object_id_t ptmeId, object_id_t tcDestination, - PtmeConfig* ptmeConfig, GpioIF* gpioIF, gpioId_t enTxClock, gpioId_t enTxData); + CcsdsIpCoreHandler(object_id_t objectId, object_id_t tcDestination, PtmeIF& ptme, + PtmeConfig& ptmeConfig, GpioIF* gpioIF, gpioId_t enTxClock, gpioId_t enTxData); ~CcsdsIpCoreHandler(); @@ -82,7 +82,7 @@ class CcsdsIpCoreHandler : public SystemObject, */ void addVirtualChannel(VcId_t virtualChannelId, VirtualChannel* virtualChannel); - MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0) const override; + // MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0) const override; ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueIdentifier, ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues, uint16_t startAtIndex); @@ -132,11 +132,9 @@ class CcsdsIpCoreHandler : public SystemObject, using VirtualChannelMap = std::unordered_map; using VirtualChannelMapIter = VirtualChannelMap::iterator; + PtmeIF& ptme; VirtualChannelMap virtualChannelMap; - // Object ID of PTME object - object_id_t ptmeId; - object_id_t tcDestination; MessageQueueIF* commandQueue = nullptr; @@ -150,7 +148,7 @@ class CcsdsIpCoreHandler : public SystemObject, MessageQueueId_t tcDistributorQueueId = MessageQueueIF::NO_QUEUE; - PtmeConfig* ptmeConfig = nullptr; + PtmeConfig& ptmeConfig; GpioIF* gpioIF = nullptr; // GPIO to enable RS485 transceiver for TX clock @@ -162,7 +160,6 @@ class CcsdsIpCoreHandler : public SystemObject, void readCommandQueue(void); void handleTelemetry(); - void handleTelecommands(); /** * @brief Forward link state to virtual channels. diff --git a/mission/tmtc/PersistentTmStore.cpp b/mission/tmtc/PersistentTmStore.cpp index 7b29e06f..694a50b7 100644 --- a/mission/tmtc/PersistentTmStore.cpp +++ b/mission/tmtc/PersistentTmStore.cpp @@ -75,41 +75,6 @@ ReturnValue_t PersistentTmStore::handleCommandQueue(StorageManagerIF& ipcStore, return returnvalue::OK; } -ReturnValue_t PersistentTmStore::passPacket(PusTmReader& reader) { - bool inApidList = false; - if (filter.apid) { - auto& apidFilter = filter.apid.value(); - if (std::find(apidFilter.begin(), apidFilter.end(), reader.getApid()) != apidFilter.end()) { - if (not filter.serviceSubservices and not filter.services) { - return storePacket(reader); - } - inApidList = true; - } - } - std::pair serviceSubservice; - serviceSubservice.first = reader.getService(); - serviceSubservice.second = reader.getSubService(); - if (filter.services) { - auto& serviceFilter = filter.services.value(); - if (std::find(serviceFilter.begin(), serviceFilter.end(), serviceSubservice.first) != - serviceFilter.end()) { - if (filter.apid and inApidList) { - return storePacket(reader); - } - } - } - if (filter.serviceSubservices) { - auto& serviceSubserviceFilter = filter.serviceSubservices.value(); - if (std::find(serviceSubserviceFilter.begin(), serviceSubserviceFilter.end(), - serviceSubservice) != serviceSubserviceFilter.end()) { - if (filter.apid and inApidList) { - return storePacket(reader); - } - } - } - return returnvalue::OK; -} - void PersistentTmStore::dumpFrom(uint32_t fromUnixSeconds, TmFunnelBase& tmFunnel) { return dumpFromUpTo(fromUnixSeconds, currentTv.tv_sec, tmFunnel); } @@ -182,31 +147,6 @@ bool PersistentTmStore::updateBaseDir() { return true; } -void PersistentTmStore::addApid(uint16_t apid) { - if (not filter.apid) { - filter.apid = std::vector({apid}); - return; - } - filter.apid.value().push_back(apid); -} - -void PersistentTmStore::addService(uint8_t service) { - if (not filter.services) { - filter.services = std::vector({service}); - return; - } - filter.services.value().push_back(service); -} - -void PersistentTmStore::addServiceSubservice(uint8_t service, uint8_t subservice) { - if (not filter.serviceSubservices) { - filter.serviceSubservices = - std::vector>({std::pair(service, subservice)}); - return; - } - filter.serviceSubservices.value().emplace_back(service, subservice); -} - void PersistentTmStore::deleteUpTo(uint32_t unixSeconds) { using namespace std::filesystem; for (auto const& file : directory_iterator(basePath)) { diff --git a/mission/tmtc/PersistentTmStore.h b/mission/tmtc/PersistentTmStore.h index d8bc9acf..280fa4ac 100644 --- a/mission/tmtc/PersistentTmStore.h +++ b/mission/tmtc/PersistentTmStore.h @@ -13,12 +13,6 @@ #include "TmFunnelBase.h" #include "eive/eventSubsystemIds.h" -struct PacketFilter { - std::optional> apid; - std::optional> services; - std::optional>> serviceSubservices; -}; - enum class RolloverInterval { MINUTELY, HOURLY, DAILY }; class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject { @@ -37,15 +31,12 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject { ReturnValue_t initializeTmStore(); ReturnValue_t handleCommandQueue(StorageManagerIF& ipcStore, TmFunnelBase& tmFunnel); - void addApid(uint16_t apid); - void addService(uint8_t service); - void addServiceSubservice(uint8_t service, uint8_t subservice); - void deleteUpTo(uint32_t unixSeconds); void dumpFrom(uint32_t fromUnixSeconds, TmFunnelBase& tmFunnel); void dumpFromUpTo(uint32_t fromUnixSeconds, uint32_t upToUnixSeconds, TmFunnelBase& tmFunnel); - ReturnValue_t passPacket(PusTmReader& reader); + // ReturnValue_t passPacket(PusTmReader& reader); + ReturnValue_t storePacket(PusTmReader& reader); private: static constexpr uint8_t MAX_FILES_IN_ONE_SECOND = 10; @@ -54,7 +45,7 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject { static constexpr char FILE_DATE_FORMAT[] = "%FT%H%M%SZ"; MessageQueueIF* tcQueue; - PacketFilter filter; + // PacketFilter filter; CdsShortTimeStamper timeReader; bool baseDirUninitialized = true; const char* baseDir; @@ -81,7 +72,6 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject { void fileToPackets(const std::filesystem::path& path, uint32_t unixStamp, TmFunnelBase& funnel); bool updateBaseDir(); ReturnValue_t assignAndOrCreateMostRecentFile(); - ReturnValue_t storePacket(PusTmReader& reader); }; #endif /* MISSION_TMTC_TMSTOREBACKEND_H_ */ diff --git a/mission/tmtc/PusPacketFilter.cpp b/mission/tmtc/PusPacketFilter.cpp new file mode 100644 index 00000000..51abc02b --- /dev/null +++ b/mission/tmtc/PusPacketFilter.cpp @@ -0,0 +1,64 @@ +#include + +#include + +PusPacketFilter::PusPacketFilter() {} + +void PusPacketFilter::addApid(uint16_t apid) { + if (not this->apid) { + this->apid = std::vector({apid}); + return; + } + this->apid.value().push_back(apid); +} + +void PusPacketFilter::addService(uint8_t service) { + if (not this->services) { + this->services = std::vector({service}); + return; + } + this->services.value().push_back(service); +} + +void PusPacketFilter::addServiceSubservice(uint8_t service, uint8_t subservice) { + if (not serviceSubservices) { + serviceSubservices = std::vector>({std::pair(service, subservice)}); + return; + } + serviceSubservices.value().emplace_back(service, subservice); +} + +bool PusPacketFilter::packetMatches(PusTmReader& reader) const { + bool inApidList = false; + if (apid) { + auto& apidFilter = apid.value(); + if (std::find(apidFilter.begin(), apidFilter.end(), reader.getApid()) != apidFilter.end()) { + if (not serviceSubservices and not services) { + return true; + } + inApidList = true; + } + } + std::pair serviceSubservice; + serviceSubservice.first = reader.getService(); + serviceSubservice.second = reader.getSubService(); + if (services) { + auto& serviceFilter = services.value(); + if (std::find(serviceFilter.begin(), serviceFilter.end(), serviceSubservice.first) != + serviceFilter.end()) { + if (apid and inApidList) { + return true; + } + } + } + if (serviceSubservices) { + auto& serviceSubserviceFilter = serviceSubservices.value(); + if (std::find(serviceSubserviceFilter.begin(), serviceSubserviceFilter.end(), + serviceSubservice) != serviceSubserviceFilter.end()) { + if (apid and inApidList) { + return true; + } + } + } + return false; +} diff --git a/mission/tmtc/PusPacketFilter.h b/mission/tmtc/PusPacketFilter.h new file mode 100644 index 00000000..78d9cc18 --- /dev/null +++ b/mission/tmtc/PusPacketFilter.h @@ -0,0 +1,24 @@ +#ifndef MISSION_TMTC_PUSPACKETFILTER_H_ +#define MISSION_TMTC_PUSPACKETFILTER_H_ + +#include + +#include +#include + +class PusPacketFilter { + public: + PusPacketFilter(); + + bool packetMatches(PusTmReader& reader) const; + void addApid(uint16_t apid); + void addService(uint8_t service); + void addServiceSubservice(uint8_t service, uint8_t subservice); + + private: + std::optional> apid; + std::optional> services; + std::optional>> serviceSubservices; +}; + +#endif /* MISSION_TMTC_PUSPACKETFILTER_H_ */ diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index 08a047a0..ad763ff5 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -12,48 +12,14 @@ PusTmFunnel::PusTmFunnel(TmFunnelBase::FunnelCfg cfg, TimeReaderIF &timeReader, SdCardMountedIF &sdcMan) - : TmFunnelBase(cfg), - timeReader(timeReader), - miscStore(objects::MISC_TM_STORE, "tm", "misc", RolloverInterval::HOURLY, 2, tmStore, sdcMan), - okStore(objects::OK_TM_STORE, "tm", "ok", RolloverInterval::MINUTELY, 30, tmStore, sdcMan), - notOkStore(objects::NOT_OK_TM_STORE, "tm", "nok", RolloverInterval::MINUTELY, 30, tmStore, - sdcMan), - hkStore(objects::HK_TM_STORE, "tm", "hk", RolloverInterval::MINUTELY, 15, tmStore, sdcMan), - sdcMan(sdcMan) { - Clock::getClock_timeval(¤tTv); - Clock::getUptime(&lastTvUpdate); - hkStore.addApid(config::EIVE_PUS_APID); - hkStore.addService(pus::PUS_SERVICE_3); - miscStore.addApid(config::EIVE_PUS_APID); - miscStore.addService(pus::PUS_SERVICE_17); - miscStore.addService(pus::PUS_SERVICE_2); - miscStore.addService(pus::PUS_SERVICE_200); - miscStore.addService(pus::PUS_SERVICE_201); - miscStore.addService(pus::PUS_SERVICE_9); - miscStore.addService(pus::PUS_SERVICE_20); - okStore.addApid(config::EIVE_PUS_APID); - okStore.addServiceSubservice(pus::PUS_SERVICE_5, - Service5EventReporting::Subservice::NORMAL_REPORT); - okStore.addService(pus::PUS_SERVICE_8); - okStore.addServiceSubservice(pus::PUS_SERVICE_1, 1); - okStore.addServiceSubservice(pus::PUS_SERVICE_1, 3); - okStore.addServiceSubservice(pus::PUS_SERVICE_1, 5); - okStore.addServiceSubservice(pus::PUS_SERVICE_1, 7); - notOkStore.addApid(config::EIVE_PUS_APID); - notOkStore.addServiceSubservice(pus::PUS_SERVICE_5, 2); - notOkStore.addServiceSubservice(pus::PUS_SERVICE_5, 3); - notOkStore.addServiceSubservice(pus::PUS_SERVICE_5, 4); - notOkStore.addServiceSubservice(pus::PUS_SERVICE_1, 2); - notOkStore.addServiceSubservice(pus::PUS_SERVICE_1, 4); - notOkStore.addServiceSubservice(pus::PUS_SERVICE_1, 6); - notOkStore.addServiceSubservice(pus::PUS_SERVICE_1, 8); -} + : TmFunnelBase(cfg), timeReader(timeReader), sdcMan(sdcMan) {} PusTmFunnel::~PusTmFunnel() = default; ReturnValue_t PusTmFunnel::performOperation(uint8_t) { CommandMessage cmdMessage; ReturnValue_t result; + /* try { result = okStore.handleCommandQueue(ipcStore, *this); if (result != returnvalue::OK) { @@ -75,6 +41,7 @@ ReturnValue_t PusTmFunnel::performOperation(uint8_t) { } catch (const std::bad_optional_access &e) { sif::error << e.what() << "when handling TM store command" << std::endl; } + */ TmTcMessage currentMessage; unsigned int count = 0; @@ -119,38 +86,45 @@ ReturnValue_t PusTmFunnel::handleTmPacket(TmTcMessage &message) { sourceSequenceCount = sourceSequenceCount % ccsds::LIMIT_SEQUENCE_COUNT; packet.updateErrorControl(); - timeval currentUptime{}; - Clock::getUptime(¤tUptime); - if (currentUptime.tv_sec - lastTvUpdate.tv_sec > - static_cast(TV_UPDATE_INTERVAL_SECS)) { - Clock::getClock_timeval(¤tTv); - lastTvUpdate = currentUptime; - } - - bool sdcUsable = sdcMan.isSdCardUsable(std::nullopt); - initStoresIfPossible(sdcUsable); - if (sdcUsable) { - miscStore.passPacket(packet); - okStore.passPacket(packet); - notOkStore.passPacket(packet); - hkStore.passPacket(packet); - } + // TODO: 1. Send packet to persistent TM store when applicable. + // 2. Send packet to live TM VC + // 3. Send packet to TCP/IP destination return sendPacketToDestinations(origStoreId, message, packetData, size); + // timeval currentUptime{}; + // Clock::getUptime(¤tUptime); + // if (currentUptime.tv_sec - lastTvUpdate.tv_sec > + // static_cast(TV_UPDATE_INTERVAL_SECS)) { + // Clock::getClock_timeval(¤tTv); + // lastTvUpdate = currentUptime; + // } + + // bool sdcUsable = sdcMan.isSdCardUsable(std::nullopt); + // initStoresIfPossible(sdcUsable); + // if (sdcUsable) { + // miscStore.passPacket(packet); + // okStore.passPacket(packet); + // notOkStore.passPacket(packet); + // hkStore.passPacket(packet); + // } } const char *PusTmFunnel::getName() const { return "PUS TM Funnel"; } void PusTmFunnel::initStoresIfPossible(bool sdCardUsable) { if (not storesInitialized and sdCardUsable and sdcMan.getCurrentMountPrefix() != nullptr) { - miscStore.initializeTmStore(); - okStore.initializeTmStore(); - hkStore.initializeTmStore(); - notOkStore.initializeTmStore(); + // miscStore.initializeTmStore(); + // okStore.initializeTmStore(); + // hkStore.initializeTmStore(); + // notOkStore.initializeTmStore(); storesInitialized = true; } } ReturnValue_t PusTmFunnel::initialize() { - initStoresIfPossible(sdcMan.isSdCardUsable(std::nullopt)); + // initStoresIfPossible(sdcMan.isSdCardUsable(std::nullopt)); return returnvalue::OK; } + +void PusTmFunnel::addPersistentTmStoreRouting(PusPacketFilter filter, MessageQueueId_t dest) { + router.addRouting(filter, dest); +} diff --git a/mission/tmtc/PusTmFunnel.h b/mission/tmtc/PusTmFunnel.h index ab6a9480..774737dc 100644 --- a/mission/tmtc/PusTmFunnel.h +++ b/mission/tmtc/PusTmFunnel.h @@ -7,6 +7,7 @@ #include #include #include +#include #include @@ -28,6 +29,7 @@ class PusTmFunnel : public TmFunnelBase { ~PusTmFunnel() override; ReturnValue_t performOperation(uint8_t operationCode); + void addPersistentTmStoreRouting(PusPacketFilter filter, MessageQueueId_t dest); private: // Update TV stamp every 5 minutes @@ -36,13 +38,8 @@ class PusTmFunnel : public TmFunnelBase { uint16_t sourceSequenceCount = 0; TimeReaderIF &timeReader; bool storesInitialized = false; - timeval currentTv{}; - timeval lastTvUpdate{}; - PersistentTmStore miscStore; - PersistentTmStore okStore; - PersistentTmStore notOkStore; - PersistentTmStore hkStore; SdCardMountedIF &sdcMan; + PersistentTmStoreRouter router; ReturnValue_t handleTmPacket(TmTcMessage &message); void initStoresIfPossible(bool sdCardUsable); diff --git a/mission/tmtc/TmStoreRouter.cpp b/mission/tmtc/TmStoreRouter.cpp new file mode 100644 index 00000000..d958574e --- /dev/null +++ b/mission/tmtc/TmStoreRouter.cpp @@ -0,0 +1,19 @@ +#include "TmStoreRouter.h" + +#include + +PersistentTmStoreRouter::PersistentTmStoreRouter() = default; + +bool PersistentTmStoreRouter::packetMatches(PusTmReader& reader, MessageQueueId_t& destination) { + for (const auto filterAndDest : routerMap) { + if (filterAndDest.first.packetMatches(reader)) { + destination = filterAndDest.second; + return true; + } + } + return false; +} + +void PersistentTmStoreRouter::addRouting(PusPacketFilter filter, MessageQueueId_t destination) { + routerMap.emplace_back(std::move(filter), destination); +} diff --git a/mission/tmtc/TmStoreRouter.h b/mission/tmtc/TmStoreRouter.h new file mode 100644 index 00000000..9daa4889 --- /dev/null +++ b/mission/tmtc/TmStoreRouter.h @@ -0,0 +1,18 @@ +#ifndef MISSION_TMTC_PUSTMROUTER_H_ +#define MISSION_TMTC_PUSTMROUTER_H_ + +#include +#include + +class PersistentTmStoreRouter { + public: + PersistentTmStoreRouter(); + + bool packetMatches(PusTmReader& reader, MessageQueueId_t& destination); + void addRouting(PusPacketFilter filter, MessageQueueId_t destination); + + private: + std::vector> routerMap; +}; + +#endif /* MISSION_TMTC_PUSTMROUTER_H_ */ diff --git a/mission/tmtc/VirtualChannel.cpp b/mission/tmtc/VirtualChannel.cpp index 6a24cc09..a6e7732c 100644 --- a/mission/tmtc/VirtualChannel.cpp +++ b/mission/tmtc/VirtualChannel.cpp @@ -7,12 +7,12 @@ #include "fsfw/serviceinterface/ServiceInterfaceStream.h" #include "fsfw/tmtcservices/TmTcMessage.h" -VirtualChannel::VirtualChannel(uint8_t vcId, uint32_t tmQueueDepth, object_id_t ownerId) - : vcId(vcId) { - auto mqArgs = MqArgs(ownerId, reinterpret_cast(vcId)); +VirtualChannel::VirtualChannel(object_id_t objectId, uint8_t vcId, const char* vcName, + uint32_t tmQueueDepth) + : SystemObject(objectId), vcId(vcId), vcName(vcName) { + auto mqArgs = MqArgs(objectId, reinterpret_cast(vcId)); tmQueue = QueueFactory::instance()->createMessageQueue( tmQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs); - vcName = "VC " + vcId; } ReturnValue_t VirtualChannel::initialize() { @@ -24,38 +24,40 @@ ReturnValue_t VirtualChannel::initialize() { return returnvalue::OK; } -ReturnValue_t VirtualChannel::performOperation() { +ReturnValue_t VirtualChannel::performOperation(uint8_t opCode) { ReturnValue_t result = returnvalue::OK; TmTcMessage message; + // To be able to push high datarates, we use a custom permanent loop. + while (true) { + unsigned int count = 0; + while (tmQueue->receiveMessage(&message) == returnvalue::OK) { + store_address_t storeId = message.getStorageId(); + const uint8_t* data = nullptr; + size_t size = 0; + result = tmStore->getData(storeId, &data, &size); + if (result != returnvalue::OK) { + sif::warning << "VirtualChannel::performOperation: Failed to read data from TM store" + << std::endl; + tmStore->deleteData(storeId); + return result; + } - unsigned int count = 0; - while (tmQueue->receiveMessage(&message) == returnvalue::OK) { - store_address_t storeId = message.getStorageId(); - const uint8_t* data = nullptr; - size_t size = 0; - result = tmStore->getData(storeId, &data, &size); - if (result != returnvalue::OK) { - sif::warning << "VirtualChannel::performOperation: Failed to read data from TM store" - << std::endl; + if (linkIsUp) { + result = ptme->writeToVc(vcId, data, size); + } tmStore->deleteData(storeId); - return result; - } + if (result != returnvalue::OK) { + return result; + } - if (linkIsUp) { - result = ptme->writeToVc(vcId, data, size); - } - tmStore->deleteData(storeId); - if (result != returnvalue::OK) { - return result; - } - - count++; - if (count == 500) { - sif::error << "VirtualChannel: Possible message storm detected" << std::endl; - break; + count++; + if (count == 500) { + sif::error << "VirtualChannel: Possible message storm detected" << std::endl; + break; + } } } - return result; + return returnvalue::FAILED; } MessageQueueId_t VirtualChannel::getReportReceptionQueue(uint8_t virtualChannel) const { diff --git a/mission/tmtc/VirtualChannel.h b/mission/tmtc/VirtualChannel.h index 96d7ba9d..98caa004 100644 --- a/mission/tmtc/VirtualChannel.h +++ b/mission/tmtc/VirtualChannel.h @@ -2,6 +2,8 @@ #define VIRTUALCHANNEL_H_ #include +#include +#include #include #include "OBSWConfig.h" @@ -16,7 +18,7 @@ class StorageManagerIF; * * @author J. Meier */ -class VirtualChannel : public AcceptsTelemetryIF { +class VirtualChannel : public SystemObject, public ExecutableObjectIF, public AcceptsTelemetryIF { public: /** * @brief Constructor @@ -24,11 +26,11 @@ class VirtualChannel : public AcceptsTelemetryIF { * @param vcId The virtual channel id assigned to this object * @param tmQueueDepth Queue depth of queue receiving telemetry from other objects */ - VirtualChannel(uint8_t vcId, uint32_t tmQueueDepth, object_id_t ownerId); + VirtualChannel(object_id_t objectId, uint8_t vcId, const char* vcName, uint32_t tmQueueDepth); - ReturnValue_t initialize(); + ReturnValue_t initialize() override; MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0) const override; - ReturnValue_t performOperation(); + ReturnValue_t performOperation(uint8_t opCode) override; /** * @brief Sets the PTME object which handles access to the PTME IP Core. diff --git a/mission/tmtc/tmFilters.cpp b/mission/tmtc/tmFilters.cpp new file mode 100644 index 00000000..540df3de --- /dev/null +++ b/mission/tmtc/tmFilters.cpp @@ -0,0 +1,51 @@ +#include "tmFilters.h" + +#include +#include + +#include "eive/definitions.h" + +PusPacketFilter filters::hkFilter() { + PusPacketFilter hkFilter; + hkFilter.addApid(config::EIVE_PUS_APID); + hkFilter.addService(pus::PUS_SERVICE_3); + return hkFilter; +} + +PusPacketFilter filters::miscFilter() { + PusPacketFilter miscFilter; + miscFilter.addApid(config::EIVE_PUS_APID); + miscFilter.addService(pus::PUS_SERVICE_17); + miscFilter.addService(pus::PUS_SERVICE_2); + miscFilter.addService(pus::PUS_SERVICE_200); + miscFilter.addService(pus::PUS_SERVICE_201); + miscFilter.addService(pus::PUS_SERVICE_9); + miscFilter.addService(pus::PUS_SERVICE_20); + return miscFilter; +} + +PusPacketFilter filters::okFilter() { + PusPacketFilter okFilter; + okFilter.addApid(config::EIVE_PUS_APID); + okFilter.addServiceSubservice(pus::PUS_SERVICE_5, + Service5EventReporting::Subservice::NORMAL_REPORT); + okFilter.addService(pus::PUS_SERVICE_8); + okFilter.addServiceSubservice(pus::PUS_SERVICE_1, 1); + okFilter.addServiceSubservice(pus::PUS_SERVICE_1, 3); + okFilter.addServiceSubservice(pus::PUS_SERVICE_1, 5); + okFilter.addServiceSubservice(pus::PUS_SERVICE_1, 7); + return okFilter; +} + +PusPacketFilter filters::notOkFilter() { + PusPacketFilter notOkFilter; + notOkFilter.addApid(config::EIVE_PUS_APID); + notOkFilter.addServiceSubservice(pus::PUS_SERVICE_5, 2); + notOkFilter.addServiceSubservice(pus::PUS_SERVICE_5, 3); + notOkFilter.addServiceSubservice(pus::PUS_SERVICE_5, 4); + notOkFilter.addServiceSubservice(pus::PUS_SERVICE_1, 2); + notOkFilter.addServiceSubservice(pus::PUS_SERVICE_1, 4); + notOkFilter.addServiceSubservice(pus::PUS_SERVICE_1, 6); + notOkFilter.addServiceSubservice(pus::PUS_SERVICE_1, 8); + return notOkFilter; +} diff --git a/mission/tmtc/tmFilters.h b/mission/tmtc/tmFilters.h new file mode 100644 index 00000000..fc5318f9 --- /dev/null +++ b/mission/tmtc/tmFilters.h @@ -0,0 +1,14 @@ +#ifndef MISSION_TMTC_FILTERS_H_ +#define MISSION_TMTC_FILTERS_H_ +#include + +namespace filters { + +PusPacketFilter hkFilter(); +PusPacketFilter miscFilter(); +PusPacketFilter okFilter(); +PusPacketFilter notOkFilter(); + +} // namespace filters + +#endif /* MISSION_TMTC_FILTERS_H_ */