split up funnel into PUS and CFDP funnel
This commit is contained in:
@@ -1 +1,2 @@
|
||||
target_sources(${TARGET_NAME} PRIVATE utility.cpp TmFunnel.cpp)
|
||||
target_sources(${TARGET_NAME} PRIVATE utility.cpp TmFunnel.cpp PusTmFunnel.cpp
|
||||
CfdpTmFunnel.cpp)
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
#include "CfdpTmFunnel.h"
|
||||
|
||||
#include "fsfw/ipc/QueueFactory.h"
|
||||
|
||||
CfdpTmFunnel::CfdpTmFunnel(object_id_t objectId, const AcceptsTelemetryIF& downlinkDestination)
|
||||
: SystemObject(objectId) {
|
||||
msgQueue = QueueFactory::instance()->createMessageQueue(5);
|
||||
}
|
||||
|
||||
const char* CfdpTmFunnel::getName() const { return "CFDP TM Funnel"; }
|
||||
|
||||
MessageQueueId_t CfdpTmFunnel::getReportReceptionQueue(uint8_t virtualChannel) const {
|
||||
return msgQueue->getId();
|
||||
}
|
||||
|
||||
ReturnValue_t CfdpTmFunnel::performOperation(uint8_t opCode) { return returnvalue::OK; }
|
||||
|
||||
ReturnValue_t CfdpTmFunnel::initialize() { return returnvalue::OK; }
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef FSFW_EXAMPLE_COMMON_CFDPTMFUNNEL_H
|
||||
#define FSFW_EXAMPLE_COMMON_CFDPTMFUNNEL_H
|
||||
|
||||
#include "fsfw/objectmanager/SystemObject.h"
|
||||
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
|
||||
|
||||
class CfdpTmFunnel : public AcceptsTelemetryIF, public SystemObject {
|
||||
public:
|
||||
CfdpTmFunnel(object_id_t objectId, const AcceptsTelemetryIF& downlinkDestination);
|
||||
[[nodiscard]] const char* getName() const override;
|
||||
[[nodiscard]] MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override;
|
||||
|
||||
ReturnValue_t performOperation(uint8_t opCode);
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
private:
|
||||
MessageQueueIF* msgQueue;
|
||||
};
|
||||
#endif // FSFW_EXAMPLE_COMMON_CFDPTMFUNNEL_H
|
||||
@@ -0,0 +1,82 @@
|
||||
#include "PusTmFunnel.h"
|
||||
|
||||
#include "fsfw/ipc/QueueFactory.h"
|
||||
#include "fsfw/objectmanager.h"
|
||||
#include "fsfw/tmtcpacket/pus/tm/PusTmZcWriter.h"
|
||||
|
||||
PusTmFunnel::PusTmFunnel(object_id_t objectId, const AcceptsTelemetryIF &downlinkDestination,
|
||||
TimeReaderIF &timeReader, uint32_t messageDepth)
|
||||
: SystemObject(objectId), timeReader(timeReader) {
|
||||
tmQueue = QueueFactory::instance()->createMessageQueue(messageDepth,
|
||||
MessageQueueMessage::MAX_MESSAGE_SIZE);
|
||||
tmQueue->setDefaultDestination(downlinkDestination.getReportReceptionQueue());
|
||||
}
|
||||
|
||||
PusTmFunnel::~PusTmFunnel() = default;
|
||||
|
||||
MessageQueueId_t PusTmFunnel::getReportReceptionQueue(uint8_t virtualChannel) const {
|
||||
return tmQueue->getId();
|
||||
}
|
||||
|
||||
ReturnValue_t PusTmFunnel::performOperation(uint8_t) {
|
||||
TmTcMessage currentMessage;
|
||||
ReturnValue_t status = tmQueue->receiveMessage(¤tMessage);
|
||||
while (status == returnvalue::OK) {
|
||||
status = handlePacket(¤tMessage);
|
||||
if (status != returnvalue::OK) {
|
||||
sif::warning << "TmFunnel packet handling failed" << std::endl;
|
||||
break;
|
||||
}
|
||||
status = tmQueue->receiveMessage(¤tMessage);
|
||||
}
|
||||
|
||||
if (status == MessageQueueIF::EMPTY) {
|
||||
return returnvalue::OK;
|
||||
} else {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t PusTmFunnel::handlePacket(TmTcMessage *message) {
|
||||
uint8_t *packetData = nullptr;
|
||||
size_t size = 0;
|
||||
ReturnValue_t result = tmPool->modifyData(message->getStorageId(), &packetData, &size);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
PusTmZeroCopyWriter packet(timeReader, packetData, size);
|
||||
result = packet.parseDataWithoutCrcCheck();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
packet.setSequenceCount(sourceSequenceCount++);
|
||||
sourceSequenceCount = sourceSequenceCount % ccsds::LIMIT_SEQUENCE_COUNT;
|
||||
packet.updateErrorControl();
|
||||
|
||||
result = tmQueue->sendToDefault(message);
|
||||
if (result != returnvalue::OK) {
|
||||
tmPool->deleteData(message->getStorageId());
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "TmFunnel::handlePacket: Error sending TM to downlink handler" << std::endl;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t PusTmFunnel::initialize() {
|
||||
tmPool = ObjectManager::instance()->get<StorageManagerIF>(objects::TM_STORE);
|
||||
if (tmPool == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "TmFunnel::initialize: TM store not set." << std::endl;
|
||||
sif::error << "Make sure the tm store is set up properly and implements "
|
||||
"StorageManagerIF"
|
||||
<< std::endl;
|
||||
#endif
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
return SystemObject::initialize();
|
||||
}
|
||||
|
||||
const char *PusTmFunnel::getName() const { return "PUS TM Funnel"; }
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef FSFW_EXAMPLE_COMMON_PUSTMFUNNEL_H
|
||||
#define FSFW_EXAMPLE_COMMON_PUSTMFUNNEL_H
|
||||
|
||||
#include <fsfw/ipc/MessageQueueIF.h>
|
||||
#include <fsfw/objectmanager/SystemObject.h>
|
||||
#include <fsfw/tasks/ExecutableObjectIF.h>
|
||||
#include <fsfw/tmtcservices/AcceptsTelemetryIF.h>
|
||||
#include <fsfw/tmtcservices/TmTcMessage.h>
|
||||
|
||||
#include "fsfw/timemanager/TimeReaderIF.h"
|
||||
|
||||
/**
|
||||
* @brief TM Recipient.
|
||||
* @details
|
||||
* Main telemetry receiver. All generated telemetry is funneled into
|
||||
* this object.
|
||||
* @ingroup utility
|
||||
* @author J. Meier
|
||||
*/
|
||||
class PusTmFunnel : public AcceptsTelemetryIF, public SystemObject {
|
||||
public:
|
||||
explicit PusTmFunnel(object_id_t objectId, const AcceptsTelemetryIF &downlinkDestination,
|
||||
TimeReaderIF &timeReader, uint32_t messageDepth = 20);
|
||||
[[nodiscard]] const char *getName() const override;
|
||||
~PusTmFunnel() override;
|
||||
|
||||
[[nodiscard]] MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override;
|
||||
ReturnValue_t performOperation(uint8_t operationCode);
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
private:
|
||||
uint16_t sourceSequenceCount = 0;
|
||||
TimeReaderIF &timeReader;
|
||||
MessageQueueIF *tmQueue = nullptr;
|
||||
StorageManagerIF *tmPool = nullptr;
|
||||
|
||||
ReturnValue_t handlePacket(TmTcMessage *message);
|
||||
};
|
||||
|
||||
#endif // FSFW_EXAMPLE_COMMON_PUSTMFUNNEL_H
|
||||
@@ -1,122 +1,16 @@
|
||||
#include "TmFunnel.h"
|
||||
|
||||
#include <fsfw/ipc/QueueFactory.h>
|
||||
#include <fsfw/objectmanager/ObjectManager.h>
|
||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||
#include <fsfw/tmtcpacket/pus/tm.h>
|
||||
|
||||
#include "fsfw/tmtcpacket/pus/tm.h"
|
||||
|
||||
object_id_t TmFunnel::downlinkDestination = objects::NO_OBJECT;
|
||||
object_id_t TmFunnel::storageDestination = objects::NO_OBJECT;
|
||||
|
||||
TmFunnel::TmFunnel(TimeReaderIF &timeReader, object_id_t objectId, uint32_t messageDepth)
|
||||
: SystemObject(objectId), timeReader(timeReader), messageDepth(messageDepth) {
|
||||
tmQueue = QueueFactory::instance()->createMessageQueue(messageDepth,
|
||||
MessageQueueMessage::MAX_MESSAGE_SIZE);
|
||||
storageQueue = QueueFactory::instance()->createMessageQueue(
|
||||
messageDepth, MessageQueueMessage::MAX_MESSAGE_SIZE);
|
||||
}
|
||||
TmFunnel::TmFunnel(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel)
|
||||
: SystemObject(objectId), pusFunnel(pusFunnel), cfdpFunnel(cfdpFunnel) {}
|
||||
|
||||
TmFunnel::~TmFunnel() = default;
|
||||
|
||||
MessageQueueId_t TmFunnel::getReportReceptionQueue(uint8_t virtualChannel) {
|
||||
return tmQueue->getId();
|
||||
}
|
||||
|
||||
ReturnValue_t TmFunnel::performOperation(uint8_t operationCode) {
|
||||
TmTcMessage currentMessage;
|
||||
ReturnValue_t status = tmQueue->receiveMessage(¤tMessage);
|
||||
while (status == returnvalue::OK) {
|
||||
status = handlePacket(¤tMessage);
|
||||
if (status != returnvalue::OK) {
|
||||
sif::warning << "TmFunnel packet handling failed" << std::endl;
|
||||
break;
|
||||
}
|
||||
status = tmQueue->receiveMessage(¤tMessage);
|
||||
}
|
||||
|
||||
if (status == MessageQueueIF::EMPTY) {
|
||||
return returnvalue::OK;
|
||||
} else {
|
||||
return status;
|
||||
}
|
||||
pusFunnel.performOperation(operationCode);
|
||||
cfdpFunnel.performOperation(operationCode);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t TmFunnel::handlePacket(TmTcMessage *message) {
|
||||
uint8_t *packetData = nullptr;
|
||||
size_t size = 0;
|
||||
ReturnValue_t result = tmPool->modifyData(message->getStorageId(), &packetData, &size);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
PusTmZeroCopyWriter packet(timeReader, packetData, size);
|
||||
result = packet.parseDataWithoutCrcCheck();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
packet.setSequenceCount(sourceSequenceCount++);
|
||||
sourceSequenceCount = sourceSequenceCount % ccsds::LIMIT_SEQUENCE_COUNT;
|
||||
packet.updateErrorControl();
|
||||
|
||||
result = tmQueue->sendToDefault(message);
|
||||
if (result != returnvalue::OK) {
|
||||
tmPool->deleteData(message->getStorageId());
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "TmFunnel::handlePacket: Error sending TM to downlink handler" << std::endl;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
if (storageDestination != objects::NO_OBJECT) {
|
||||
result = storageQueue->sendToDefault(message);
|
||||
if (result != returnvalue::OK) {
|
||||
tmPool->deleteData(message->getStorageId());
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "TmFunnel::handlePacket: Error sending to storage handler" << std::endl;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t TmFunnel::initialize() {
|
||||
tmPool = ObjectManager::instance()->get<StorageManagerIF>(objects::TM_STORE);
|
||||
if (tmPool == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "TmFunnel::initialize: TM store not set." << std::endl;
|
||||
sif::error << "Make sure the tm store is set up properly and implements "
|
||||
"StorageManagerIF"
|
||||
<< std::endl;
|
||||
#endif
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
|
||||
auto *tmTarget = ObjectManager::instance()->get<AcceptsTelemetryIF>(downlinkDestination);
|
||||
if (tmTarget == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "TmFunnel::initialize: Downlink Destination not set." << std::endl;
|
||||
sif::error << "Make sure the downlink destination object is set up "
|
||||
"properly and implements "
|
||||
"AcceptsTelemetryIF"
|
||||
<< std::endl;
|
||||
#endif
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
tmQueue->setDefaultDestination(tmTarget->getReportReceptionQueue());
|
||||
|
||||
// Storage destination is optional.
|
||||
if (storageDestination == objects::NO_OBJECT) {
|
||||
return SystemObject::initialize();
|
||||
}
|
||||
|
||||
auto *storageTarget = ObjectManager::instance()->get<AcceptsTelemetryIF>(storageDestination);
|
||||
if (storageTarget != nullptr) {
|
||||
storageQueue->setDefaultDestination(storageTarget->getReportReceptionQueue());
|
||||
}
|
||||
|
||||
return SystemObject::initialize();
|
||||
}
|
||||
|
||||
const char *TmFunnel::getName() const { return "TM Funnel"; }
|
||||
ReturnValue_t TmFunnel::initialize() { return returnvalue::OK; }
|
||||
|
||||
@@ -7,12 +7,10 @@
|
||||
#include <fsfw/tmtcservices/AcceptsTelemetryIF.h>
|
||||
#include <fsfw/tmtcservices/TmTcMessage.h>
|
||||
|
||||
#include "CfdpTmFunnel.h"
|
||||
#include "PusTmFunnel.h"
|
||||
#include "fsfw/timemanager/TimeReaderIF.h"
|
||||
|
||||
namespace Factory {
|
||||
void setStaticFrameworkObjectIds();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TM Recipient.
|
||||
* @details
|
||||
@@ -21,32 +19,17 @@ void setStaticFrameworkObjectIds();
|
||||
* @ingroup utility
|
||||
* @author J. Meier
|
||||
*/
|
||||
class TmFunnel : public AcceptsTelemetryIF, public ExecutableObjectIF, public SystemObject {
|
||||
friend void(Factory::setStaticFrameworkObjectIds)();
|
||||
|
||||
class TmFunnel : public ExecutableObjectIF, public SystemObject {
|
||||
public:
|
||||
explicit TmFunnel(TimeReaderIF &timeReader, object_id_t objectId, uint32_t messageDepth = 20);
|
||||
const char *getName() const override;
|
||||
TmFunnel(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel);
|
||||
~TmFunnel() override;
|
||||
|
||||
MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) override;
|
||||
ReturnValue_t performOperation(uint8_t operationCode) override;
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
protected:
|
||||
static object_id_t downlinkDestination;
|
||||
static object_id_t storageDestination;
|
||||
|
||||
private:
|
||||
uint16_t sourceSequenceCount = 0;
|
||||
TimeReaderIF &timeReader;
|
||||
MessageQueueIF *tmQueue = nullptr;
|
||||
MessageQueueIF *storageQueue = nullptr;
|
||||
|
||||
StorageManagerIF *tmPool = nullptr;
|
||||
uint32_t messageDepth = 0;
|
||||
|
||||
ReturnValue_t handlePacket(TmTcMessage *message);
|
||||
PusTmFunnel& pusFunnel;
|
||||
CfdpTmFunnel& cfdpFunnel;
|
||||
};
|
||||
|
||||
#endif /* MISSION_UTILITY_TMFUNNEL_H_ */
|
||||
|
||||
Reference in New Issue
Block a user