2020-09-06 15:23:38 +02:00
|
|
|
#include "PoolDataSetBase.h"
|
|
|
|
#include "../serviceinterface/ServiceInterfaceStream.h"
|
|
|
|
|
|
|
|
PoolDataSetBase::PoolDataSetBase(PoolVariableIF** registeredVariablesArray,
|
|
|
|
const size_t maxFillCount):
|
|
|
|
registeredVariables(registeredVariablesArray),
|
|
|
|
maxFillCount(maxFillCount) {
|
|
|
|
}
|
|
|
|
|
|
|
|
PoolDataSetBase::~PoolDataSetBase() {}
|
|
|
|
|
2020-12-26 23:57:23 +01:00
|
|
|
|
2020-09-06 15:23:38 +02:00
|
|
|
ReturnValue_t PoolDataSetBase::registerVariable(
|
|
|
|
PoolVariableIF *variable) {
|
2020-12-24 02:03:33 +01:00
|
|
|
if (state != States::STATE_SET_UNINITIALISED) {
|
2021-01-03 14:16:52 +01:00
|
|
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
2020-09-06 15:23:38 +02:00
|
|
|
sif::error << "DataSet::registerVariable: "
|
|
|
|
"Call made in wrong position." << std::endl;
|
2021-01-03 13:58:18 +01:00
|
|
|
#endif
|
2020-09-06 15:23:38 +02:00
|
|
|
return DataSetIF::DATA_SET_UNINITIALISED;
|
|
|
|
}
|
|
|
|
if (variable == nullptr) {
|
2021-01-03 14:16:52 +01:00
|
|
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
2020-09-06 15:23:38 +02:00
|
|
|
sif::error << "DataSet::registerVariable: "
|
|
|
|
"Pool variable is nullptr." << std::endl;
|
2021-01-03 13:58:18 +01:00
|
|
|
#endif
|
2020-09-06 15:23:38 +02:00
|
|
|
return DataSetIF::POOL_VAR_NULL;
|
|
|
|
}
|
|
|
|
if (fillCount >= maxFillCount) {
|
2021-01-03 14:16:52 +01:00
|
|
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
2020-09-06 15:23:38 +02:00
|
|
|
sif::error << "DataSet::registerVariable: "
|
|
|
|
"DataSet is full." << std::endl;
|
2021-01-03 13:58:18 +01:00
|
|
|
#endif
|
2020-09-06 15:23:38 +02:00
|
|
|
return DataSetIF::DATA_SET_FULL;
|
|
|
|
}
|
|
|
|
registeredVariables[fillCount] = variable;
|
|
|
|
fillCount++;
|
|
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
|
|
}
|
|
|
|
|
2021-01-06 21:14:23 +01:00
|
|
|
ReturnValue_t PoolDataSetBase::read(MutexIF::TimeoutType timeoutType,
|
|
|
|
uint32_t lockTimeout) {
|
2020-09-06 15:23:38 +02:00
|
|
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
2020-12-27 01:15:52 +01:00
|
|
|
ReturnValue_t error = result;
|
2020-12-24 02:03:33 +01:00
|
|
|
if (state == States::STATE_SET_UNINITIALISED) {
|
2021-01-06 21:14:23 +01:00
|
|
|
lockDataPool(timeoutType, lockTimeout);
|
2020-09-06 15:23:38 +02:00
|
|
|
for (uint16_t count = 0; count < fillCount; count++) {
|
|
|
|
result = readVariable(count);
|
|
|
|
if(result != RETURN_OK) {
|
2020-12-27 01:15:52 +01:00
|
|
|
error = result;
|
2020-09-06 15:23:38 +02:00
|
|
|
}
|
|
|
|
}
|
2020-12-24 02:03:33 +01:00
|
|
|
state = States::STATE_SET_WAS_READ;
|
2020-09-06 15:23:38 +02:00
|
|
|
unlockDataPool();
|
|
|
|
}
|
|
|
|
else {
|
2021-01-03 14:16:52 +01:00
|
|
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
2020-09-06 15:23:38 +02:00
|
|
|
sif::error << "DataSet::read(): "
|
|
|
|
"Call made in wrong position. Don't forget to commit"
|
|
|
|
" member datasets!" << std::endl;
|
2021-01-03 13:58:18 +01:00
|
|
|
#endif
|
2020-09-06 15:23:38 +02:00
|
|
|
result = SET_WAS_ALREADY_READ;
|
|
|
|
}
|
2020-12-27 01:15:52 +01:00
|
|
|
|
|
|
|
if(error != HasReturnvaluesIF::RETURN_OK) {
|
|
|
|
result = error;
|
|
|
|
}
|
2020-09-06 15:23:38 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16_t PoolDataSetBase::getFillCount() const {
|
|
|
|
return fillCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PoolDataSetBase::readVariable(uint16_t count) {
|
|
|
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
2020-12-22 13:29:06 +01:00
|
|
|
if(registeredVariables[count] == nullptr) {
|
|
|
|
// configuration error.
|
|
|
|
return HasReturnvaluesIF::RETURN_FAILED;
|
|
|
|
}
|
|
|
|
|
2020-09-06 15:23:38 +02:00
|
|
|
// These checks are often performed by the respective
|
|
|
|
// variable implementation too, but I guess a double check does not hurt.
|
|
|
|
if (registeredVariables[count]->getReadWriteMode() !=
|
|
|
|
PoolVariableIF::VAR_WRITE and
|
|
|
|
registeredVariables[count]->getDataPoolId()
|
|
|
|
!= PoolVariableIF::NO_PARAMETER)
|
|
|
|
{
|
2020-12-26 23:57:23 +01:00
|
|
|
if(protectEveryReadCommitCall) {
|
2021-01-06 21:14:23 +01:00
|
|
|
result = registeredVariables[count]->read(
|
|
|
|
MutexIF::TimeoutType::WAITING, mutexTimeout);
|
2020-12-26 23:57:23 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
result = registeredVariables[count]->readWithoutLock();
|
|
|
|
}
|
|
|
|
|
2020-09-06 15:23:38 +02:00
|
|
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
|
|
|
result = INVALID_PARAMETER_DEFINITION;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2021-01-06 21:14:23 +01:00
|
|
|
ReturnValue_t PoolDataSetBase::commit(MutexIF::TimeoutType timeoutType,
|
|
|
|
uint32_t lockTimeout) {
|
2020-12-24 02:03:33 +01:00
|
|
|
if (state == States::STATE_SET_WAS_READ) {
|
2021-01-06 21:14:23 +01:00
|
|
|
handleAlreadyReadDatasetCommit(timeoutType, lockTimeout);
|
2020-09-06 15:23:38 +02:00
|
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
|
|
}
|
|
|
|
else {
|
2021-01-06 21:14:23 +01:00
|
|
|
return handleUnreadDatasetCommit(timeoutType, lockTimeout);
|
2020-09-06 15:23:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-06 21:14:23 +01:00
|
|
|
void PoolDataSetBase::handleAlreadyReadDatasetCommit(
|
|
|
|
MutexIF::TimeoutType timeoutType, uint32_t lockTimeout) {
|
|
|
|
lockDataPool(timeoutType, lockTimeout);
|
2020-09-06 15:23:38 +02:00
|
|
|
for (uint16_t count = 0; count < fillCount; count++) {
|
|
|
|
if (registeredVariables[count]->getReadWriteMode()
|
|
|
|
!= PoolVariableIF::VAR_READ
|
|
|
|
&& registeredVariables[count]->getDataPoolId()
|
|
|
|
!= PoolVariableIF::NO_PARAMETER) {
|
2020-12-26 23:57:23 +01:00
|
|
|
if(protectEveryReadCommitCall) {
|
2021-01-06 21:14:23 +01:00
|
|
|
registeredVariables[count]->commit(
|
|
|
|
MutexIF::TimeoutType::WAITING, mutexTimeout);
|
2020-12-26 23:57:23 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
registeredVariables[count]->commitWithoutLock();
|
|
|
|
}
|
2020-09-06 15:23:38 +02:00
|
|
|
}
|
|
|
|
}
|
2020-12-24 02:03:33 +01:00
|
|
|
state = States::STATE_SET_UNINITIALISED;
|
2020-09-06 15:23:38 +02:00
|
|
|
unlockDataPool();
|
|
|
|
}
|
|
|
|
|
2021-01-06 21:14:23 +01:00
|
|
|
ReturnValue_t PoolDataSetBase::handleUnreadDatasetCommit(
|
|
|
|
MutexIF::TimeoutType timeoutType, uint32_t lockTimeout) {
|
2020-09-06 15:23:38 +02:00
|
|
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
2021-01-06 21:14:23 +01:00
|
|
|
lockDataPool(timeoutType, lockTimeout);
|
2020-09-06 15:23:38 +02:00
|
|
|
for (uint16_t count = 0; count < fillCount; count++) {
|
|
|
|
if (registeredVariables[count]->getReadWriteMode()
|
|
|
|
== PoolVariableIF::VAR_WRITE
|
|
|
|
&& registeredVariables[count]->getDataPoolId()
|
|
|
|
!= PoolVariableIF::NO_PARAMETER) {
|
2020-12-26 23:57:23 +01:00
|
|
|
if(protectEveryReadCommitCall) {
|
2021-01-06 21:14:23 +01:00
|
|
|
result = registeredVariables[count]->commit(
|
|
|
|
MutexIF::TimeoutType::WAITING, mutexTimeout);
|
2020-12-26 23:57:23 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
result = registeredVariables[count]->commitWithoutLock();
|
|
|
|
}
|
|
|
|
|
2020-09-06 15:23:38 +02:00
|
|
|
} else if (registeredVariables[count]->getDataPoolId()
|
|
|
|
!= PoolVariableIF::NO_PARAMETER) {
|
|
|
|
if (result != COMMITING_WITHOUT_READING) {
|
2021-01-03 14:16:52 +01:00
|
|
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
2020-09-06 15:23:38 +02:00
|
|
|
sif::error << "DataSet::commit(): commit-without-read call made "
|
|
|
|
"with non write-only variable." << std::endl;
|
2021-01-03 13:58:18 +01:00
|
|
|
#endif
|
2020-09-06 15:23:38 +02:00
|
|
|
result = COMMITING_WITHOUT_READING;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-12-24 02:03:33 +01:00
|
|
|
state = States::STATE_SET_UNINITIALISED;
|
2020-09-06 15:23:38 +02:00
|
|
|
unlockDataPool();
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-01-06 21:14:23 +01:00
|
|
|
ReturnValue_t PoolDataSetBase::lockDataPool(MutexIF::TimeoutType timeoutType,
|
|
|
|
uint32_t lockTimeout) {
|
2020-09-06 15:23:38 +02:00
|
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PoolDataSetBase::unlockDataPool() {
|
|
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PoolDataSetBase::serialize(uint8_t** buffer, size_t* size,
|
|
|
|
const size_t maxSize, SerializeIF::Endianness streamEndianness) const {
|
|
|
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
|
|
|
|
for (uint16_t count = 0; count < fillCount; count++) {
|
|
|
|
result = registeredVariables[count]->serialize(buffer, size, maxSize,
|
|
|
|
streamEndianness);
|
|
|
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PoolDataSetBase::deSerialize(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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t PoolDataSetBase::getSerializedSize() const {
|
|
|
|
uint32_t size = 0;
|
|
|
|
for (uint16_t count = 0; count < fillCount; count++) {
|
|
|
|
size += registeredVariables[count]->getSerializedSize();
|
|
|
|
}
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PoolDataSetBase::setContainer(PoolVariableIF **variablesContainer) {
|
|
|
|
this->registeredVariables = variablesContainer;
|
|
|
|
}
|
2020-12-26 23:57:23 +01:00
|
|
|
|
2021-01-10 12:53:01 +01:00
|
|
|
PoolVariableIF** PoolDataSetBase::getContainer() const {
|
|
|
|
return registeredVariables;
|
|
|
|
}
|
|
|
|
|
2020-12-26 23:57:23 +01:00
|
|
|
void PoolDataSetBase::setReadCommitProtectionBehaviour(
|
|
|
|
bool protectEveryReadCommit, uint32_t mutexTimeout) {
|
|
|
|
this->protectEveryReadCommitCall = protectEveryReadCommit;
|
|
|
|
this->mutexTimeout = mutexTimeout;
|
|
|
|
}
|