fsfw/datapoollocal/LocalPoolDataSetBase.cpp

320 lines
10 KiB
C++
Raw Normal View History

2020-10-01 12:05:24 +02:00
#include "LocalPoolDataSetBase.h"
2021-01-12 19:41:47 +01:00
#include "HasLocalDataPoolIF.h"
2021-01-12 20:46:34 +01:00
#include "internal/HasLocalDpIFUserAttorney.h"
#include "../serviceinterface/ServiceInterface.h"
2020-10-01 12:05:24 +02:00
#include "../datapoollocal/LocalDataPoolManager.h"
#include "../housekeeping/PeriodicHousekeepingHelper.h"
#include "../serialize/SerializeAdapter.h"
#include <cmath>
#include <cstring>
2021-01-11 22:18:42 +01:00
LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner,
2021-01-13 12:41:24 +01:00
uint32_t setId, PoolVariableIF** registeredVariablesArray,
const size_t maxNumberOfVariables, bool periodicHandling):
PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
if(hkOwner == nullptr) {
// Configuration error.
2021-01-03 14:16:52 +01:00
#if FSFW_CPP_OSTREAM_ENABLED == 1
2021-01-13 12:41:24 +01:00
sif::error << "LocalPoolDataSetBase::LocalPoolDataSetBase: Owner "
<< "invalid!" << std::endl;
#else
2021-01-13 12:41:24 +01:00
sif::printError("LocalPoolDataSetBase::LocalPoolDataSetBase: Owner "
"invalid!\n\r");
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
2021-01-13 12:41:24 +01:00
return;
}
AccessPoolManagerIF* accessor = HasLocalDpIFUserAttorney::getAccessorHandle(hkOwner);
if(accessor != nullptr) {
2021-01-25 13:09:39 +01:00
poolManager = accessor->getPoolManagerHandle();
2021-01-13 12:41:24 +01:00
mutexIfSingleDataCreator = accessor->getLocalPoolMutex();
}
this->sid.objectId = hkOwner->getObjectId();
this->sid.ownerSetId = setId;
// Data creators get a periodic helper for periodic HK data generation.
if(periodicHandling) {
periodicHelper = new PeriodicHousekeepingHelper(this);
}
2020-10-01 12:05:24 +02:00
}
LocalPoolDataSetBase::LocalPoolDataSetBase(sid_t sid,
2021-01-13 12:41:24 +01:00
PoolVariableIF** registeredVariablesArray,
const size_t maxNumberOfVariables):
PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
HasLocalDataPoolIF* hkOwner = objectManager->get<HasLocalDataPoolIF>(
sid.objectId);
if(hkOwner != nullptr) {
AccessPoolManagerIF* accessor = HasLocalDpIFUserAttorney::getAccessorHandle(hkOwner);
if(accessor != nullptr) {
mutexIfSingleDataCreator = accessor->getLocalPoolMutex();
}
}
this->sid = sid;
2020-10-01 12:05:24 +02:00
}
LocalPoolDataSetBase::LocalPoolDataSetBase(
2021-01-13 12:41:24 +01:00
PoolVariableIF **registeredVariablesArray,
const size_t maxNumberOfVariables, bool protectEveryReadCommitCall):
PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
this->setReadCommitProtectionBehaviour(protectEveryReadCommitCall);
}
2020-10-01 12:05:24 +02:00
LocalPoolDataSetBase::~LocalPoolDataSetBase() {
2021-01-13 12:41:24 +01:00
if(periodicHelper != nullptr) {
delete periodicHelper;
}
2020-10-01 12:05:24 +02:00
}
ReturnValue_t LocalPoolDataSetBase::lockDataPool(
2021-01-13 12:41:24 +01:00
MutexIF::TimeoutType timeoutType,
uint32_t timeoutMs) {
if(mutexIfSingleDataCreator != nullptr) {
return mutexIfSingleDataCreator->lockMutex(timeoutType, timeoutMs);
}
return HasReturnvaluesIF::RETURN_OK;
2020-10-01 12:05:24 +02:00
}
ReturnValue_t LocalPoolDataSetBase::serializeWithValidityBuffer(uint8_t **buffer,
2021-01-13 12:41:24 +01:00
size_t *size, size_t maxSize,
SerializeIF::Endianness streamEndianness) const {
2021-02-03 18:04:55 +01:00
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
2021-01-13 12:41:24 +01:00
uint8_t validityMaskSize = std::ceil(static_cast<float>(fillCount)/8.0);
uint8_t validityMask[validityMaskSize];
uint8_t validBufferIndex = 0;
uint8_t validBufferIndexBit = 0;
for (uint16_t count = 0; count < fillCount; count++) {
if(registeredVariables[count]->isValid()) {
// set validity buffer here.
this->bitSetter(validityMask + validBufferIndex,
validBufferIndexBit);
if(validBufferIndexBit == 7) {
validBufferIndex ++;
validBufferIndexBit = 0;
}
else {
validBufferIndexBit ++;
}
}
result = registeredVariables[count]->serialize(buffer, size, maxSize,
streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
}
if(*size + validityMaskSize > maxSize) {
return SerializeIF::BUFFER_TOO_SHORT;
}
// copy validity buffer to end
std::memcpy(*buffer, validityMask, validityMaskSize);
*size += validityMaskSize;
return result;
2020-10-01 12:05:24 +02:00
}
ReturnValue_t LocalPoolDataSetBase::deSerializeWithValidityBuffer(
2021-01-13 12:41:24 +01:00
const uint8_t **buffer, size_t *size,
SerializeIF::Endianness streamEndianness) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
for (uint16_t count = 0; count < fillCount; count++) {
result = registeredVariables[count]->deSerialize(buffer, size,
streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
}
if(*size < std::ceil(static_cast<float>(fillCount) / 8.0)) {
return SerializeIF::STREAM_TOO_SHORT;
}
uint8_t validBufferIndex = 0;
uint8_t validBufferIndexBit = 0;
for (uint16_t count = 0; count < fillCount; count++) {
// set validity buffer here.
bool nextVarValid = this->bitGetter(*buffer +
validBufferIndex, validBufferIndexBit);
registeredVariables[count]->setValid(nextVarValid);
if(validBufferIndexBit == 7) {
validBufferIndex ++;
validBufferIndexBit = 0;
}
else {
validBufferIndexBit ++;
}
}
return result;
2020-10-01 12:05:24 +02:00
}
2020-12-03 13:00:04 +01:00
2020-10-01 12:05:24 +02:00
ReturnValue_t LocalPoolDataSetBase::unlockDataPool() {
2021-01-13 12:41:24 +01:00
if(mutexIfSingleDataCreator != nullptr) {
return mutexIfSingleDataCreator->unlockMutex();
}
return HasReturnvaluesIF::RETURN_OK;
2020-10-01 12:05:24 +02:00
}
ReturnValue_t LocalPoolDataSetBase::serializeLocalPoolIds(uint8_t** buffer,
2021-01-13 12:41:24 +01:00
size_t* size, size_t maxSize,SerializeIF::Endianness streamEndianness,
bool serializeFillCount) const {
// Serialize as uint8_t
uint8_t fillCount = this->fillCount;
if(serializeFillCount) {
SerializeAdapter::serialize(&fillCount, buffer, size, maxSize,
streamEndianness);
}
for (uint16_t count = 0; count < fillCount; count++) {
lp_id_t currentPoolId = registeredVariables[count]->getDataPoolId();
auto result = SerializeAdapter::serialize(&currentPoolId, buffer,
size, maxSize, streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK) {
2021-01-03 14:16:52 +01:00
#if FSFW_CPP_OSTREAM_ENABLED == 1
2021-01-13 12:41:24 +01:00
sif::warning << "LocalPoolDataSetBase::serializeLocalPoolIds: "
<< "Serialization error!" << std::endl;
#else
2021-01-13 12:41:24 +01:00
sif::printWarning("LocalPoolDataSetBase::serializeLocalPoolIds: "
"Serialization error!\n\r");
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
2021-01-13 12:41:24 +01:00
return result;
}
}
return HasReturnvaluesIF::RETURN_OK;
2020-10-01 12:05:24 +02:00
}
uint8_t LocalPoolDataSetBase::getLocalPoolIdsSerializedSize(
2021-01-13 12:41:24 +01:00
bool serializeFillCount) const {
if(serializeFillCount) {
return fillCount * sizeof(lp_id_t) + sizeof(uint8_t);
}
else {
return fillCount * sizeof(lp_id_t);
}
2020-10-01 12:05:24 +02:00
}
size_t LocalPoolDataSetBase::getSerializedSize() const {
2021-01-13 12:41:24 +01:00
if(withValidityBuffer) {
uint8_t validityMaskSize = std::ceil(static_cast<float>(fillCount)/8.0);
return validityMaskSize + PoolDataSetBase::getSerializedSize();
}
else {
return PoolDataSetBase::getSerializedSize();
}
2020-10-01 12:05:24 +02:00
}
void LocalPoolDataSetBase::setValidityBufferGeneration(
2021-01-13 12:41:24 +01:00
bool withValidityBuffer) {
this->withValidityBuffer = withValidityBuffer;
2020-10-01 12:05:24 +02:00
}
ReturnValue_t LocalPoolDataSetBase::deSerialize(const uint8_t **buffer,
2021-01-13 12:41:24 +01:00
size_t *size, SerializeIF::Endianness streamEndianness) {
if(withValidityBuffer) {
return this->deSerializeWithValidityBuffer(buffer, size,
streamEndianness);
}
else {
return PoolDataSetBase::deSerialize(buffer, size, streamEndianness);
}
2020-10-01 12:05:24 +02:00
}
ReturnValue_t LocalPoolDataSetBase::serialize(uint8_t **buffer, size_t *size,
2021-01-13 12:41:24 +01:00
size_t maxSize, SerializeIF::Endianness streamEndianness) const {
if(withValidityBuffer) {
return this->serializeWithValidityBuffer(buffer, size,
maxSize, streamEndianness);
}
else {
return PoolDataSetBase::serialize(buffer, size, maxSize,
streamEndianness);
}
2020-10-01 12:05:24 +02:00
}
void LocalPoolDataSetBase::bitSetter(uint8_t* byte, uint8_t position) const {
2021-01-13 12:41:24 +01:00
if(position > 7) {
2021-01-03 14:16:52 +01:00
#if FSFW_CPP_OSTREAM_ENABLED == 1
2021-01-13 12:41:24 +01:00
sif::warning << "LocalPoolDataSetBase::bitSetter: Invalid position!"
<< std::endl;
#else
2021-01-13 12:41:24 +01:00
sif::printWarning("LocalPoolDataSetBase::bitSetter: "
"Invalid position!\n\r");
#endif
2021-01-13 12:41:24 +01:00
return;
}
uint8_t shiftNumber = position + (7 - 2 * position);
*byte |= 1 << shiftNumber;
2020-10-01 12:05:24 +02:00
}
void LocalPoolDataSetBase::setDiagnostic(bool isDiagnostics) {
2021-01-13 12:41:24 +01:00
this->diagnostic = isDiagnostics;
2020-10-01 12:05:24 +02:00
}
bool LocalPoolDataSetBase::isDiagnostics() const {
2021-01-13 12:41:24 +01:00
return diagnostic;
2020-10-01 12:05:24 +02:00
}
void LocalPoolDataSetBase::setReportingEnabled(bool reportingEnabled) {
2021-01-13 12:41:24 +01:00
this->reportingEnabled = reportingEnabled;
2020-10-01 12:05:24 +02:00
}
bool LocalPoolDataSetBase::getReportingEnabled() const {
2021-01-13 12:41:24 +01:00
return reportingEnabled;
2020-10-01 12:05:24 +02:00
}
void LocalPoolDataSetBase::initializePeriodicHelper(
2021-01-13 12:41:24 +01:00
float collectionInterval, dur_millis_t minimumPeriodicInterval,
bool isDiagnostics, uint8_t nonDiagIntervalFactor) {
periodicHelper->initialize(collectionInterval, minimumPeriodicInterval,
isDiagnostics, nonDiagIntervalFactor);
2020-10-01 12:05:24 +02:00
}
void LocalPoolDataSetBase::setChanged(bool changed) {
2021-01-13 12:41:24 +01:00
this->changed = changed;
2020-10-01 12:05:24 +02:00
}
2020-12-03 13:00:04 +01:00
bool LocalPoolDataSetBase::hasChanged() const {
2021-01-13 12:41:24 +01:00
return changed;
2020-10-01 12:05:24 +02:00
}
sid_t LocalPoolDataSetBase::getSid() const {
2021-01-13 12:41:24 +01:00
return sid;
2020-10-01 12:05:24 +02:00
}
bool LocalPoolDataSetBase::bitGetter(const uint8_t* byte,
2021-01-13 12:41:24 +01:00
uint8_t position) const {
if(position > 7) {
2021-01-03 14:16:52 +01:00
#if FSFW_CPP_OSTREAM_ENABLED == 1
2021-01-13 12:41:24 +01:00
sif::debug << "Pool Raw Access: Bit setting invalid position"
<< std::endl;
#endif
2021-01-13 12:41:24 +01:00
return false;
}
uint8_t shiftNumber = position + (7 - 2 * position);
return *byte & (1 << shiftNumber);
2020-10-01 12:05:24 +02:00
}
bool LocalPoolDataSetBase::isValid() const {
2021-01-13 12:41:24 +01:00
return this->valid;
2020-10-01 12:05:24 +02:00
}
void LocalPoolDataSetBase::setValidity(bool valid, bool setEntriesRecursively) {
2021-01-13 12:41:24 +01:00
if(setEntriesRecursively) {
for(size_t idx = 0; idx < this->getFillCount(); idx++) {
registeredVariables[idx] -> setValid(valid);
}
}
this->valid = valid;
2020-10-01 12:05:24 +02:00
}
2021-01-12 00:13:49 +01:00
object_id_t LocalPoolDataSetBase::getCreatorObjectId() {
2021-01-13 12:41:24 +01:00
if(poolManager != nullptr) {
return poolManager->getCreatorObjectId();
}
return objects::NO_OBJECT;
2021-01-11 16:33:02 +01:00
}