Merge remote-tracking branch 'upstream/mueller/refactor-tmtc-stack' into develop

This commit is contained in:
Robin Müller 2022-08-30 14:53:38 +02:00
commit 4d17f1c4bb
No known key found for this signature in database
GPG Key ID: 11D4952C8CCEF814
21 changed files with 149 additions and 231 deletions

View File

@ -35,7 +35,7 @@ void Factory::produceFsfwObjects(void) {
} }
void Factory::setStaticFrameworkObjectIds() { void Factory::setStaticFrameworkObjectIds() {
PusServiceBase::packetSource = objects::NO_OBJECT; PusServiceBase::PUS_DISTRIBUTOR = objects::NO_OBJECT;
PusServiceBase::PACKET_DESTINATION = objects::NO_OBJECT; PusServiceBase::PACKET_DESTINATION = objects::NO_OBJECT;
CommandingServiceBase::defaultPacketSource = objects::NO_OBJECT; CommandingServiceBase::defaultPacketSource = objects::NO_OBJECT;

View File

@ -14,7 +14,6 @@
#include "internal/HasLocalDpIFManagerAttorney.h" #include "internal/HasLocalDpIFManagerAttorney.h"
#include "internal/LocalPoolDataSetAttorney.h" #include "internal/LocalPoolDataSetAttorney.h"
// TODO: Get rid of this. This should be a constructor argument, not something hardcoded in any way
object_id_t LocalDataPoolManager::defaultHkDestination = objects::PUS_SERVICE_3_HOUSEKEEPING; object_id_t LocalDataPoolManager::defaultHkDestination = objects::PUS_SERVICE_3_HOUSEKEEPING;
LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner, MessageQueueIF* queueToUse, LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner, MessageQueueIF* queueToUse,
@ -326,32 +325,28 @@ void LocalDataPoolManager::resetHkUpdateResetHelper() {
} }
} }
ReturnValue_t LocalDataPoolManager::subscribeForRegularPeriodicPacket( ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(sid_t sid, bool enableReporting,
subdp::RegularHkPeriodicParams params) { float collectionInterval,
return subscribeForPeriodicPacket(params); bool isDiagnostics,
} object_id_t packetDestination) {
ReturnValue_t LocalDataPoolManager::subscribeForDiagPeriodicPacket(
subdp::DiagnosticsHkPeriodicParams params) {
return subscribeForPeriodicPacket(params);
}
ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(subdp::ParamsBase& params) {
struct HkReceiver hkReceiver; struct HkReceiver hkReceiver;
hkReceiver.dataId.sid = params.sid; hkReceiver.dataId.sid = sid;
hkReceiver.reportingType = ReportingType::PERIODIC; hkReceiver.reportingType = ReportingType::PERIODIC;
hkReceiver.dataType = DataType::DATA_SET; hkReceiver.dataType = DataType::DATA_SET;
if (params.receiver == MessageQueueIF::NO_QUEUE) { if (packetDestination != objects::NO_OBJECT) {
hkReceiver.destinationQueue = hkDestinationId; auto* receivedHkIF = ObjectManager::instance()->get<AcceptsHkPacketsIF>(packetDestination);
} else { if (receivedHkIF->getHkQueue() == MessageQueueIF::NO_QUEUE) {
hkReceiver.destinationQueue = params.receiver; hkReceiver.destinationQueue = hkDestinationId;
} else {
hkReceiver.destinationQueue = receivedHkIF->getHkQueue();
}
} }
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, params.sid); LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
if (dataSet != nullptr) { if (dataSet != nullptr) {
LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, params.enableReporting); LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, enableReporting);
LocalPoolDataSetAttorney::setDiagnostic(*dataSet, params.isDiagnostics()); LocalPoolDataSetAttorney::setDiagnostic(*dataSet, isDiagnostics);
LocalPoolDataSetAttorney::initializePeriodicHelper(*dataSet, params.collectionInterval, LocalPoolDataSetAttorney::initializePeriodicHelper(*dataSet, collectionInterval,
owner->getPeriodicOperationFrequency()); owner->getPeriodicOperationFrequency());
} }
@ -359,30 +354,26 @@ ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(subdp::ParamsBase
return returnvalue::OK; return returnvalue::OK;
} }
ReturnValue_t LocalDataPoolManager::subscribeForRegularUpdatePacket( ReturnValue_t LocalDataPoolManager::subscribeForUpdatePacket(sid_t sid, bool reportingEnabled,
subdp::RegularHkUpdateParams params) { bool isDiagnostics,
return subscribeForUpdatePacket(params); object_id_t packetDestination) {
}
ReturnValue_t LocalDataPoolManager::subscribeForDiagUpdatePacket(
subdp::DiagnosticsHkUpdateParams params) {
return subscribeForUpdatePacket(params);
}
ReturnValue_t LocalDataPoolManager::subscribeForUpdatePacket(subdp::ParamsBase& params) {
struct HkReceiver hkReceiver; struct HkReceiver hkReceiver;
hkReceiver.dataId.sid = params.sid; hkReceiver.dataId.sid = sid;
hkReceiver.reportingType = ReportingType::UPDATE_HK; hkReceiver.reportingType = ReportingType::UPDATE_HK;
hkReceiver.dataType = DataType::DATA_SET; hkReceiver.dataType = DataType::DATA_SET;
if (params.receiver == MessageQueueIF::NO_QUEUE) { if (packetDestination != objects::NO_OBJECT) {
hkReceiver.destinationQueue = hkDestinationId; auto* receivedHkIF = ObjectManager::instance()->get<AcceptsHkPacketsIF>(packetDestination);
} else { if (receivedHkIF->getHkQueue() == MessageQueueIF::NO_QUEUE) {
hkReceiver.destinationQueue = params.receiver; hkReceiver.destinationQueue = hkDestinationId;
} else {
hkReceiver.destinationQueue = receivedHkIF->getHkQueue();
}
} }
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, params.sid); LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
if (dataSet != nullptr) { if (dataSet != nullptr) {
LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, true); LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, true);
LocalPoolDataSetAttorney::setDiagnostic(*dataSet, params.isDiagnostics()); LocalPoolDataSetAttorney::setDiagnostic(*dataSet, isDiagnostics);
} }
hkReceivers.push_back(hkReceiver); hkReceivers.push_back(hkReceiver);

