Refactor TM handling #450
@ -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
|
||||
|
@ -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");
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <mission/tmtc/CcsdsIpCoreHandler.h>
|
||||
#include <mission/tmtc/CfdpTmFunnel.h>
|
||||
#include <mission/tmtc/PusTmFunnel.h>
|
||||
#include <mission/tmtc/TmStoreRouter.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
@ -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);
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -33,8 +33,11 @@
|
||||
#include <mission/system/objects/SusAssembly.h>
|
||||
#include <mission/system/objects/TcsBoardAssembly.h>
|
||||
#include <mission/tmtc/CfdpTmFunnel.h>
|
||||
#include <mission/tmtc/PersistentTmStore.h>
|
||||
#include <mission/tmtc/PusPacketFilter.h>
|
||||
#include <mission/tmtc/PusTmFunnel.h>
|
||||
#include <mission/tmtc/TmFunnelHandler.h>
|
||||
#include <mission/tmtc/TmStoreRouter.h>
|
||||
|
||||
#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);
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <mission/memory/SdCardMountedIF.h>
|
||||
#include <mission/tmtc/TmStoreRouter.h>
|
||||
|
||||
#include "fsfw/objectmanager/SystemObjectIF.h"
|
||||
#include "fsfw/power/PowerSwitchIF.h"
|
||||
|
@ -5,6 +5,9 @@ target_sources(
|
||||
TmFunnelHandler.cpp
|
||||
TmFunnelBase.cpp
|
||||
CfdpTmFunnel.cpp
|
||||
tmFilters.cpp
|
||||
PusPacketFilter.cpp
|
||||
TmStoreRouter.cpp
|
||||
Service15TmStorage.cpp
|
||||
PersistentTmStore.cpp
|
||||
PusTmFunnel.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<PtmeIF>(ptmeId);
|
||||
if (ptme == nullptr) {
|
||||
sif::warning << "Invalid PTME object" << std::endl;
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
|
||||
AcceptsTelecommandsIF* tcDistributor =
|
||||
ObjectManager::instance()->get<AcceptsTelecommandsIF>(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<unsigned int>(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<unsigned int>(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<Submode_t>(com::CcsdsSubmode::DATARATE_LOW);
|
||||
result = ptmeConfig->setRate(RATE_100KBPS);
|
||||
result = ptmeConfig.setRate(RATE_100KBPS);
|
||||
break;
|
||||
}
|
||||
case SET_HIGH_RATE: {
|
||||
submode = static_cast<Submode_t>(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;
|
||||
}
|
||||
|
@ -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<VcId_t, VirtualChannel*>;
|
||||
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.
|
||||
|
@ -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<uint8_t, uint8_t> 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<uint16_t>({apid});
|
||||
return;
|
||||
}
|
||||
filter.apid.value().push_back(apid);
|
||||
}
|
||||
|
||||
void PersistentTmStore::addService(uint8_t service) {
|
||||
if (not filter.services) {
|
||||
filter.services = std::vector<uint8_t>({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<uint8_t, uint8_t>>({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)) {
|
||||
|
@ -13,12 +13,6 @@
|
||||
#include "TmFunnelBase.h"
|
||||
#include "eive/eventSubsystemIds.h"
|
||||
|
||||
struct PacketFilter {
|
||||
std::optional<std::vector<uint16_t>> apid;
|
||||
std::optional<std::vector<uint8_t>> services;
|
||||
std::optional<std::vector<std::pair<uint8_t, uint8_t>>> 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_ */
|
||||
|
64
mission/tmtc/PusPacketFilter.cpp
Normal file
64
mission/tmtc/PusPacketFilter.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
#include <mission/tmtc/PusPacketFilter.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
PusPacketFilter::PusPacketFilter() {}
|
||||
|
||||
void PusPacketFilter::addApid(uint16_t apid) {
|
||||
if (not this->apid) {
|
||||
this->apid = std::vector<uint16_t>({apid});
|
||||
return;
|
||||
}
|
||||
this->apid.value().push_back(apid);
|
||||
}
|
||||
|
||||
void PusPacketFilter::addService(uint8_t service) {
|
||||
if (not this->services) {
|
||||
this->services = std::vector<uint8_t>({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<uint8_t, uint8_t>>({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<uint8_t, uint8_t> 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;
|
||||
}
|
24
mission/tmtc/PusPacketFilter.h
Normal file
24
mission/tmtc/PusPacketFilter.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef MISSION_TMTC_PUSPACKETFILTER_H_
|
||||
#define MISSION_TMTC_PUSPACKETFILTER_H_
|
||||
|
||||
#include <fsfw/tmtcpacket/pus/tm/PusTmReader.h>
|
||||
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
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<std::vector<uint16_t>> apid;
|
||||
std::optional<std::vector<uint8_t>> services;
|
||||
std::optional<std::vector<std::pair<uint8_t, uint8_t>>> serviceSubservices;
|
||||
};
|
||||
|
||||
#endif /* MISSION_TMTC_PUSPACKETFILTER_H_ */
|
@ -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<signed int>(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<signed int>(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);
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <fsfw/tmtcservices/AcceptsTelemetryIF.h>
|
||||
#include <fsfw/tmtcservices/TmTcMessage.h>
|
||||
#include <mission/tmtc/TmFunnelBase.h>
|
||||
#include <mission/tmtc/TmStoreRouter.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
@ -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);
|
||||
|
19
mission/tmtc/TmStoreRouter.cpp
Normal file
19
mission/tmtc/TmStoreRouter.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
#include "TmStoreRouter.h"
|
||||
|
||||
#include <fsfw/ipc/MessageQueueIF.h>
|
||||
|
||||
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);
|
||||
}
|
18
mission/tmtc/TmStoreRouter.h
Normal file
18
mission/tmtc/TmStoreRouter.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef MISSION_TMTC_PUSTMROUTER_H_
|
||||
#define MISSION_TMTC_PUSTMROUTER_H_
|
||||
|
||||
#include <fsfw/ipc/messageQueueDefinitions.h>
|
||||
#include <mission/tmtc/PusPacketFilter.h>
|
||||
|
||||
class PersistentTmStoreRouter {
|
||||
public:
|
||||
PersistentTmStoreRouter();
|
||||
|
||||
bool packetMatches(PusTmReader& reader, MessageQueueId_t& destination);
|
||||
void addRouting(PusPacketFilter filter, MessageQueueId_t destination);
|
||||
|
||||
private:
|
||||
std::vector<std::pair<PusPacketFilter, MessageQueueId_t>> routerMap;
|
||||
};
|
||||
|
||||
#endif /* MISSION_TMTC_PUSTMROUTER_H_ */
|
@ -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<void*>(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<void*>(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 {
|
||||
|
@ -2,6 +2,8 @@
|
||||
#define VIRTUALCHANNEL_H_
|
||||
|
||||
#include <fsfw/ipc/MessageQueueIF.h>
|
||||
#include <fsfw/objectmanager/SystemObject.h>
|
||||
#include <fsfw/tasks/ExecutableObjectIF.h>
|
||||
#include <linux/ipcore/PtmeIF.h>
|
||||
|
||||
#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.
|
||||
|
51
mission/tmtc/tmFilters.cpp
Normal file
51
mission/tmtc/tmFilters.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
#include "tmFilters.h"
|
||||
|
||||
#include <fsfw/pus/Service5EventReporting.h>
|
||||
#include <tmtc/pusIds.h>
|
||||
|
||||
#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;
|
||||
}
|
14
mission/tmtc/tmFilters.h
Normal file
14
mission/tmtc/tmFilters.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef MISSION_TMTC_FILTERS_H_
|
||||
#define MISSION_TMTC_FILTERS_H_
|
||||
#include <mission/tmtc/PusPacketFilter.h>
|
||||
|
||||
namespace filters {
|
||||
|
||||
PusPacketFilter hkFilter();
|
||||
PusPacketFilter miscFilter();
|
||||
PusPacketFilter okFilter();
|
||||
PusPacketFilter notOkFilter();
|
||||
|
||||
} // namespace filters
|
||||
|
||||
#endif /* MISSION_TMTC_FILTERS_H_ */
|
Loading…
Reference in New Issue
Block a user