start groundwork for new TM downlink arch

This commit is contained in:
2023-03-09 01:32:27 +01:00
parent c1b43bb504
commit 21899d663e
24 changed files with 379 additions and 266 deletions

View File

@ -5,6 +5,9 @@ target_sources(
TmFunnelHandler.cpp
TmFunnelBase.cpp
CfdpTmFunnel.cpp
tmFilters.cpp
PusPacketFilter.cpp
TmStoreRouter.cpp
Service15TmStorage.cpp
PersistentTmStore.cpp
PusTmFunnel.cpp)

View File

@ -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;
}

View File

@ -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.

View File

@ -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)) {

View File

@ -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_ */

View 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;
}

View 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_ */

View File

@ -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(&currentTv);
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(&currentUptime);
if (currentUptime.tv_sec - lastTvUpdate.tv_sec >
static_cast<signed int>(TV_UPDATE_INTERVAL_SECS)) {
Clock::getClock_timeval(&currentTv);
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(&currentUptime);
// if (currentUptime.tv_sec - lastTvUpdate.tv_sec >
// static_cast<signed int>(TV_UPDATE_INTERVAL_SECS)) {
// Clock::getClock_timeval(&currentTv);
// 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);
}

View File

@ -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);

View 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);
}

View 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_ */

View File

@ -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 {

View File

@ -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.

View 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
View 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_ */