View File

@ -241,11 +241,13 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
MutexIF* getMutexHandle(); MutexIF* getMutexHandle();
LocalDataPoolManager* getPoolManagerHandle() override; LocalDataPoolManager* getPoolManagerHandle() override;
ReturnValue_t subscribeForRegularPeriodicPacket(subdp::RegularHkPeriodicParams params) override; ReturnValue_t subscribeForPeriodicPacket(
ReturnValue_t subscribeForDiagPeriodicPacket(subdp::DiagnosticsHkPeriodicParams params) override; sid_t sid, bool enableReporting, float collectionInterval, bool isDiagnostics,
object_id_t packetDestination = objects::NO_OBJECT) override;
ReturnValue_t subscribeForRegularUpdatePacket(subdp::RegularHkUpdateParams params) override; ReturnValue_t subscribeForUpdatePacket(
ReturnValue_t subscribeForDiagUpdatePacket(subdp::DiagnosticsHkUpdateParams params) override; sid_t sid, bool reportingEnabled, bool isDiagnostics,
object_id_t packetDestination = objects::NO_OBJECT) override;
protected: protected:
ReturnValue_t subscribeForPeriodicPacket(subdp::ParamsBase& params); ReturnValue_t subscribeForPeriodicPacket(subdp::ParamsBase& params);

View File

@ -1,96 +1,24 @@
#ifndef FSFW_DATAPOOLLOCAL_PROVIDESDATAPOOLSUBSCRIPTION_H_ #ifndef FSFW_DATAPOOLLOCAL_PROVIDESDATAPOOLSUBSCRIPTION_H_
#define FSFW_DATAPOOLLOCAL_PROVIDESDATAPOOLSUBSCRIPTION_H_ #define FSFW_DATAPOOLLOCAL_PROVIDESDATAPOOLSUBSCRIPTION_H_
#include "fsfw/housekeeping/AcceptsHkPacketsIF.h" #include "../ipc/messageQueueDefinitions.h"
#include "fsfw/ipc/MessageQueueIF.h" #include "../returnvalues/returnvalue.h"
#include "fsfw/ipc/messageQueueDefinitions.h"
#include "fsfw/returnvalues/returnvalue.h"
#include "localPoolDefinitions.h" #include "localPoolDefinitions.h"
namespace subdp {
struct ParamsBase {
ParamsBase(sid_t sid, bool enableReporting, float collectionInterval, bool diagnostics)
: sid(sid),
enableReporting(enableReporting),
collectionInterval(collectionInterval),
diagnostics(diagnostics) {}
[[nodiscard]] bool isDiagnostics() const { return diagnostics; }
sid_t sid;
bool enableReporting;
float collectionInterval;
MessageQueueId_t receiver = MessageQueueIF::NO_QUEUE;
protected:
bool diagnostics;
};
struct RegularHkPeriodicParams : public ParamsBase {
RegularHkPeriodicParams(sid_t sid, float collectionInterval)
: ParamsBase(sid, false, collectionInterval, false) {}
RegularHkPeriodicParams(sid_t sid, bool enableReporting, float collectionInterval)
: ParamsBase(sid, enableReporting, collectionInterval, false) {}
};
struct DiagnosticsHkPeriodicParams : public ParamsBase {
DiagnosticsHkPeriodicParams(sid_t sid, float collectionInterval)
: ParamsBase(sid, false, collectionInterval, true) {}
DiagnosticsHkPeriodicParams(sid_t sid, bool enableReporting, float collectionInterval)
: ParamsBase(sid, enableReporting, collectionInterval, true) {}
};
struct RegularHkUpdateParams : public ParamsBase {
RegularHkUpdateParams(sid_t sid, bool enableReporting)
: ParamsBase(sid, enableReporting, 0.0, false) {}
};
struct DiagnosticsHkUpdateParams : public ParamsBase {
DiagnosticsHkUpdateParams(sid_t sid, bool enableReporting)
: ParamsBase(sid, enableReporting, 0.0, true) {}
};
} // namespace subdp
class ProvidesDataPoolSubscriptionIF { class ProvidesDataPoolSubscriptionIF {
public: public:
virtual ~ProvidesDataPoolSubscriptionIF() = default; virtual ~ProvidesDataPoolSubscriptionIF(){};
/** /**
* @brief Subscribe for the generation of periodic packets. Used for regular HK packets * @brief Subscribe for the generation of periodic packets.
* @details * @details
* This subscription mechanism will generally be used by the data creator * This subscription mechanism will generally be used by the data creator
* to generate housekeeping packets which are downlinked directly. * to generate housekeeping packets which are downlinked directly.
* @return * @return
*/ */
virtual ReturnValue_t subscribeForRegularPeriodicPacket( virtual ReturnValue_t subscribeForPeriodicPacket(sid_t sid, bool enableReporting,
subdp::RegularHkPeriodicParams params) = 0; float collectionInterval, bool isDiagnostics,
/** object_id_t packetDestination) = 0;
* @brief Subscribe for the generation of periodic packets. Used for diagnostic packets
* @details
* This subscription mechanism will generally be used by the data creator
* to generate housekeeping packets which are downlinked directly.
* @return
*/
virtual ReturnValue_t subscribeForDiagPeriodicPacket(
subdp::DiagnosticsHkPeriodicParams params) = 0;
[[deprecated(
"Please use the new API which takes all arguments as one wrapper "
"struct")]] virtual ReturnValue_t
subscribeForPeriodicPacket(sid_t sid, bool enableReporting, float collectionInterval,
bool isDiagnostics,
object_id_t packetDestination = objects::NO_OBJECT) {
if (isDiagnostics) {
subdp::DiagnosticsHkPeriodicParams params(sid, enableReporting, collectionInterval);
return subscribeForDiagPeriodicPacket(params);
} else {
subdp::RegularHkPeriodicParams params(sid, enableReporting, collectionInterval);
return subscribeForRegularPeriodicPacket(params);
}
}
/** /**
* @brief Subscribe for the generation of packets if the dataset * @brief Subscribe for the generation of packets if the dataset
* is marked as changed. * is marked as changed.
@ -101,28 +29,9 @@ class ProvidesDataPoolSubscriptionIF {
* @param packetDestination * @param packetDestination
* @return * @return
*/ */
virtual ReturnValue_t subscribeForRegularUpdatePacket(subdp::RegularHkUpdateParams params) = 0; virtual ReturnValue_t subscribeForUpdatePacket(sid_t sid, bool reportingEnabled,
virtual ReturnValue_t subscribeForDiagUpdatePacket(subdp::DiagnosticsHkUpdateParams params) = 0; bool isDiagnostics,
object_id_t packetDestination) = 0;
// virtual ReturnValue_t
// subscribeForUpdatePacket(sid_t sid, bool reportingEnabled, bool isDiagnostics) {
// return subscribeForUpdatePacket(sid, reportingEnabled, isDiagnostics, objects::NO_OBJECT);
// }
[[deprecated(
"Please use the new API which takes all arguments as one wrapper "
"struct")]] virtual ReturnValue_t
subscribeForUpdatePacket(sid_t sid, bool reportingEnabled, bool isDiagnostics,
object_id_t packetDestination = objects::NO_OBJECT) {
if (isDiagnostics) {
subdp::DiagnosticsHkUpdateParams params(sid, reportingEnabled);
return subscribeForDiagUpdatePacket(params);
} else {
subdp::RegularHkUpdateParams params(sid, reportingEnabled);
return subscribeForRegularUpdatePacket(params);
}
}
/** /**
* @brief Subscribe for a notification message which will be sent * @brief Subscribe for a notification message which will be sent
* if a dataset has changed. * if a dataset has changed.
@ -137,7 +46,8 @@ class ProvidesDataPoolSubscriptionIF {
* Otherwise, only an notification message is sent. * Otherwise, only an notification message is sent.
* @return * @return
*/ */
virtual ReturnValue_t subscribeForSetUpdateMessage(uint32_t setId, object_id_t destinationObject, virtual ReturnValue_t subscribeForSetUpdateMessage(const uint32_t setId,
object_id_t destinationObject,
MessageQueueId_t targetQueueId, MessageQueueId_t targetQueueId,
bool generateSnapshot) = 0; bool generateSnapshot) = 0;
/** /**
@ -154,7 +64,7 @@ class ProvidesDataPoolSubscriptionIF {
* only an notification message is sent. * only an notification message is sent.
* @return * @return
*/ */
virtual ReturnValue_t subscribeForVariableUpdateMessage(lp_id_t localPoolId, virtual ReturnValue_t subscribeForVariableUpdateMessage(const lp_id_t localPoolId,
object_id_t destinationObject, object_id_t destinationObject,
MessageQueueId_t targetQueueId, MessageQueueId_t targetQueueId,
bool generateSnapshot) = 0; bool generateSnapshot) = 0;

View File

@ -130,9 +130,9 @@ ReturnValue_t InternalErrorReporter::initializeLocalDataPool(localpool::DataPool
localDataPoolMap.emplace(errorPoolIds::TM_HITS, &tmHitsEntry); localDataPoolMap.emplace(errorPoolIds::TM_HITS, &tmHitsEntry);
localDataPoolMap.emplace(errorPoolIds::QUEUE_HITS, &queueHitsEntry); localDataPoolMap.emplace(errorPoolIds::QUEUE_HITS, &queueHitsEntry);
localDataPoolMap.emplace(errorPoolIds::STORE_HITS, &storeHitsEntry); localDataPoolMap.emplace(errorPoolIds::STORE_HITS, &storeHitsEntry);
poolManager.subscribeForDiagPeriodicPacket(subdp::DiagnosticsHkPeriodicParams( poolManager.subscribeForPeriodicPacket(
internalErrorSid, false, internalErrorSid, false,
static_cast<float>(getPeriodicOperationFrequency()) / static_cast<float>(1000.0))); static_cast<float>(getPeriodicOperationFrequency()) / static_cast<float>(1000.0), true);
internalErrorDataset.setValidity(true, true); internalErrorDataset.setValidity(true, true);
return returnvalue::OK; return returnvalue::OK;
} }

View File

@ -12,7 +12,7 @@ MessageQueueMessage::MessageQueueMessage() : messageSize(getMinimumMessageSize()
MessageQueueMessage::MessageQueueMessage(uint8_t* data, size_t size) MessageQueueMessage::MessageQueueMessage(uint8_t* data, size_t size)
: messageSize(MessageQueueMessage::HEADER_SIZE + size) { : messageSize(MessageQueueMessage::HEADER_SIZE + size) {
if (size <= MessageQueueMessage::MAX_DATA_SIZE) { if (size <= MessageQueueMessage::MAX_DATA_SIZE) {
std::memcpy(internalBuffer + MessageQueueMessage::HEADER_SIZE, data, size); std::memcpy(MessageQueueMessage::getData(), data, size);
this->messageSize = MessageQueueMessage::HEADER_SIZE + size; this->messageSize = MessageQueueMessage::HEADER_SIZE + size;
} else { } else {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1

View File

@ -581,8 +581,7 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::getMapFilterFr
} }
// additional security check, this should never be true // additional security check, this should never be true
if ((itBegin != telecommandMap.end() and itEnd != telecommandMap.end()) and if (itBegin > itEnd) {
(itBegin->first > itEnd->first)) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "11::getMapFilterFromData: itBegin > itEnd\n" << std::endl; sif::error << "11::getMapFilterFromData: itBegin > itEnd\n" << std::endl;
#else #else

View File

@ -39,13 +39,13 @@ class CCSDSTime {
* Struct for CDS day-segmented format. * Struct for CDS day-segmented format.
*/ */
struct CDS_short { struct CDS_short {
uint8_t pField; uint8_t pField = P_FIELD_CDS_SHORT;
uint8_t dayMSB; uint8_t dayMSB = 0;
uint8_t dayLSB; uint8_t dayLSB = 0;
uint8_t msDay_hh; uint8_t msDay_hh = 0;
uint8_t msDay_h; uint8_t msDay_h = 0;
uint8_t msDay_l; uint8_t msDay_l = 0;
uint8_t msDay_ll; uint8_t msDay_ll = 0;
}; };
/** /**
* Struct for the CCS fromat in day of month variation with max resolution * Struct for the CCS fromat in day of month variation with max resolution

View File

@ -13,44 +13,6 @@ using PusChecksumT = uint16_t;
//! Version numbers according to ECSS-E-ST-70-41C p.439 //! Version numbers according to ECSS-E-ST-70-41C p.439
enum PusVersion : uint8_t { PUS_A = 1, PUS_C = 2 }; enum PusVersion : uint8_t { PUS_A = 1, PUS_C = 2 };
struct RawData {
const uint8_t* data;
size_t len;
};
enum DataTypes { RAW, SERIALIZABLE };
union DataUnion {
RawData raw;
SerializeIF* serializable;
};
struct DataWrapper {
DataTypes type;
DataUnion dataUnion;
using BufPairT = std::pair<const uint8_t*, size_t>;
[[nodiscard]] size_t getLength() const {
if (type == DataTypes::RAW) {
return dataUnion.raw.len;
} else if (type == DataTypes::SERIALIZABLE and dataUnion.serializable != nullptr) {
return dataUnion.serializable->getSerializedSize();
}
return 0;
}
void setRawData(BufPairT bufPair) {
type = DataTypes::RAW;
dataUnion.raw.data = bufPair.first;
dataUnion.raw.len = bufPair.second;
}
void setSerializable(SerializeIF& serializable) {
type = DataTypes::SERIALIZABLE;
dataUnion.serializable = &serializable;
}
};
/** /**
* This struct defines the data structure of a Space Packet when accessed * This struct defines the data structure of a Space Packet when accessed
* via a pointer. * via a pointer.

View File

@ -37,14 +37,14 @@ ReturnValue_t PusTcCreator::serialize(uint8_t **buffer, size_t *size, size_t max
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
if (pusParams.dataWrapper.type == ecss::DataTypes::RAW) { if (pusParams.dataWrapper.type == util::DataTypes::RAW) {
const uint8_t *data = pusParams.dataWrapper.dataUnion.raw.data; const uint8_t *data = pusParams.dataWrapper.dataUnion.raw.data;
if (data != nullptr and userDataLen > 0) { if (data != nullptr and userDataLen > 0) {
std::memcpy(*buffer, data, userDataLen); std::memcpy(*buffer, data, userDataLen);
*buffer += userDataLen; *buffer += userDataLen;
*size += userDataLen; *size += userDataLen;
} }
} else if (pusParams.dataWrapper.type == ecss::DataTypes::SERIALIZABLE and } else if (pusParams.dataWrapper.type == util::DataTypes::SERIALIZABLE and
pusParams.dataWrapper.dataUnion.serializable != nullptr) { pusParams.dataWrapper.dataUnion.serializable != nullptr) {
result = pusParams.dataWrapper.dataUnion.serializable->serialize(buffer, size, maxSize, result = pusParams.dataWrapper.dataUnion.serializable->serialize(buffer, size, maxSize,
streamEndianness); streamEndianness);

View File

@ -7,6 +7,7 @@
#include "fsfw/tmtcpacket/pus/CustomUserDataIF.h" #include "fsfw/tmtcpacket/pus/CustomUserDataIF.h"
#include "fsfw/tmtcpacket/pus/defs.h" #include "fsfw/tmtcpacket/pus/defs.h"
#include "fsfw/tmtcpacket/pus/tc/PusTcIF.h" #include "fsfw/tmtcpacket/pus/tc/PusTcIF.h"
#include "fsfw/util/dataWrapper.h"
struct PusTcParams { struct PusTcParams {
PusTcParams(uint8_t service_, uint8_t subservice_) : service(service_), subservice(subservice_) {} PusTcParams(uint8_t service_, uint8_t subservice_) : service(service_), subservice(subservice_) {}
@ -15,7 +16,7 @@ struct PusTcParams {
uint8_t subservice; uint8_t subservice;
uint8_t ackFlags = ecss::ACK_ALL; uint8_t ackFlags = ecss::ACK_ALL;
uint16_t sourceId = 0; uint16_t sourceId = 0;
ecss::DataWrapper dataWrapper{}; util::DataWrapper dataWrapper{};
uint8_t pusVersion = ecss::PusVersion::PUS_C; uint8_t pusVersion = ecss::PusVersion::PUS_C;
}; };

View File

@ -77,12 +77,12 @@ ReturnValue_t PusTmCreator::serialize(uint8_t** buffer, size_t* size, size_t max
} }
} }
if (pusParams.dataWrapper.type == ecss::DataTypes::RAW and if (pusParams.dataWrapper.type == util::DataTypes::RAW and
pusParams.dataWrapper.dataUnion.raw.data != nullptr) { pusParams.dataWrapper.dataUnion.raw.data != nullptr) {
std::memcpy(*buffer, pusParams.dataWrapper.dataUnion.raw.data, userDataLen); std::memcpy(*buffer, pusParams.dataWrapper.dataUnion.raw.data, userDataLen);
*buffer += userDataLen; *buffer += userDataLen;
*size += userDataLen; *size += userDataLen;
} else if (pusParams.dataWrapper.type == ecss::DataTypes::SERIALIZABLE and } else if (pusParams.dataWrapper.type == util::DataTypes::SERIALIZABLE and
pusParams.dataWrapper.dataUnion.serializable != nullptr) { pusParams.dataWrapper.dataUnion.serializable != nullptr) {
result = pusParams.dataWrapper.dataUnion.serializable->serialize(buffer, size, maxSize, result = pusParams.dataWrapper.dataUnion.serializable->serialize(buffer, size, maxSize,
streamEndianness); streamEndianness);

View File

@ -4,6 +4,7 @@
#include "PusTmIF.h" #include "PusTmIF.h"
#include "fsfw/tmtcpacket/ccsds/SpacePacketCreator.h" #include "fsfw/tmtcpacket/ccsds/SpacePacketCreator.h"
#include "fsfw/tmtcpacket/pus/CustomUserDataIF.h" #include "fsfw/tmtcpacket/pus/CustomUserDataIF.h"
#include "fsfw/util/dataWrapper.h"
struct PusTmSecHeader { struct PusTmSecHeader {
PusTmSecHeader() = default; PusTmSecHeader() = default;
@ -22,19 +23,19 @@ struct PusTmSecHeader {
struct PusTmParams { struct PusTmParams {
PusTmParams() = default; PusTmParams() = default;
explicit PusTmParams(PusTmSecHeader secHeader) : secHeader(secHeader){}; explicit PusTmParams(PusTmSecHeader secHeader) : secHeader(secHeader){};
PusTmParams(PusTmSecHeader secHeader, ecss::DataWrapper dataWrapper) PusTmParams(PusTmSecHeader secHeader, util::DataWrapper dataWrapper)
: secHeader(secHeader), dataWrapper(dataWrapper) {} : secHeader(secHeader), dataWrapper(dataWrapper) {}
PusTmParams(uint8_t service, uint8_t subservice, TimeStamperIF* timeStamper) PusTmParams(uint8_t service, uint8_t subservice, TimeStamperIF* timeStamper)
: secHeader(service, subservice, timeStamper) {} : secHeader(service, subservice, timeStamper) {}
PusTmParams(uint8_t service, uint8_t subservice, TimeStamperIF* timeStamper, PusTmParams(uint8_t service, uint8_t subservice, TimeStamperIF* timeStamper,
ecss::DataWrapper dataWrapper_) util::DataWrapper dataWrapper_)
: PusTmParams(service, subservice, timeStamper) { : PusTmParams(service, subservice, timeStamper) {
dataWrapper = dataWrapper_; dataWrapper = dataWrapper_;
} }
PusTmSecHeader secHeader; PusTmSecHeader secHeader;
ecss::DataWrapper dataWrapper{}; util::DataWrapper dataWrapper{};
}; };
class TimeStamperIF; class TimeStamperIF;

View File

@ -5,7 +5,7 @@
namespace tcverif { namespace tcverif {
enum VerifFlags : uint8_t { enum VerificationFlags : uint8_t {
NONE = 0b0000, NONE = 0b0000,
ACCEPTANCE = 0b0001, ACCEPTANCE = 0b0001,
START = 0b0010, START = 0b0010,

View File

@ -11,13 +11,13 @@ class DataWithObjectIdPrefix : public SerializeIF {
public: public:
DataWithObjectIdPrefix(object_id_t objectId, const uint8_t* srcData, size_t srcDataLen) DataWithObjectIdPrefix(object_id_t objectId, const uint8_t* srcData, size_t srcDataLen)
: objectId(objectId) { : objectId(objectId) {
dataWrapper.type = ecss::DataTypes::RAW; dataWrapper.type = util::DataTypes::RAW;
dataWrapper.dataUnion.raw.data = srcData; dataWrapper.dataUnion.raw.data = srcData;
dataWrapper.dataUnion.raw.len = srcDataLen; dataWrapper.dataUnion.raw.len = srcDataLen;
} }
DataWithObjectIdPrefix(object_id_t objectId, SerializeIF& serializable) : objectId(objectId) { DataWithObjectIdPrefix(object_id_t objectId, SerializeIF& serializable) : objectId(objectId) {
dataWrapper.type = ecss::DataTypes::SERIALIZABLE; dataWrapper.type = util::DataTypes::SERIALIZABLE;
dataWrapper.dataUnion.serializable = &serializable; dataWrapper.dataUnion.serializable = &serializable;
} }
@ -26,11 +26,11 @@ class DataWithObjectIdPrefix : public SerializeIF {
if (*size + getSerializedSize() > maxSize) { if (*size + getSerializedSize() > maxSize) {
return SerializeIF::BUFFER_TOO_SHORT; return SerializeIF::BUFFER_TOO_SHORT;
} }
if (dataWrapper.type != ecss::DataTypes::RAW) { if (dataWrapper.type != util::DataTypes::RAW) {
if ((dataWrapper.dataUnion.raw.data == nullptr) and (dataWrapper.dataUnion.raw.len > 0)) { if ((dataWrapper.dataUnion.raw.data == nullptr) and (dataWrapper.dataUnion.raw.len > 0)) {
return returnvalue::FAILED; return returnvalue::FAILED;
} }
} else if (dataWrapper.type == ecss::DataTypes::SERIALIZABLE) { } else if (dataWrapper.type == util::DataTypes::SERIALIZABLE) {
if (dataWrapper.dataUnion.serializable == nullptr) { if (dataWrapper.dataUnion.serializable == nullptr) {
return returnvalue::FAILED; return returnvalue::FAILED;
} }
@ -40,7 +40,7 @@ class DataWithObjectIdPrefix : public SerializeIF {
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
if (dataWrapper.type != ecss::DataTypes::RAW) { if (dataWrapper.type != util::DataTypes::RAW) {
std::memcpy(*buffer, dataWrapper.dataUnion.raw.data, dataWrapper.dataUnion.raw.len); std::memcpy(*buffer, dataWrapper.dataUnion.raw.data, dataWrapper.dataUnion.raw.len);
*buffer += dataWrapper.dataUnion.raw.len; *buffer += dataWrapper.dataUnion.raw.len;
*size += dataWrapper.dataUnion.raw.len; *size += dataWrapper.dataUnion.raw.len;
@ -63,7 +63,7 @@ class DataWithObjectIdPrefix : public SerializeIF {
private: private:
object_id_t objectId; object_id_t objectId;
ecss::DataWrapper dataWrapper{}; util::DataWrapper dataWrapper{};
}; };
} // namespace telemetry } // namespace telemetry

View File

@ -0,0 +1,60 @@
#ifndef FSFW_UTIL_DATAWRAPPER_H
#define FSFW_UTIL_DATAWRAPPER_H
#include <cstddef>
#include <cstdint>
#include <utility>
#include "fsfw/serialize.h"
namespace util {
struct RawData {
const uint8_t* data = nullptr;
size_t len = 0;
};
enum DataTypes { NONE, RAW, SERIALIZABLE };
union DataUnion {
RawData raw;
SerializeIF* serializable = nullptr;
};
struct DataWrapper {
DataTypes type = DataTypes::NONE;
DataUnion dataUnion;
using BufPairT = std::pair<const uint8_t*, size_t>;
[[nodiscard]] size_t getLength() const {
if (type == DataTypes::RAW) {
return dataUnion.raw.len;
} else if (type == DataTypes::SERIALIZABLE and dataUnion.serializable != nullptr) {
return dataUnion.serializable->getSerializedSize();
}
return 0;
}
[[nodiscard]] bool isNull() const {
if ((type == DataTypes::NONE) or (type == DataTypes::RAW and dataUnion.raw.data == nullptr) or
(type == DataTypes::SERIALIZABLE and dataUnion.serializable == nullptr)) {
return true;
}
return false;
}
void setRawData(BufPairT bufPair) {
type = DataTypes::RAW;
dataUnion.raw.data = bufPair.first;
dataUnion.raw.len = bufPair.second;
}
void setSerializable(SerializeIF& serializable) {
type = DataTypes::SERIALIZABLE;
dataUnion.serializable = &serializable;
}
};
} // namespace util
#endif // FSFW_UTIL_DATAWRAPPER_H

View File

@ -469,7 +469,7 @@ ReturnValue_t MgmLIS3MDLHandler::initializeLocalDataPool(localpool::DataPool &lo
LocalDataPoolManager &poolManager) { LocalDataPoolManager &poolManager) {
localDataPoolMap.emplace(MGMLIS3MDL::FIELD_STRENGTHS, &mgmXYZ); localDataPoolMap.emplace(MGMLIS3MDL::FIELD_STRENGTHS, &mgmXYZ);
localDataPoolMap.emplace(MGMLIS3MDL::TEMPERATURE_CELCIUS, &temperature); localDataPoolMap.emplace(MGMLIS3MDL::TEMPERATURE_CELCIUS, &temperature);
poolManager.subscribeForRegularPeriodicPacket({dataset.getSid(), false, 10.0}); poolManager.subscribeForPeriodicPacket(dataset.getSid(), false, 10.0, false);
return returnvalue::OK; return returnvalue::OK;
} }

View File

@ -310,7 +310,7 @@ void MgmRM3100Handler::modeChanged() { internalState = InternalState::NONE; }
ReturnValue_t MgmRM3100Handler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap, ReturnValue_t MgmRM3100Handler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) { LocalDataPoolManager &poolManager) {
localDataPoolMap.emplace(RM3100::FIELD_STRENGTHS, &mgmXYZ); localDataPoolMap.emplace(RM3100::FIELD_STRENGTHS, &mgmXYZ);
poolManager.subscribeForRegularPeriodicPacket({primaryDataset.getSid(), false, 10.0}); poolManager.subscribeForPeriodicPacket(primaryDataset.getSid(), false, 10.0, false);
return returnvalue::OK; return returnvalue::OK;
} }

View File

@ -2,5 +2,5 @@ target_sources(${FSFW_TEST_TGT} PRIVATE
testLocalPoolVariable.cpp testLocalPoolVariable.cpp
testLocalPoolVector.cpp testLocalPoolVector.cpp
testDataSet.cpp testDataSet.cpp
testLocalPoolManager.cpp testLocalPoolManager.cpp
) )

View File

@ -11,6 +11,7 @@
#include <fsfw/objectmanager/SystemObject.h> #include <fsfw/objectmanager/SystemObject.h>
#include "fsfw/datapool/PoolEntry.h" #include "fsfw/datapool/PoolEntry.h"
#include "fsfw/housekeeping/AcceptsHkPacketsIF.h"
#include "mocks/MessageQueueMock.h" #include "mocks/MessageQueueMock.h"
#include "tests/TestsConfig.h" #include "tests/TestsConfig.h"
@ -104,8 +105,7 @@ class LocalPoolOwnerBase : public SystemObject, public HasLocalDataPoolIF {
} }
ReturnValue_t subscribePeriodicHk(bool enableReporting) { ReturnValue_t subscribePeriodicHk(bool enableReporting) {
return poolManager.subscribeForRegularPeriodicPacket( return poolManager.subscribeForPeriodicPacket(lpool::testSid, enableReporting, 0.2, false);
subdp::RegularHkPeriodicParams(lpool::testSid, enableReporting, 0.2));
} }
ReturnValue_t subscribeWrapperSetUpdate(MessageQueueId_t receiverId) { ReturnValue_t subscribeWrapperSetUpdate(MessageQueueId_t receiverId) {
@ -121,17 +121,9 @@ class LocalPoolOwnerBase : public SystemObject, public HasLocalDataPoolIF {
ReturnValue_t subscribeWrapperSetUpdateHk(bool diagnostics = false, ReturnValue_t subscribeWrapperSetUpdateHk(bool diagnostics = false,
AcceptsHkPacketsIF* receiver = nullptr) { AcceptsHkPacketsIF* receiver = nullptr) {
if (diagnostics) { if (diagnostics) {
auto params = subdp::DiagnosticsHkUpdateParams(lpool::testSid, true); return poolManager.subscribeForUpdatePacket(lpool::testSid, true, true);
if (receiver != nullptr) {
params.receiver = receiver->getHkQueue();
}
return poolManager.subscribeForDiagUpdatePacket(params);
} else { } else {
auto params = subdp::RegularHkUpdateParams(lpool::testSid, true); return poolManager.subscribeForUpdatePacket(lpool::testSid, true, false);
if (receiver != nullptr) {
params.receiver = receiver->getHkQueue();
}
return poolManager.subscribeForRegularUpdatePacket(params);
} }
} }

View File

@ -44,7 +44,7 @@ TEST_CASE("TM Store And Send Helper", "[tm-store-send-helper]") {
REQUIRE(creator.getSubService() == 2); REQUIRE(creator.getSubService() == 2);
REQUIRE(creator.getService() == 17); REQUIRE(creator.getService() == 17);
auto& params = creator.getParams(); auto& params = creator.getParams();
REQUIRE(params.dataWrapper.type == ecss::DataTypes::RAW); REQUIRE(params.dataWrapper.type == util::DataTypes::RAW);
REQUIRE(params.dataWrapper.dataUnion.raw.data == nullptr); REQUIRE(params.dataWrapper.dataUnion.raw.data == nullptr);
REQUIRE(params.dataWrapper.dataUnion.raw.len == 0); REQUIRE(params.dataWrapper.dataUnion.raw.len == 0);
REQUIRE(tmHelper.sendCounter == 0); REQUIRE(tmHelper.sendCounter == 0);
@ -65,7 +65,7 @@ TEST_CASE("TM Store And Send Helper", "[tm-store-send-helper]") {
REQUIRE(tmHelper.prepareTmPacket(2, data.data(), data.size()) == returnvalue::OK); REQUIRE(tmHelper.prepareTmPacket(2, data.data(), data.size()) == returnvalue::OK);
auto& creator = storeHelper.getCreatorRef(); auto& creator = storeHelper.getCreatorRef();
auto& params = creator.getParams(); auto& params = creator.getParams();
REQUIRE(params.dataWrapper.type == ecss::DataTypes::RAW); REQUIRE(params.dataWrapper.type == util::DataTypes::RAW);
REQUIRE(params.dataWrapper.dataUnion.raw.data == data.data()); REQUIRE(params.dataWrapper.dataUnion.raw.data == data.data());
REQUIRE(params.dataWrapper.dataUnion.raw.len == data.size()); REQUIRE(params.dataWrapper.dataUnion.raw.len == data.size());
} }
@ -75,7 +75,7 @@ TEST_CASE("TM Store And Send Helper", "[tm-store-send-helper]") {
REQUIRE(tmHelper.prepareTmPacket(2, simpleSer) == returnvalue::OK); REQUIRE(tmHelper.prepareTmPacket(2, simpleSer) == returnvalue::OK);
auto& creator = storeHelper.getCreatorRef(); auto& creator = storeHelper.getCreatorRef();
auto& params = creator.getParams(); auto& params = creator.getParams();
REQUIRE(params.dataWrapper.type == ecss::DataTypes::SERIALIZABLE); REQUIRE(params.dataWrapper.type == util::DataTypes::SERIALIZABLE);
REQUIRE(params.dataWrapper.dataUnion.serializable == &simpleSer); REQUIRE(params.dataWrapper.dataUnion.serializable == &simpleSer);
} }
@ -86,7 +86,7 @@ TEST_CASE("TM Store And Send Helper", "[tm-store-send-helper]") {
REQUIRE(tmHelper.prepareTmPacket(2, dataWithObjId) == returnvalue::OK); REQUIRE(tmHelper.prepareTmPacket(2, dataWithObjId) == returnvalue::OK);
auto& creator = storeHelper.getCreatorRef(); auto& creator = storeHelper.getCreatorRef();
auto& params = creator.getParams(); auto& params = creator.getParams();
REQUIRE(params.dataWrapper.type == ecss::DataTypes::SERIALIZABLE); REQUIRE(params.dataWrapper.type == util::DataTypes::SERIALIZABLE);
REQUIRE(params.dataWrapper.dataUnion.serializable == &dataWithObjId); REQUIRE(params.dataWrapper.dataUnion.serializable == &dataWithObjId);
} }