fixed merge conflicts

This commit is contained in:
2022-06-06 10:30:17 +02:00
120 changed files with 3886 additions and 1334 deletions

View File

@ -1,9 +1,6 @@
target_include_directories(${LIB_FSFW_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
)
target_include_directories(${LIB_FSFW_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(${LIB_FSFW_NAME} INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}
)
target_include_directories(${LIB_FSFW_NAME}
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
add_subdirectory(fsfw)

View File

@ -1,6 +1,4 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
version.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE version.cpp)
# Core
@ -37,22 +35,22 @@ add_subdirectory(tmtcservices)
# Optional
if(FSFW_ADD_MONITORING)
add_subdirectory(monitoring)
add_subdirectory(monitoring)
endif()
if(FSFW_ADD_PUS)
add_subdirectory(pus)
add_subdirectory(pus)
endif()
if(FSFW_ADD_TMSTORAGE)
add_subdirectory(tmstorage)
add_subdirectory(tmstorage)
endif()
if(FSFW_ADD_COORDINATES)
add_subdirectory(coordinates)
add_subdirectory(coordinates)
endif()
if(FSFW_ADD_RMAP)
add_subdirectory(rmap)
add_subdirectory(rmap)
endif()
if(FSFW_ADD_DATALINKLAYER)
add_subdirectory(datalinklayer)
add_subdirectory(datalinklayer)
endif()
# OSAL

View File

@ -1,9 +1,11 @@
#ifndef FSFW_VERSION_H_
#define FSFW_VERSION_H_
// Versioning is kept in project CMakeLists.txt file
#define FSFW_VERSION_MAJOR @FSFW_VERSION@
#define FSFW_VERSION_MINOR @FSFW_SUBVERSION@
#define FSFW_VERSION_REVISION @FSFW_REVISION@
// Versioning is managed in project CMakeLists.txt file
static constexpr int FSFW_VERSION_MAJOR = @FSFW_VERSION@;
static constexpr int FSFW_VERSION_MINOR = @FSFW_SUBVERSION@;
static constexpr int FSFW_VERSION_REVISION = @FSFW_REVISION@;
// Also contains CST (Commits since tag) information
static const char FSFW_VCS_INFO[] = "@FSFW_VCS_INFO@";
#endif /* FSFW_VERSION_H_ */

View File

@ -1,7 +1,3 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
ActionHelper.cpp
ActionMessage.cpp
CommandActionHelper.cpp
SimpleActionHelper.cpp
)
target_sources(
${LIB_FSFW_NAME} PRIVATE ActionHelper.cpp ActionMessage.cpp
CommandActionHelper.cpp SimpleActionHelper.cpp)

View File

@ -1,7 +1,4 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
CFDPHandler.cpp
CFDPMessage.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE CFDPHandler.cpp CFDPMessage.cpp)
add_subdirectory(pdu)
add_subdirectory(tlv)

View File

@ -1,32 +1,30 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
PduConfig.cpp
VarLenField.cpp
HeaderSerializer.cpp
HeaderDeserializer.cpp
FileDirectiveDeserializer.cpp
FileDirectiveSerializer.cpp
AckInfo.cpp
AckPduSerializer.cpp
AckPduDeserializer.cpp
EofInfo.cpp
EofPduSerializer.cpp
EofPduDeserializer.cpp
NakInfo.cpp
NakPduSerializer.cpp
NakPduDeserializer.cpp
FinishedInfo.cpp
FinishedPduSerializer.cpp
FinishedPduDeserializer.cpp
MetadataInfo.cpp
MetadataPduSerializer.cpp
MetadataPduDeserializer.cpp
KeepAlivePduSerializer.cpp
KeepAlivePduDeserializer.cpp
PromptPduSerializer.cpp
PromptPduDeserializer.cpp
FileDataSerializer.cpp
FileDataDeserializer.cpp
FileDataInfo.cpp
)
target_sources(
${LIB_FSFW_NAME}
PRIVATE PduConfig.cpp
VarLenField.cpp
HeaderSerializer.cpp
HeaderDeserializer.cpp
FileDirectiveDeserializer.cpp
FileDirectiveSerializer.cpp
AckInfo.cpp
AckPduSerializer.cpp
AckPduDeserializer.cpp
EofInfo.cpp
EofPduSerializer.cpp
EofPduDeserializer.cpp
NakInfo.cpp
NakPduSerializer.cpp
NakPduDeserializer.cpp
FinishedInfo.cpp
FinishedPduSerializer.cpp
FinishedPduDeserializer.cpp
MetadataInfo.cpp
MetadataPduSerializer.cpp
MetadataPduDeserializer.cpp
KeepAlivePduSerializer.cpp
KeepAlivePduDeserializer.cpp
PromptPduSerializer.cpp
PromptPduDeserializer.cpp
FileDataSerializer.cpp
FileDataDeserializer.cpp
FileDataInfo.cpp)

View File

@ -1,10 +1,10 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
EntityIdTlv.cpp
FilestoreRequestTlv.cpp
FilestoreResponseTlv.cpp
Lv.cpp
Tlv.cpp
FlowLabelTlv.cpp
MessageToUserTlv.cpp
FaultHandlerOverrideTlv.cpp
)
target_sources(
${LIB_FSFW_NAME}
PRIVATE EntityIdTlv.cpp
FilestoreRequestTlv.cpp
FilestoreResponseTlv.cpp
Lv.cpp
Tlv.cpp
FlowLabelTlv.cpp
MessageToUserTlv.cpp
FaultHandlerOverrideTlv.cpp)

View File

@ -1,5 +1,2 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
SharedRingBuffer.cpp
SimpleRingBuffer.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE SharedRingBuffer.cpp
SimpleRingBuffer.cpp)

View File

@ -5,89 +5,88 @@
#error Include FIFOBase.h before FIFOBase.tpp!
#endif
template<typename T>
inline FIFOBase<T>::FIFOBase(T* values, const size_t maxCapacity):
maxCapacity(maxCapacity), values(values){};
template <typename T>
inline FIFOBase<T>::FIFOBase(T* values, const size_t maxCapacity)
: maxCapacity(maxCapacity), values(values){};
template<typename T>
template <typename T>
inline ReturnValue_t FIFOBase<T>::insert(T value) {
if (full()) {
return FULL;
} else {
values[writeIndex] = value;
writeIndex = next(writeIndex);
++currentSize;
return HasReturnvaluesIF::RETURN_OK;
}
if (full()) {
return FULL;
} else {
values[writeIndex] = value;
writeIndex = next(writeIndex);
++currentSize;
return HasReturnvaluesIF::RETURN_OK;
}
};
template<typename T>
template <typename T>
inline ReturnValue_t FIFOBase<T>::retrieve(T* value) {
if (empty()) {
return EMPTY;
} else {
if (value == nullptr){
return HasReturnvaluesIF::RETURN_FAILED;
}
*value = values[readIndex];
readIndex = next(readIndex);
--currentSize;
return HasReturnvaluesIF::RETURN_OK;
if (empty()) {
return EMPTY;
} else {
if (value == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}
*value = values[readIndex];
readIndex = next(readIndex);
--currentSize;
return HasReturnvaluesIF::RETURN_OK;
}
};
template<typename T>
template <typename T>
inline ReturnValue_t FIFOBase<T>::peek(T* value) {
if(empty()) {
return EMPTY;
} else {
if (value == nullptr){
return HasReturnvaluesIF::RETURN_FAILED;
}
*value = values[readIndex];
return HasReturnvaluesIF::RETURN_OK;
if (empty()) {
return EMPTY;
} else {
if (value == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}
*value = values[readIndex];
return HasReturnvaluesIF::RETURN_OK;
}
};
template<typename T>
template <typename T>
inline ReturnValue_t FIFOBase<T>::pop() {
T value;
return this->retrieve(&value);
T value;
return this->retrieve(&value);
};
template<typename T>
template <typename T>
inline bool FIFOBase<T>::empty() {
return (currentSize == 0);
return (currentSize == 0);
};
template<typename T>
template <typename T>
inline bool FIFOBase<T>::full() {
return (currentSize == maxCapacity);
return (currentSize == maxCapacity);
}
template<typename T>
template <typename T>
inline size_t FIFOBase<T>::size() {
return currentSize;
return currentSize;
}
template<typename T>
template <typename T>
inline size_t FIFOBase<T>::next(size_t current) {
++current;
if (current == maxCapacity) {
current = 0;
}
return current;
++current;
if (current == maxCapacity) {
current = 0;
}
return current;
}
template<typename T>
template <typename T>
inline size_t FIFOBase<T>::getMaxCapacity() const {
return maxCapacity;
return maxCapacity;
}
template<typename T>
inline void FIFOBase<T>::setContainer(T *data) {
this->values = data;
template <typename T>
inline void FIFOBase<T>::setContainer(T* data) {
this->values = data;
}
#endif

View File

@ -2,6 +2,7 @@
#define FIXEDARRAYLIST_H_
#include <cmath>
#include <limits>
#include "ArrayList.h"
/**
@ -9,10 +10,9 @@
*/
template <typename T, size_t MAX_SIZE, typename count_t = uint8_t>
class FixedArrayList : public ArrayList<T, count_t> {
#if !defined(_MSC_VER) && !defined(__clang__)
static_assert(MAX_SIZE <= (std::pow(2, sizeof(count_t) * 8) - 1),
static_assert(MAX_SIZE <= std::numeric_limits<count_t>::max(),
"count_t is not large enough to hold MAX_SIZE");
#endif
private:
T data[MAX_SIZE];

View File

@ -1,109 +1,109 @@
#ifndef FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_TPP_
#define FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_TPP_
template<typename key_t, typename T, typename KEY_COMPARE>
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::insert(key_t key, T value, Iterator *storedValue) {
if (_size == theMap.maxSize()) {
return MAP_FULL;
}
size_t position = findNicePlace(key);
memmove(static_cast<void*>(&theMap[position + 1]),static_cast<void*>(&theMap[position]),
(_size - position) * sizeof(std::pair<key_t,T>));
theMap[position].first = key;
theMap[position].second = value;
++_size;
if (storedValue != nullptr) {
*storedValue = Iterator(&theMap[position]);
}
return HasReturnvaluesIF::RETURN_OK;
template <typename key_t, typename T, typename KEY_COMPARE>
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::insert(key_t key, T value,
Iterator *storedValue) {
if (_size == theMap.maxSize()) {
return MAP_FULL;
}
size_t position = findNicePlace(key);
memmove(static_cast<void *>(&theMap[position + 1]), static_cast<void *>(&theMap[position]),
(_size - position) * sizeof(std::pair<key_t, T>));
theMap[position].first = key;
theMap[position].second = value;
++_size;
if (storedValue != nullptr) {
*storedValue = Iterator(&theMap[position]);
}
return HasReturnvaluesIF::RETURN_OK;
}
template<typename key_t, typename T, typename KEY_COMPARE>
template <typename key_t, typename T, typename KEY_COMPARE>
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::insert(std::pair<key_t, T> pair) {
return insert(pair.first, pair.second);
return insert(pair.first, pair.second);
}
template<typename key_t, typename T, typename KEY_COMPARE>
template <typename key_t, typename T, typename KEY_COMPARE>
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::exists(key_t key) const {
ReturnValue_t result = KEY_DOES_NOT_EXIST;
if (findFirstIndex(key) < _size) {
result = HasReturnvaluesIF::RETURN_OK;
}
return result;
ReturnValue_t result = KEY_DOES_NOT_EXIST;
if (findFirstIndex(key) < _size) {
result = HasReturnvaluesIF::RETURN_OK;
}
return result;
}
template<typename key_t, typename T, typename KEY_COMPARE>
template <typename key_t, typename T, typename KEY_COMPARE>
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::erase(Iterator *iter) {
size_t i;
if ((i = findFirstIndex((*iter).value->first)) >= _size) {
return KEY_DOES_NOT_EXIST;
}
removeFromPosition(i);
if (*iter != begin()) {
(*iter)--;
} else {
*iter = begin();
}
return HasReturnvaluesIF::RETURN_OK;
size_t i;
if ((i = findFirstIndex((*iter).value->first)) >= _size) {
return KEY_DOES_NOT_EXIST;
}
removeFromPosition(i);
if (*iter != begin()) {
(*iter)--;
} else {
*iter = begin();
}
return HasReturnvaluesIF::RETURN_OK;
}
template<typename key_t, typename T, typename KEY_COMPARE>
template <typename key_t, typename T, typename KEY_COMPARE>
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::erase(key_t key) {
size_t i;
if ((i = findFirstIndex(key)) >= _size) {
return KEY_DOES_NOT_EXIST;
}
do {
removeFromPosition(i);
i = findFirstIndex(key, i);
} while (i < _size);
return HasReturnvaluesIF::RETURN_OK;
size_t i;
if ((i = findFirstIndex(key)) >= _size) {
return KEY_DOES_NOT_EXIST;
}
do {
removeFromPosition(i);
i = findFirstIndex(key, i);
} while (i < _size);
return HasReturnvaluesIF::RETURN_OK;
}
template<typename key_t, typename T, typename KEY_COMPARE>
template <typename key_t, typename T, typename KEY_COMPARE>
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::find(key_t key, T **value) const {
ReturnValue_t result = exists(key);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
*value = &theMap[findFirstIndex(key)].second;
return HasReturnvaluesIF::RETURN_OK;
ReturnValue_t result = exists(key);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
*value = &theMap[findFirstIndex(key)].second;
return HasReturnvaluesIF::RETURN_OK;
}
template<typename key_t, typename T, typename KEY_COMPARE>
inline size_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::findFirstIndex(key_t key, size_t startAt) const {
if (startAt >= _size) {
return startAt + 1;
template <typename key_t, typename T, typename KEY_COMPARE>
inline size_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::findFirstIndex(key_t key,
size_t startAt) const {
if (startAt >= _size) {
return startAt + 1;
}
size_t i = startAt;
for (i = startAt; i < _size; ++i) {
if (theMap[i].first == key) {
return i;
}
size_t i = startAt;
for (i = startAt; i < _size; ++i) {
if (theMap[i].first == key) {
return i;
}
}
return i;
}
return i;
}
template<typename key_t, typename T, typename KEY_COMPARE>
template <typename key_t, typename T, typename KEY_COMPARE>
inline size_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::findNicePlace(key_t key) const {
size_t i = 0;
for (i = 0; i < _size; ++i) {
if (myComp(key, theMap[i].first)) {
return i;
}
size_t i = 0;
for (i = 0; i < _size; ++i) {
if (myComp(key, theMap[i].first)) {
return i;
}
return i;
}
return i;
}
template<typename key_t, typename T, typename KEY_COMPARE>
template <typename key_t, typename T, typename KEY_COMPARE>
inline void FixedOrderedMultimap<key_t, T, KEY_COMPARE>::removeFromPosition(size_t position) {
if (_size <= position) {
return;
}
memmove(static_cast<void*>(&theMap[position]), static_cast<void*>(&theMap[position + 1]),
(_size - position - 1) * sizeof(std::pair<key_t,T>));
--_size;
if (_size <= position) {
return;
}
memmove(static_cast<void *>(&theMap[position]), static_cast<void *>(&theMap[position + 1]),
(_size - position - 1) * sizeof(std::pair<key_t, T>));
--_size;
}
#endif /* FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_TPP_ */

View File

@ -1,4 +1,2 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
ControllerBase.cpp
ExtendedControllerBase.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE ControllerBase.cpp
ExtendedControllerBase.cpp)

View File

@ -1,5 +1,2 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
CoordinateTransformations.cpp
Sgp4Propagator.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE CoordinateTransformations.cpp
Sgp4Propagator.cpp)

View File

@ -1,12 +1,11 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
Clcw.cpp
DataLinkLayer.cpp
Farm1StateLockout.cpp
Farm1StateOpen.cpp
Farm1StateWait.cpp
MapPacketExtraction.cpp
TcTransferFrame.cpp
TcTransferFrameLocal.cpp
VirtualChannelReception.cpp
)
target_sources(
${LIB_FSFW_NAME}
PRIVATE Clcw.cpp
DataLinkLayer.cpp
Farm1StateLockout.cpp
Farm1StateOpen.cpp
Farm1StateWait.cpp
MapPacketExtraction.cpp
TcTransferFrame.cpp
TcTransferFrameLocal.cpp
VirtualChannelReception.cpp)

View File

@ -1,4 +1 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
PoolDataSetBase.cpp
PoolEntry.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE PoolDataSetBase.cpp PoolEntry.cpp)

View File

@ -1,10 +1,6 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
LocalDataPoolManager.cpp
LocalDataSet.cpp
LocalPoolDataSetBase.cpp
LocalPoolObjectBase.cpp
SharedLocalDataSet.cpp
)
target_sources(
${LIB_FSFW_NAME}
PRIVATE LocalDataPoolManager.cpp LocalDataSet.cpp LocalPoolDataSetBase.cpp
LocalPoolObjectBase.cpp SharedLocalDataSet.cpp)
add_subdirectory(internal)
add_subdirectory(internal)

View File

@ -5,205 +5,189 @@
#error Include LocalPoolVariable.h before LocalPoolVariable.tpp!
#endif
template<typename T>
inline LocalPoolVariable<T>::LocalPoolVariable(HasLocalDataPoolIF* hkOwner,
lp_id_t poolId, DataSetIF* dataSet, pool_rwm_t setReadWriteMode):
LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {}
template <typename T>
inline LocalPoolVariable<T>::LocalPoolVariable(HasLocalDataPoolIF* hkOwner, lp_id_t poolId,
DataSetIF* dataSet, pool_rwm_t setReadWriteMode)
: LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {}
template<typename T>
inline LocalPoolVariable<T>::LocalPoolVariable(object_id_t poolOwner,
lp_id_t poolId, DataSetIF *dataSet, pool_rwm_t setReadWriteMode):
LocalPoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {}
template <typename T>
inline LocalPoolVariable<T>::LocalPoolVariable(object_id_t poolOwner, lp_id_t poolId,
DataSetIF* dataSet, pool_rwm_t setReadWriteMode)
: LocalPoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {}
template <typename T>
inline LocalPoolVariable<T>::LocalPoolVariable(gp_id_t globalPoolId, DataSetIF* dataSet,
pool_rwm_t setReadWriteMode)
: LocalPoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId, dataSet,
setReadWriteMode) {}
template<typename T>
inline LocalPoolVariable<T>::LocalPoolVariable(gp_id_t globalPoolId,
DataSetIF *dataSet, pool_rwm_t setReadWriteMode):
LocalPoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId,
dataSet, setReadWriteMode){}
template<typename T>
inline ReturnValue_t LocalPoolVariable<T>::read(
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
if(hkManager == nullptr) {
return readWithoutLock();
}
MutexIF* mutex = LocalDpManagerAttorney::getMutexHandle(*hkManager);
ReturnValue_t result = mutex->lockMutex(timeoutType, timeoutMs);
if(result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = readWithoutLock();
mutex->unlockMutex();
template <typename T>
inline ReturnValue_t LocalPoolVariable<T>::read(MutexIF::TimeoutType timeoutType,
uint32_t timeoutMs) {
if (hkManager == nullptr) {
return readWithoutLock();
}
MutexIF* mutex = LocalDpManagerAttorney::getMutexHandle(*hkManager);
ReturnValue_t result = mutex->lockMutex(timeoutType, timeoutMs);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = readWithoutLock();
mutex->unlockMutex();
return result;
}
template<typename T>
template <typename T>
inline ReturnValue_t LocalPoolVariable<T>::readWithoutLock() {
if(readWriteMode == pool_rwm_t::VAR_WRITE) {
object_id_t targetObjectId = hkManager->getCreatorObjectId();
reportReadCommitError("LocalPoolVector",
PoolVariableIF::INVALID_READ_WRITE_MODE, true, targetObjectId,
localPoolId);
return PoolVariableIF::INVALID_READ_WRITE_MODE;
}
if (readWriteMode == pool_rwm_t::VAR_WRITE) {
object_id_t targetObjectId = hkManager->getCreatorObjectId();
reportReadCommitError("LocalPoolVector", PoolVariableIF::INVALID_READ_WRITE_MODE, true,
targetObjectId, localPoolId);
return PoolVariableIF::INVALID_READ_WRITE_MODE;
}
PoolEntry<T>* poolEntry = nullptr;
ReturnValue_t result = LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId,
&poolEntry);
if(result != RETURN_OK) {
object_id_t ownerObjectId = hkManager->getCreatorObjectId();
reportReadCommitError("LocalPoolVariable", result,
false, ownerObjectId, localPoolId);
return result;
}
this->value = *(poolEntry->getDataPtr());
this->valid = poolEntry->getValid();
return RETURN_OK;
}
template<typename T>
inline ReturnValue_t LocalPoolVariable<T>::commit(bool setValid,
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
this->setValid(setValid);
return commit(timeoutType, timeoutMs);
}
template<typename T>
inline ReturnValue_t LocalPoolVariable<T>::commit(
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
if(hkManager == nullptr) {
return commitWithoutLock();
}
MutexIF* mutex = LocalDpManagerAttorney::getMutexHandle(*hkManager);
ReturnValue_t result = mutex->lockMutex(timeoutType, timeoutMs);
if(result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = commitWithoutLock();
mutex->unlockMutex();
PoolEntry<T>* poolEntry = nullptr;
ReturnValue_t result =
LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId, &poolEntry);
if (result != RETURN_OK) {
object_id_t ownerObjectId = hkManager->getCreatorObjectId();
reportReadCommitError("LocalPoolVariable", result, false, ownerObjectId, localPoolId);
return result;
}
this->value = *(poolEntry->getDataPtr());
this->valid = poolEntry->getValid();
return RETURN_OK;
}
template<typename T>
template <typename T>
inline ReturnValue_t LocalPoolVariable<T>::commit(bool setValid, MutexIF::TimeoutType timeoutType,
uint32_t timeoutMs) {
this->setValid(setValid);
return commit(timeoutType, timeoutMs);
}
template <typename T>
inline ReturnValue_t LocalPoolVariable<T>::commit(MutexIF::TimeoutType timeoutType,
uint32_t timeoutMs) {
if (hkManager == nullptr) {
return commitWithoutLock();
}
MutexIF* mutex = LocalDpManagerAttorney::getMutexHandle(*hkManager);
ReturnValue_t result = mutex->lockMutex(timeoutType, timeoutMs);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = commitWithoutLock();
mutex->unlockMutex();
return result;
}
template <typename T>
inline ReturnValue_t LocalPoolVariable<T>::commitWithoutLock() {
if(readWriteMode == pool_rwm_t::VAR_READ) {
object_id_t targetObjectId = hkManager->getCreatorObjectId();
reportReadCommitError("LocalPoolVector",
PoolVariableIF::INVALID_READ_WRITE_MODE, false, targetObjectId,
localPoolId);
return PoolVariableIF::INVALID_READ_WRITE_MODE;
}
if (readWriteMode == pool_rwm_t::VAR_READ) {
object_id_t targetObjectId = hkManager->getCreatorObjectId();
reportReadCommitError("LocalPoolVector", PoolVariableIF::INVALID_READ_WRITE_MODE, false,
targetObjectId, localPoolId);
return PoolVariableIF::INVALID_READ_WRITE_MODE;
}
PoolEntry<T>* poolEntry = nullptr;
ReturnValue_t result = LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId,
&poolEntry);
if(result != RETURN_OK) {
object_id_t ownerObjectId = hkManager->getCreatorObjectId();
reportReadCommitError("LocalPoolVariable", result,
false, ownerObjectId, localPoolId);
return result;
}
PoolEntry<T>* poolEntry = nullptr;
ReturnValue_t result =
LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId, &poolEntry);
if (result != RETURN_OK) {
object_id_t ownerObjectId = hkManager->getCreatorObjectId();
reportReadCommitError("LocalPoolVariable", result, false, ownerObjectId, localPoolId);
return result;
}
*(poolEntry->getDataPtr()) = this->value;
poolEntry->setValid(this->valid);
return RETURN_OK;
*(poolEntry->getDataPtr()) = this->value;
poolEntry->setValid(this->valid);
return RETURN_OK;
}
template<typename T>
inline ReturnValue_t LocalPoolVariable<T>::serialize(uint8_t** buffer,
size_t* size, const size_t max_size,
SerializeIF::Endianness streamEndianness) const {
return SerializeAdapter::serialize(&value,
buffer, size ,max_size, streamEndianness);
template <typename T>
inline ReturnValue_t LocalPoolVariable<T>::serialize(
uint8_t** buffer, size_t* size, const size_t max_size,
SerializeIF::Endianness streamEndianness) const {
return SerializeAdapter::serialize(&value, buffer, size, max_size, streamEndianness);
}
template<typename T>
template <typename T>
inline size_t LocalPoolVariable<T>::getSerializedSize() const {
return SerializeAdapter::getSerializedSize(&value);
return SerializeAdapter::getSerializedSize(&value);
}
template<typename T>
inline ReturnValue_t LocalPoolVariable<T>::deSerialize(const uint8_t** buffer,
size_t* size, SerializeIF::Endianness streamEndianness) {
return SerializeAdapter::deSerialize(&value, buffer, size, streamEndianness);
template <typename T>
inline ReturnValue_t LocalPoolVariable<T>::deSerialize(const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) {
return SerializeAdapter::deSerialize(&value, buffer, size, streamEndianness);
}
#if FSFW_CPP_OSTREAM_ENABLED == 1
template<typename T>
inline std::ostream& operator<< (std::ostream &out,
const LocalPoolVariable<T> &var) {
out << var.value;
return out;
template <typename T>
inline std::ostream& operator<<(std::ostream& out, const LocalPoolVariable<T>& var) {
out << var.value;
return out;
}
#endif
template<typename T>
template <typename T>
inline LocalPoolVariable<T>::operator T() const {
return value;
return value;
}
template<typename T>
inline LocalPoolVariable<T> & LocalPoolVariable<T>::operator=(
const T& newValue) {
value = newValue;
return *this;
template <typename T>
inline LocalPoolVariable<T>& LocalPoolVariable<T>::operator=(const T& newValue) {
value = newValue;
return *this;
}
template<typename T>
inline LocalPoolVariable<T>& LocalPoolVariable<T>::operator =(
const LocalPoolVariable<T>& newPoolVariable) {
value = newPoolVariable.value;
return *this;
template <typename T>
inline LocalPoolVariable<T>& LocalPoolVariable<T>::operator=(
const LocalPoolVariable<T>& newPoolVariable) {
value = newPoolVariable.value;
return *this;
}
template<typename T>
inline bool LocalPoolVariable<T>::operator ==(
const LocalPoolVariable<T> &other) const {
return this->value == other.value;
template <typename T>
inline bool LocalPoolVariable<T>::operator==(const LocalPoolVariable<T>& other) const {
return this->value == other.value;
}
template<typename T>
inline bool LocalPoolVariable<T>::operator ==(const T &other) const {
return this->value == other;
template <typename T>
inline bool LocalPoolVariable<T>::operator==(const T& other) const {
return this->value == other;
}
template<typename T>
inline bool LocalPoolVariable<T>::operator !=(
const LocalPoolVariable<T> &other) const {
return not (*this == other);
template <typename T>
inline bool LocalPoolVariable<T>::operator!=(const LocalPoolVariable<T>& other) const {
return not(*this == other);
}
template<typename T>
inline bool LocalPoolVariable<T>::operator !=(const T &other) const {
return not (*this == other);
template <typename T>
inline bool LocalPoolVariable<T>::operator!=(const T& other) const {
return not(*this == other);
}
template<typename T>
inline bool LocalPoolVariable<T>::operator <(
const LocalPoolVariable<T> &other) const {
return this->value < other.value;
template <typename T>
inline bool LocalPoolVariable<T>::operator<(const LocalPoolVariable<T>& other) const {
return this->value < other.value;
}
template<typename T>
inline bool LocalPoolVariable<T>::operator <(const T &other) const {
return this->value < other;
template <typename T>
inline bool LocalPoolVariable<T>::operator<(const T& other) const {
return this->value < other;
}
template<typename T>
inline bool LocalPoolVariable<T>::operator >(
const LocalPoolVariable<T> &other) const {
return not (*this < other);
template <typename T>
inline bool LocalPoolVariable<T>::operator>(const LocalPoolVariable<T>& other) const {
return not(*this < other);
}
template<typename T>
inline bool LocalPoolVariable<T>::operator >(const T &other) const {
return not (*this < other);
template <typename T>
inline bool LocalPoolVariable<T>::operator>(const T& other) const {
return not(*this < other);
}
#endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_TPP_ */

View File

@ -5,174 +5,172 @@
#error Include LocalPoolVector.h before LocalPoolVector.tpp!
#endif
template<typename T, uint16_t vectorSize>
inline LocalPoolVector<T, vectorSize>::LocalPoolVector(
HasLocalDataPoolIF* hkOwner, lp_id_t poolId, DataSetIF* dataSet,
pool_rwm_t setReadWriteMode):
LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {}
template <typename T, uint16_t vectorSize>
inline LocalPoolVector<T, vectorSize>::LocalPoolVector(HasLocalDataPoolIF* hkOwner, lp_id_t poolId,
DataSetIF* dataSet,
pool_rwm_t setReadWriteMode)
: LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {}
template<typename T, uint16_t vectorSize>
inline LocalPoolVector<T, vectorSize>::LocalPoolVector(object_id_t poolOwner,
lp_id_t poolId, DataSetIF *dataSet, pool_rwm_t setReadWriteMode):
LocalPoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {}
template <typename T, uint16_t vectorSize>
inline LocalPoolVector<T, vectorSize>::LocalPoolVector(object_id_t poolOwner, lp_id_t poolId,
DataSetIF* dataSet,
pool_rwm_t setReadWriteMode)
: LocalPoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {}
template<typename T, uint16_t vectorSize>
inline LocalPoolVector<T, vectorSize>::LocalPoolVector(gp_id_t globalPoolId,
DataSetIF *dataSet, pool_rwm_t setReadWriteMode):
LocalPoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId,
dataSet, setReadWriteMode) {}
template <typename T, uint16_t vectorSize>
inline LocalPoolVector<T, vectorSize>::LocalPoolVector(gp_id_t globalPoolId, DataSetIF* dataSet,
pool_rwm_t setReadWriteMode)
: LocalPoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId, dataSet,
setReadWriteMode) {}
template<typename T, uint16_t vectorSize>
inline ReturnValue_t LocalPoolVector<T, vectorSize>::read(
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
MutexGuard(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs);
return readWithoutLock();
template <typename T, uint16_t vectorSize>
inline ReturnValue_t LocalPoolVector<T, vectorSize>::read(MutexIF::TimeoutType timeoutType,
uint32_t timeoutMs) {
MutexGuard(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs);
return readWithoutLock();
}
template<typename T, uint16_t vectorSize>
template <typename T, uint16_t vectorSize>
inline ReturnValue_t LocalPoolVector<T, vectorSize>::readWithoutLock() {
if(readWriteMode == pool_rwm_t::VAR_WRITE) {
object_id_t targetObjectId = hkManager->getCreatorObjectId();
reportReadCommitError("LocalPoolVector",
PoolVariableIF::INVALID_READ_WRITE_MODE, true, targetObjectId,
localPoolId);
return PoolVariableIF::INVALID_READ_WRITE_MODE;
}
if (readWriteMode == pool_rwm_t::VAR_WRITE) {
object_id_t targetObjectId = hkManager->getCreatorObjectId();
reportReadCommitError("LocalPoolVector", PoolVariableIF::INVALID_READ_WRITE_MODE, true,
targetObjectId, localPoolId);
return PoolVariableIF::INVALID_READ_WRITE_MODE;
}
PoolEntry<T>* poolEntry = nullptr;
ReturnValue_t result = LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId,
&poolEntry);
memset(this->value, 0, vectorSize * sizeof(T));
PoolEntry<T>* poolEntry = nullptr;
ReturnValue_t result =
LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId, &poolEntry);
memset(this->value, 0, vectorSize * sizeof(T));
if(result != RETURN_OK) {
object_id_t targetObjectId = hkManager->getCreatorObjectId();
reportReadCommitError("LocalPoolVector", result, true, targetObjectId,
localPoolId);
return result;
}
std::memcpy(this->value, poolEntry->getDataPtr(), poolEntry->getByteSize());
this->valid = poolEntry->getValid();
return RETURN_OK;
if (result != RETURN_OK) {
object_id_t targetObjectId = hkManager->getCreatorObjectId();
reportReadCommitError("LocalPoolVector", result, true, targetObjectId, localPoolId);
return result;
}
std::memcpy(this->value, poolEntry->getDataPtr(), poolEntry->getByteSize());
this->valid = poolEntry->getValid();
return RETURN_OK;
}
template<typename T, uint16_t vectorSize>
template <typename T, uint16_t vectorSize>
inline ReturnValue_t LocalPoolVector<T, vectorSize>::commit(bool valid,
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
this->setValid(valid);
return commit(timeoutType, timeoutMs);
MutexIF::TimeoutType timeoutType,
uint32_t timeoutMs) {
this->setValid(valid);
return commit(timeoutType, timeoutMs);
}
template<typename T, uint16_t vectorSize>
inline ReturnValue_t LocalPoolVector<T, vectorSize>::commit(
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
MutexGuard(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs);
return commitWithoutLock();
template <typename T, uint16_t vectorSize>
inline ReturnValue_t LocalPoolVector<T, vectorSize>::commit(MutexIF::TimeoutType timeoutType,
uint32_t timeoutMs) {
MutexGuard(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs);
return commitWithoutLock();
}
template<typename T, uint16_t vectorSize>
template <typename T, uint16_t vectorSize>
inline ReturnValue_t LocalPoolVector<T, vectorSize>::commitWithoutLock() {
if(readWriteMode == pool_rwm_t::VAR_READ) {
object_id_t targetObjectId = hkManager->getCreatorObjectId();
reportReadCommitError("LocalPoolVector",
PoolVariableIF::INVALID_READ_WRITE_MODE, false, targetObjectId,
localPoolId);
return PoolVariableIF::INVALID_READ_WRITE_MODE;
}
PoolEntry<T>* poolEntry = nullptr;
ReturnValue_t result = LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId,
&poolEntry);
if(result != RETURN_OK) {
object_id_t targetObjectId = hkManager->getCreatorObjectId();
reportReadCommitError("LocalPoolVector", result, false, targetObjectId,
localPoolId);
return result;
}
std::memcpy(poolEntry->getDataPtr(), this->value, poolEntry->getByteSize());
poolEntry->setValid(this->valid);
return RETURN_OK;
}
template<typename T, uint16_t vectorSize>
inline T& LocalPoolVector<T, vectorSize>::operator [](size_t i) {
if(i < vectorSize) {
return value[i];
}
// If this happens, I have to set some value. I consider this
// a configuration error, but I wont exit here.
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "LocalPoolVector: Invalid index. Setting or returning"
" last value!" << std::endl;
#else
sif::printWarning("LocalPoolVector: Invalid index. Setting or returning"
" last value!\n");
#endif
return value[vectorSize - 1];
}
template<typename T, uint16_t vectorSize>
inline const T& LocalPoolVector<T, vectorSize>::operator [](size_t i) const {
if(i < vectorSize) {
return value[i];
}
// If this happens, I have to set some value. I consider this
// a configuration error, but I wont exit here.
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "LocalPoolVector: Invalid index. Setting or returning"
" last value!" << std::endl;
#else
sif::printWarning("LocalPoolVector: Invalid index. Setting or returning"
" last value!\n");
#endif
return value[vectorSize - 1];
}
template<typename T, uint16_t vectorSize>
inline ReturnValue_t LocalPoolVector<T, vectorSize>::serialize(uint8_t** buffer,
size_t* size, size_t maxSize,
SerializeIF::Endianness streamEndianness) const {
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
for (uint16_t i = 0; i < vectorSize; i++) {
result = SerializeAdapter::serialize(&(value[i]), buffer, size,
maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
break;
}
}
if (readWriteMode == pool_rwm_t::VAR_READ) {
object_id_t targetObjectId = hkManager->getCreatorObjectId();
reportReadCommitError("LocalPoolVector", PoolVariableIF::INVALID_READ_WRITE_MODE, false,
targetObjectId, localPoolId);
return PoolVariableIF::INVALID_READ_WRITE_MODE;
}
PoolEntry<T>* poolEntry = nullptr;
ReturnValue_t result =
LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId, &poolEntry);
if (result != RETURN_OK) {
object_id_t targetObjectId = hkManager->getCreatorObjectId();
reportReadCommitError("LocalPoolVector", result, false, targetObjectId, localPoolId);
return result;
}
std::memcpy(poolEntry->getDataPtr(), this->value, poolEntry->getByteSize());
poolEntry->setValid(this->valid);
return RETURN_OK;
}
template<typename T, uint16_t vectorSize>
template <typename T, uint16_t vectorSize>
inline T& LocalPoolVector<T, vectorSize>::operator[](size_t i) {
if (i < vectorSize) {
return value[i];
}
// If this happens, I have to set some value. I consider this
// a configuration error, but I wont exit here.
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "LocalPoolVector: Invalid index. Setting or returning"
" last value!"
<< std::endl;
#else
sif::printWarning(
"LocalPoolVector: Invalid index. Setting or returning"
" last value!\n");
#endif
return value[vectorSize - 1];
}
template <typename T, uint16_t vectorSize>
inline const T& LocalPoolVector<T, vectorSize>::operator[](size_t i) const {
if (i < vectorSize) {
return value[i];
}
// If this happens, I have to set some value. I consider this
// a configuration error, but I wont exit here.
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "LocalPoolVector: Invalid index. Setting or returning"
" last value!"
<< std::endl;
#else
sif::printWarning(
"LocalPoolVector: Invalid index. Setting or returning"
" last value!\n");
#endif
return value[vectorSize - 1];
}
template <typename T, uint16_t vectorSize>
inline ReturnValue_t LocalPoolVector<T, vectorSize>::serialize(
uint8_t** buffer, size_t* size, size_t maxSize,
SerializeIF::Endianness streamEndianness) const {
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
for (uint16_t i = 0; i < vectorSize; i++) {
result = SerializeAdapter::serialize(&(value[i]), buffer, size, maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
break;
}
}
return result;
}
template <typename T, uint16_t vectorSize>
inline size_t LocalPoolVector<T, vectorSize>::getSerializedSize() const {
return vectorSize * SerializeAdapter::getSerializedSize(value);
return vectorSize * SerializeAdapter::getSerializedSize(value);
}
template<typename T, uint16_t vectorSize>
template <typename T, uint16_t vectorSize>
inline ReturnValue_t LocalPoolVector<T, vectorSize>::deSerialize(
const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
for (uint16_t i = 0; i < vectorSize; i++) {
result = SerializeAdapter::deSerialize(&(value[i]), buffer, size,
streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
break;
}
const uint8_t** buffer, size_t* size, SerializeIF::Endianness streamEndianness) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
for (uint16_t i = 0; i < vectorSize; i++) {
result = SerializeAdapter::deSerialize(&(value[i]), buffer, size, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
break;
}
return result;
}
return result;
}
#if FSFW_CPP_OSTREAM_ENABLED == 1
template<typename T, uint16_t vectorSize>
inline std::ostream& operator<< (std::ostream &out,
const LocalPoolVector<T, vectorSize> &var) {
out << "Vector: [";
for(int i = 0;i < vectorSize; i++) {
out << var.value[i];
if(i < vectorSize - 1) {
out << ", ";
}
template <typename T, uint16_t vectorSize>
inline std::ostream& operator<<(std::ostream& out, const LocalPoolVector<T, vectorSize>& var) {
out << "Vector: [";
for (int i = 0; i < vectorSize; i++) {
out << var.value[i];
if (i < vectorSize - 1) {
out << ", ";
}
out << "]";
return out;
}
out << "]";
return out;
}
#endif

View File

@ -1,5 +1,2 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
HasLocalDpIFUserAttorney.cpp
HasLocalDpIFManagerAttorney.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE HasLocalDpIFUserAttorney.cpp
HasLocalDpIFManagerAttorney.cpp)

View File

@ -1,11 +1,10 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
AssemblyBase.cpp
ChildHandlerBase.cpp
ChildHandlerFDIR.cpp
DeviceHandlerBase.cpp
DeviceHandlerFailureIsolation.cpp
DeviceHandlerMessage.cpp
DeviceTmReportingWrapper.cpp
HealthDevice.cpp
)
target_sources(
${LIB_FSFW_NAME}
PRIVATE AssemblyBase.cpp
ChildHandlerBase.cpp
ChildHandlerFDIR.cpp
DeviceHandlerBase.cpp
DeviceHandlerFailureIsolation.cpp
DeviceHandlerMessage.cpp
DeviceTmReportingWrapper.cpp
HealthDevice.cpp)

View File

@ -1074,7 +1074,8 @@ class DeviceHandlerBase : public DeviceHandlerIF,
/**
* Same as triggerEvent, but for forwarding if object is used as proxy.
*/
virtual void forwardEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0) const override;
virtual void forwardEvent(Event event, uint32_t parameter1 = 0,
uint32_t parameter2 = 0) const override;
/**
* Checks if current mode is transitional mode.

View File

@ -1,6 +1,3 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
EventManager.cpp
EventMessage.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE EventManager.cpp EventMessage.cpp)
add_subdirectory(eventmatching)

View File

@ -1,7 +1,3 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
EventIdRangeMatcher.cpp
EventMatchTree.cpp
ReporterRangeMatcher.cpp
SeverityRangeMatcher.cpp
)
target_sources(
${LIB_FSFW_NAME} PRIVATE EventIdRangeMatcher.cpp EventMatchTree.cpp
ReporterRangeMatcher.cpp SeverityRangeMatcher.cpp)

View File

@ -27,6 +27,7 @@ enum : uint8_t {
PUS_SERVICE_6 = 86,
PUS_SERVICE_8 = 88,
PUS_SERVICE_9 = 89,
PUS_SERVICE_11 = 91,
PUS_SERVICE_17 = 97,
PUS_SERVICE_23 = 103,
MGM_LIS3MDL = 106,

View File

@ -1,6 +1,3 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
EventCorrelation.cpp
FailureIsolationBase.cpp
FaultCounter.cpp
)
target_sources(
${LIB_FSFW_NAME} PRIVATE EventCorrelation.cpp FailureIsolationBase.cpp
FaultCounter.cpp)

View File

@ -1,13 +1,12 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
arrayprinter.cpp
AsciiConverter.cpp
CRC.cpp
DleEncoder.cpp
PeriodicOperationDivider.cpp
timevalOperations.cpp
Type.cpp
bitutility.cpp
)
target_sources(
${LIB_FSFW_NAME}
PRIVATE arrayprinter.cpp
AsciiConverter.cpp
CRC.cpp
DleEncoder.cpp
PeriodicOperationDivider.cpp
timevalOperations.cpp
Type.cpp
bitutility.cpp)
add_subdirectory(math)

View File

@ -1,4 +1 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
QuaternionOperations.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE QuaternionOperations.cpp)

View File

@ -1,6 +1,2 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
HealthHelper.cpp
HealthMessage.cpp
HealthTable.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE HealthHelper.cpp HealthMessage.cpp
HealthTable.cpp)

View File

@ -1,5 +1,2 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
HousekeepingMessage.cpp
PeriodicHousekeepingHelper.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE HousekeepingMessage.cpp
PeriodicHousekeepingHelper.cpp)

View File

@ -1,4 +1 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
InternalErrorReporter.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE InternalErrorReporter.cpp)

View File

@ -1,6 +1,3 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
CommandMessage.cpp
CommandMessageCleaner.cpp
MessageQueueMessage.cpp
MessageQueueBase.cpp
)
target_sources(
${LIB_FSFW_NAME} PRIVATE CommandMessage.cpp CommandMessageCleaner.cpp
MessageQueueMessage.cpp MessageQueueBase.cpp)

View File

@ -1,5 +1,2 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
MemoryHelper.cpp
MemoryMessage.cpp
GenericFileSystemMessage.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE MemoryHelper.cpp MemoryMessage.cpp
GenericFileSystemMessage.cpp)

View File

@ -1,5 +1 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
ModeHelper.cpp
ModeMessage.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE ModeHelper.cpp ModeMessage.cpp)

View File

@ -1,5 +1,2 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
LimitViolationReporter.cpp
MonitoringMessage.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE LimitViolationReporter.cpp
MonitoringMessage.cpp)

View File

@ -1,5 +1 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
ObjectManager.cpp
SystemObject.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE ObjectManager.cpp SystemObject.cpp)

View File

@ -50,7 +50,8 @@ class SystemObject : public SystemObjectIF {
virtual ReturnValue_t initialize() override;
virtual ReturnValue_t checkObjectConnections() override;
virtual void forwardEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0) const override;
virtual void forwardEvent(Event event, uint32_t parameter1 = 0,
uint32_t parameter2 = 0) const override;
};
#endif /* FSFW_OBJECTMANAGER_SYSTEMOBJECT_H_ */

View File

@ -14,6 +14,7 @@ enum framework_objects : object_id_t {
PUS_SERVICE_5_EVENT_REPORTING = 0x53000005,
PUS_SERVICE_8_FUNCTION_MGMT = 0x53000008,
PUS_SERVICE_9_TIME_MGMT = 0x53000009,
PUS_SERVICE_11_TC_SCHEDULER = 0x53000011,
PUS_SERVICE_17_TEST = 0x53000017,
PUS_SERVICE_20_PARAMETERS = 0x53000020,
PUS_SERVICE_200_MODE_MGMT = 0x53000200,

View File

@ -1,35 +1,33 @@
# Check the OS_FSFW variable
if(FSFW_OSAL MATCHES "freertos")
add_subdirectory(freertos)
add_subdirectory(freertos)
elseif(FSFW_OSAL MATCHES "rtems")
add_subdirectory(rtems)
add_subdirectory(rtems)
elseif(FSFW_OSAL MATCHES "linux")
add_subdirectory(linux)
add_subdirectory(linux)
elseif(FSFW_OSAL MATCHES "host")
add_subdirectory(host)
if (WIN32)
add_subdirectory(windows)
elseif(UNIX)
# We still need to pull in some Linux specific sources
target_sources(${LIB_FSFW_NAME} PUBLIC
linux/tcpipHelpers.cpp
)
endif ()
add_subdirectory(host)
if(WIN32)
add_subdirectory(windows)
elseif(UNIX)
# We still need to pull in some Linux specific sources
target_sources(${LIB_FSFW_NAME} PUBLIC linux/tcpipHelpers.cpp)
endif()
else()
message(WARNING "The OS_FSFW variable was not set. Assuming host OS..")
# Not set. Assumuing this is a host build, try to determine host OS
if (WIN32)
add_subdirectory(host)
add_subdirectory(windows)
elseif (UNIX)
add_subdirectory(linux)
else ()
# MacOS or other OSes have not been tested yet / are not supported.
message(FATAL_ERROR "The host OS could not be determined! Aborting.")
endif()
message(WARNING "The OS_FSFW variable was not set. Assuming host OS..")
# Not set. Assumuing this is a host build, try to determine host OS
if(WIN32)
add_subdirectory(host)
add_subdirectory(windows)
elseif(UNIX)
add_subdirectory(linux)
else()
# MacOS or other OSes have not been tested yet / are not supported.
message(FATAL_ERROR "The host OS could not be determined! Aborting.")
endif()
endif()
add_subdirectory(common)
add_subdirectory(common)

View File

@ -1,17 +1,10 @@
if(DEFINED WIN32 OR DEFINED UNIX)
target_sources(${LIB_FSFW_NAME} PRIVATE
tcpipCommon.cpp
TcpIpBase.cpp
UdpTcPollingTask.cpp
UdpTmTcBridge.cpp
TcpTmTcServer.cpp
TcpTmTcBridge.cpp
)
target_sources(
${LIB_FSFW_NAME}
PRIVATE tcpipCommon.cpp TcpIpBase.cpp UdpTcPollingTask.cpp
UdpTmTcBridge.cpp TcpTmTcServer.cpp TcpTmTcBridge.cpp)
endif()
if(WIN32)
target_link_libraries(${LIB_FSFW_NAME} PRIVATE
wsock32
ws2_32
)
endif()
target_link_libraries(${LIB_FSFW_NAME} PRIVATE wsock32 ws2_32)
endif()

View File

@ -19,6 +19,8 @@
#include <ws2tcpip.h>
#elif defined(PLATFORM_UNIX)
#include <netdb.h>
#include <utility>
#endif
const std::string TcpTmTcServer::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT;
@ -29,7 +31,7 @@ TcpTmTcServer::TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge,
: SystemObject(objectId),
tmtcBridgeId(tmtcTcpBridge),
receptionMode(receptionMode),
tcpConfig(customTcpServerPort),
tcpConfig(std::move(customTcpServerPort)),
receptionBuffer(receptionBufferSize),
ringBuffer(ringBufferSize, true) {}
@ -103,12 +105,12 @@ ReturnValue_t TcpTmTcServer::initialize() {
TcpTmTcServer::~TcpTmTcServer() { closeSocket(listenerTcpSocket); }
ReturnValue_t TcpTmTcServer::performOperation(uint8_t opCode) {
[[noreturn]] ReturnValue_t TcpTmTcServer::performOperation(uint8_t opCode) {
using namespace tcpip;
// If a connection is accepted, the corresponding socket will be assigned to the new socket
socket_t connSocket = 0;
// sockaddr clientSockAddr = {};
// socklen_t connectorSockAddrLen = 0;
sockaddr clientSockAddr = {};
socklen_t connectorSockAddrLen = 0;
int retval = 0;
// Listen for connection requests permanently for lifetime of program
@ -119,8 +121,7 @@ ReturnValue_t TcpTmTcServer::performOperation(uint8_t opCode) {
continue;
}
// connSocket = accept(listenerTcpSocket, &clientSockAddr, &connectorSockAddrLen);
connSocket = accept(listenerTcpSocket, nullptr, nullptr);
connSocket = accept(listenerTcpSocket, &clientSockAddr, &connectorSockAddrLen);
if (connSocket == INVALID_SOCKET) {
handleError(Protocol::TCP, ErrorSources::ACCEPT_CALL, 500);
@ -135,10 +136,10 @@ ReturnValue_t TcpTmTcServer::performOperation(uint8_t opCode) {
if (retval != 0) {
handleError(Protocol::TCP, ErrorSources::SHUTDOWN_CALL);
}
closeSocket(connSocket);
connSocket = 0;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t TcpTmTcServer::initializeAfterTaskCreation() {
@ -159,8 +160,8 @@ void TcpTmTcServer::handleServerOperation(socket_t& connSocket) {
#endif
while (true) {
int retval = recv(connSocket, reinterpret_cast<char*>(receptionBuffer.data()),
receptionBuffer.capacity(), tcpConfig.tcpFlags);
ssize_t retval = recv(connSocket, reinterpret_cast<char*>(receptionBuffer.data()),
receptionBuffer.capacity(), tcpConfig.tcpFlags);
if (retval == 0) {
size_t availableReadData = ringBuffer.getAvailableReadData();
if (availableReadData > lastRingBufferSize) {
@ -252,17 +253,17 @@ ReturnValue_t TcpTmTcServer::handleTcReception(uint8_t* spacePacket, size_t pack
return result;
}
std::string TcpTmTcServer::getTcpPort() const { return tcpConfig.tcpPort; }
const std::string& TcpTmTcServer::getTcpPort() const { return tcpConfig.tcpPort; }
void TcpTmTcServer::setSpacePacketParsingOptions(std::vector<uint16_t> validPacketIds) {
this->validPacketIds = validPacketIds;
void TcpTmTcServer::setSpacePacketParsingOptions(std::vector<uint16_t> validPacketIds_) {
this->validPacketIds = std::move(validPacketIds_);
}
TcpTmTcServer::TcpConfig& TcpTmTcServer::getTcpConfigStruct() { return tcpConfig; }
ReturnValue_t TcpTmTcServer::handleTmSending(socket_t connSocket, bool& tmSent) {
// Access to the FIFO is mutex protected because it is filled by the bridge
MutexGuard(tmtcBridge->mutex, tmtcBridge->timeoutType, tmtcBridge->mutexTimeoutMs);
MutexGuard mg(tmtcBridge->mutex, tmtcBridge->timeoutType, tmtcBridge->mutexTimeoutMs);
store_address_t storeId;
while ((not tmtcBridge->tmFifo->empty()) and
(tmtcBridge->packetSentCounter < tmtcBridge->sentPacketsPerCycle)) {
@ -283,8 +284,8 @@ ReturnValue_t TcpTmTcServer::handleTmSending(socket_t connSocket, bool& tmSent)
#endif
arrayprinter::print(storeAccessor.data(), storeAccessor.size());
}
int retval = send(connSocket, reinterpret_cast<const char*>(storeAccessor.data()),
storeAccessor.size(), tcpConfig.tcpTmFlags);
ssize_t retval = send(connSocket, reinterpret_cast<const char*>(storeAccessor.data()),
storeAccessor.size(), tcpConfig.tcpTmFlags);
if (retval == static_cast<int>(storeAccessor.size())) {
// Packet sent, clear FIFO entry
tmtcBridge->tmFifo->pop();
@ -339,6 +340,9 @@ ReturnValue_t TcpTmTcServer::handleTcRingBufferData(size_t availableReadData) {
size_t foundSize = 0;
size_t readLen = 0;
while (readLen < readAmount) {
if (spacePacketParser == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}
result =
spacePacketParser->parseSpacePackets(bufPtrPtr, readAmount, startIdx, foundSize, readLen);
switch (result) {

View File

@ -17,6 +17,7 @@
#endif
#include <string>
#include <utility>
#include <vector>
class TcpTmTcBridge;
@ -44,7 +45,7 @@ class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableOb
struct TcpConfig {
public:
TcpConfig(std::string tcpPort) : tcpPort(tcpPort) {}
explicit TcpConfig(std::string tcpPort) : tcpPort(std::move(tcpPort)) {}
/**
* Passed to the recv call
@ -84,7 +85,7 @@ class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableOb
size_t ringBufferSize = RING_BUFFER_SIZE,
std::string customTcpServerPort = DEFAULT_SERVER_PORT,
ReceptionModes receptionMode = ReceptionModes::SPACE_PACKETS);
virtual ~TcpTmTcServer();
~TcpTmTcServer() override;
void enableWiretapping(bool enable);
@ -97,10 +98,10 @@ class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableOb
void setSpacePacketParsingOptions(std::vector<uint16_t> validPacketIds);
ReturnValue_t initialize() override;
ReturnValue_t performOperation(uint8_t opCode) override;
[[noreturn]] ReturnValue_t performOperation(uint8_t opCode) override;
ReturnValue_t initializeAfterTaskCreation() override;
std::string getTcpPort() const;
[[nodiscard]] const std::string& getTcpPort() const;
protected:
StorageManagerIF* tcStore = nullptr;
@ -115,7 +116,7 @@ class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableOb
ReceptionModes receptionMode;
TcpConfig tcpConfig;
struct sockaddr tcpAddress;
struct sockaddr tcpAddress = {};
socket_t listenerTcpSocket = 0;
MessageQueueId_t targetTcDestination = MessageQueueIF::NO_QUEUE;

View File

@ -154,7 +154,7 @@ void UdpTcPollingTask::setTimeout(double timeoutSeconds) {
#endif
}
#elif defined(PLATFORM_UNIX)
timeval tval {};
timeval tval{};
tval = timevalOperations::toTimeval(timeoutSeconds);
int result = setsockopt(serverSocket, SOL_SOCKET, SO_RCVTIMEO, &tval, sizeof(receptionTimeout));
if (result == -1) {

View File

@ -20,7 +20,7 @@
const std::string UdpTmTcBridge::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT;
UdpTmTcBridge::UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination,
const std::string& udpServerPort_, object_id_t tmStoreId,
const std::string &udpServerPort_, object_id_t tmStoreId,
object_id_t tcStoreId)
: TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) {
if (udpServerPort_.empty()) {
@ -118,7 +118,7 @@ ReturnValue_t UdpTmTcBridge::sendTm(const uint8_t *data, size_t dataLen) {
#endif
ssize_t bytesSent = sendto(serverSocket, reinterpret_cast<const char *>(data), dataLen, flags,
&clientAddress, clientAddressLen);
&clientAddress, clientAddressLen);
if (bytesSent == SOCKET_ERROR) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "TmTcUdpBridge::sendTm: Send operation failed." << std::endl;

View File

@ -29,8 +29,8 @@ class UdpTmTcBridge : public TmTcBridge, public TcpIpBase {
/* The ports chosen here should not be used by any other process. */
static const std::string DEFAULT_SERVER_PORT;
UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, const std::string& udpServerPort = "",
object_id_t tmStoreId = objects::TM_STORE,
UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination,
const std::string& udpServerPort = "", object_id_t tmStoreId = objects::TM_STORE,
object_id_t tcStoreId = objects::TC_STORE);
~UdpTmTcBridge() override;

View File

@ -1,32 +1,30 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
Clock.cpp
FixedTimeslotTask.cpp
BinarySemaphore.cpp
BinSemaphUsingTask.cpp
CountingSemaphore.cpp
CountingSemaphUsingTask.cpp
MessageQueue.cpp
Mutex.cpp
MutexFactory.cpp
PeriodicTask.cpp
QueueFactory.cpp
SemaphoreFactory.cpp
TaskFactory.cpp
Timekeeper.cpp
TaskManagement.cpp
QueueMapManager.cpp
)
target_sources(
${LIB_FSFW_NAME}
PRIVATE Clock.cpp
FixedTimeslotTask.cpp
BinarySemaphore.cpp
BinSemaphUsingTask.cpp
CountingSemaphore.cpp
CountingSemaphUsingTask.cpp
MessageQueue.cpp
Mutex.cpp
MutexFactory.cpp
PeriodicTask.cpp
QueueFactory.cpp
SemaphoreFactory.cpp
TaskFactory.cpp
Timekeeper.cpp
TaskManagement.cpp
QueueMapManager.cpp)
# FreeRTOS is required to link the FSFW now. It is recommended to compile
# FreeRTOS as a static library and set LIB_OS_NAME to the target name of the
# FreeRTOS is required to link the FSFW now. It is recommended to compile
# FreeRTOS as a static library and set LIB_OS_NAME to the target name of the
# library.
if(NOT LIB_OS_NAME)
message(STATUS
"LIB_OS_NAME is empty. Make sure to include the FreeRTOS header path properly."
)
message(
STATUS
"LIB_OS_NAME is empty. Make sure to include the FreeRTOS header path properly."
)
else()
target_link_libraries(${LIB_FSFW_NAME} PRIVATE
${LIB_OS_NAME}
)
target_link_libraries(${LIB_FSFW_NAME} PRIVATE ${LIB_OS_NAME})
endif()

View File

@ -1,27 +1,23 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
Clock.cpp
FixedTimeslotTask.cpp
MessageQueue.cpp
Mutex.cpp
MutexFactory.cpp
PeriodicTask.cpp
QueueFactory.cpp
QueueMapManager.cpp
SemaphoreFactory.cpp
TaskFactory.cpp
taskHelpers.cpp
)
target_sources(
${LIB_FSFW_NAME}
PRIVATE Clock.cpp
FixedTimeslotTask.cpp
MessageQueue.cpp
Mutex.cpp
MutexFactory.cpp
PeriodicTask.cpp
QueueFactory.cpp
QueueMapManager.cpp
SemaphoreFactory.cpp
TaskFactory.cpp
taskHelpers.cpp)
if(UNIX)
find_package(Threads REQUIRED)
target_link_libraries(${LIB_FSFW_NAME} PRIVATE
${CMAKE_THREAD_LIBS_INIT}
)
target_link_libraries(${LIB_FSFW_NAME} PRIVATE ${CMAKE_THREAD_LIBS_INIT})
if(NOT APPLE)
target_link_libraries(${LIB_FSFW_NAME} PRIVATE
rt
)
target_link_libraries(${LIB_FSFW_NAME} PRIVATE rt)
endif()
endif()
endif()

View File

@ -1,29 +1,25 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
Clock.cpp
BinarySemaphore.cpp
CountingSemaphore.cpp
FixedTimeslotTask.cpp
InternalErrorCodes.cpp
MessageQueue.cpp
Mutex.cpp
MutexFactory.cpp
PeriodicPosixTask.cpp
PosixThread.cpp
QueueFactory.cpp
SemaphoreFactory.cpp
TaskFactory.cpp
tcpipHelpers.cpp
unixUtility.cpp
)
target_sources(
${LIB_FSFW_NAME}
PRIVATE Clock.cpp
BinarySemaphore.cpp
CountingSemaphore.cpp
FixedTimeslotTask.cpp
InternalErrorCodes.cpp
MessageQueue.cpp
Mutex.cpp
MutexFactory.cpp
PeriodicPosixTask.cpp
PosixThread.cpp
QueueFactory.cpp
SemaphoreFactory.cpp
TaskFactory.cpp
tcpipHelpers.cpp
unixUtility.cpp)
find_package(Threads REQUIRED)
target_link_libraries(${LIB_FSFW_NAME} PUBLIC
${CMAKE_THREAD_LIBS_INIT}
)
target_link_libraries(${LIB_FSFW_NAME} PUBLIC ${CMAKE_THREAD_LIBS_INIT})
if(NOT APPLE)
target_link_libraries(${LIB_FSFW_NAME} PUBLIC
rt
)
target_link_libraries(${LIB_FSFW_NAME} PUBLIC rt)
endif()

View File

@ -1,20 +1,17 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
Clock.cpp
CpuUsage.cpp
InitTask.cpp
InternalErrorCodes.cpp
MessageQueue.cpp
PeriodicTask.cpp
Mutex.cpp
MutexFactory.cpp
FixedTimeslotTask.cpp
QueueFactory.cpp
RtemsBasic.cpp
RTEMSTaskBase.cpp
TaskFactory.cpp
BinarySemaphore.cpp
SemaphoreFactory.cpp
)
target_sources(
${LIB_FSFW_NAME}
PRIVATE Clock.cpp
CpuUsage.cpp
InitTask.cpp
InternalErrorCodes.cpp
MessageQueue.cpp
PeriodicTask.cpp
Mutex.cpp
MutexFactory.cpp
FixedTimeslotTask.cpp
QueueFactory.cpp
RtemsBasic.cpp
RTEMSTaskBase.cpp
TaskFactory.cpp
BinarySemaphore.cpp
SemaphoreFactory.cpp)

View File

@ -1,4 +1 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
tcpipHelpers.cpp
winTaskHelpers.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE tcpipHelpers.cpp winTaskHelpers.cpp)

View File

@ -1,6 +1,3 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
ParameterHelper.cpp
ParameterMessage.cpp
ParameterWrapper.cpp
)
target_sources(
${LIB_FSFW_NAME} PRIVATE ParameterHelper.cpp ParameterMessage.cpp
ParameterWrapper.cpp)

View File

@ -1,7 +1,4 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
Fuse.cpp
PowerComponent.cpp
PowerSensor.cpp
PowerSwitcher.cpp
)
target_sources(
${LIB_FSFW_NAME}
PRIVATE Fuse.cpp PowerComponent.cpp PowerSensor.cpp PowerSwitcher.cpp
DummyPowerSwitcher.cpp PowerSwitcherComponent.cpp)

View File

@ -0,0 +1,47 @@
#include "DummyPowerSwitcher.h"
DummyPowerSwitcher::DummyPowerSwitcher(object_id_t objectId, size_t numberOfSwitches,
size_t numberOfFuses, bool registerGlobally,
uint32_t switchDelayMs)
: SystemObject(objectId, registerGlobally),
switcherList(numberOfSwitches),
fuseList(numberOfFuses),
switchDelayMs(switchDelayMs) {}
void DummyPowerSwitcher::setInitialSwitcherList(std::vector<ReturnValue_t> switcherList) {
this->switcherList = switcherList;
}
void DummyPowerSwitcher::setInitialFusesList(std::vector<ReturnValue_t> fuseList) {
this->fuseList = fuseList;
}
ReturnValue_t DummyPowerSwitcher::sendSwitchCommand(power::Switch_t switchNr, ReturnValue_t onOff) {
if (switchNr < switcherList.size()) {
switcherList[switchNr] = onOff;
}
return RETURN_FAILED;
}
ReturnValue_t DummyPowerSwitcher::sendFuseOnCommand(uint8_t fuseNr) {
if (fuseNr < fuseList.size()) {
fuseList[fuseNr] = FUSE_ON;
}
return RETURN_FAILED;
}
ReturnValue_t DummyPowerSwitcher::getSwitchState(power::Switch_t switchNr) const {
if (switchNr < switcherList.size()) {
return switcherList[switchNr];
}
return HasReturnvaluesIF::RETURN_FAILED;
}
ReturnValue_t DummyPowerSwitcher::getFuseState(uint8_t fuseNr) const {
if (fuseNr < fuseList.size()) {
return fuseList[fuseNr];
}
return HasReturnvaluesIF::RETURN_FAILED;
}
uint32_t DummyPowerSwitcher::getSwitchDelayMs(void) const { return switchDelayMs; }

View File

@ -0,0 +1,38 @@
#ifndef FSFW_SRC_FSFW_POWER_DUMMYPOWERSWITCHER_H_
#define FSFW_SRC_FSFW_POWER_DUMMYPOWERSWITCHER_H_
#include <cstddef>
#include <vector>
#include "PowerSwitchIF.h"
#include "definitions.h"
#include "fsfw/objectmanager/SystemObject.h"
/**
* @brief This component can be used to simulate a power switcher like a
* Power Control Distribution Unit (PCDU)
* @details
* The dummy switcher will simply cache the commanded fuse and switch states and return them
* in the according switch getter functions. In that sense, it simulates an ideal PCDU.
*/
class DummyPowerSwitcher : public SystemObject, public PowerSwitchIF {
public:
DummyPowerSwitcher(object_id_t objectId, size_t numberOfSwitches, size_t numberOfFuses,
bool registerGlobally = true, uint32_t switchDelayMs = 5000);
void setInitialSwitcherList(std::vector<ReturnValue_t> switcherList);
void setInitialFusesList(std::vector<ReturnValue_t> switcherList);
virtual ReturnValue_t sendSwitchCommand(power::Switch_t switchNr, ReturnValue_t onOff) override;
virtual ReturnValue_t sendFuseOnCommand(uint8_t fuseNr) override;
virtual ReturnValue_t getSwitchState(power::Switch_t switchNr) const override;
virtual ReturnValue_t getFuseState(uint8_t fuseNr) const override;
virtual uint32_t getSwitchDelayMs(void) const override;
private:
std::vector<ReturnValue_t> switcherList;
std::vector<ReturnValue_t> fuseList;
uint32_t switchDelayMs = 5000;
};
#endif /* FSFW_SRC_FSFW_POWER_DUMMYPOWERSWITCHER_H_ */

View File

@ -34,14 +34,14 @@ class Fuse : public SystemObject,
};
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PCDU_1;
static const Event FUSE_CURRENT_HIGH = MAKE_EVENT(
1, severity::LOW); //!< PSS detected that current on a fuse is totally out of bounds.
static const Event FUSE_WENT_OFF =
MAKE_EVENT(2, severity::LOW); //!< PSS detected a fuse that went off.
static const Event POWER_ABOVE_HIGH_LIMIT =
MAKE_EVENT(4, severity::LOW); //!< PSS detected a fuse that violates its limits.
static const Event POWER_BELOW_LOW_LIMIT =
MAKE_EVENT(5, severity::LOW); //!< PSS detected a fuse that violates its limits.
//! PSS detected that current on a fuse is totally out of bounds.
static const Event FUSE_CURRENT_HIGH = MAKE_EVENT(1, severity::LOW);
//! PSS detected a fuse that went off.
static const Event FUSE_WENT_OFF = MAKE_EVENT(2, severity::LOW);
//! PSS detected a fuse that violates its limits.
static const Event POWER_ABOVE_HIGH_LIMIT = MAKE_EVENT(4, severity::LOW);
//! PSS detected a fuse that violates its limits.
static const Event POWER_BELOW_LOW_LIMIT = MAKE_EVENT(5, severity::LOW);
typedef std::list<PowerComponentIF *> DeviceList;
Fuse(object_id_t fuseObjectId, uint8_t fuseId, sid_t variableSet, VariableIds ids,

View File

@ -3,6 +3,7 @@
#include "../events/Event.h"
#include "../returnvalues/HasReturnvaluesIF.h"
#include "definitions.h"
/**
*
* @brief This interface defines a connection to a device that is capable of
@ -37,11 +38,11 @@ class PowerSwitchIF : public HasReturnvaluesIF {
* @param switchNr
* @param onOff on == @c SWITCH_ON; off != @c SWITCH_ON
*/
virtual void sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) const = 0;
virtual ReturnValue_t sendSwitchCommand(power::Switch_t switchNr, ReturnValue_t onOff) = 0;
/**
* Sends a command to the Power Unit to enable a certain fuse.
*/
virtual void sendFuseOnCommand(uint8_t fuseNr) const = 0;
virtual ReturnValue_t sendFuseOnCommand(uint8_t fuseNr) = 0;
/**
* get the state of the Switches.
@ -51,7 +52,7 @@ class PowerSwitchIF : public HasReturnvaluesIF {
* - @c SWITCH_OFF if the specified switch is off.
* - @c RETURN_FAILED if an error occured
*/
virtual ReturnValue_t getSwitchState(uint8_t switchNr) const = 0;
virtual ReturnValue_t getSwitchState(power::Switch_t switchNr) const = 0;
/**
* get state of a fuse.
* @param fuseNr

View File

@ -1,19 +1,12 @@
#include "fsfw/power/PowerSwitcher.h"
#include "definitions.h"
#include "fsfw/objectmanager/ObjectManager.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
PowerSwitcher::PowerSwitcher(uint8_t setSwitch1, uint8_t setSwitch2,
PowerSwitcher::State_t setStartState)
: state(setStartState), firstSwitch(setSwitch1), secondSwitch(setSwitch2) {}
ReturnValue_t PowerSwitcher::initialize(object_id_t powerSwitchId) {
power = ObjectManager::instance()->get<PowerSwitchIF>(powerSwitchId);
if (power == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_OK;
}
PowerSwitcher::PowerSwitcher(PowerSwitchIF* switcher, power::Switch_t setSwitch1,
power::Switch_t setSwitch2, PowerSwitcher::State_t setStartState)
: power(switcher), state(setStartState), firstSwitch(setSwitch1), secondSwitch(setSwitch2) {}
ReturnValue_t PowerSwitcher::getStateOfSwitches() {
SwitchReturn_t result = howManySwitches();
@ -52,18 +45,37 @@ void PowerSwitcher::commandSwitches(ReturnValue_t onOff) {
return;
}
void PowerSwitcher::turnOn() {
void PowerSwitcher::turnOn(bool checkCurrentState) {
if (checkCurrentState) {
if (getStateOfSwitches() == PowerSwitchIF::SWITCH_ON) {
state = SWITCH_IS_ON;
return;
}
}
commandSwitches(PowerSwitchIF::SWITCH_ON);
state = WAIT_ON;
}
void PowerSwitcher::turnOff() {
void PowerSwitcher::turnOff(bool checkCurrentState) {
if (checkCurrentState) {
if (getStateOfSwitches() == PowerSwitchIF::SWITCH_OFF) {
state = SWITCH_IS_OFF;
return;
}
}
commandSwitches(PowerSwitchIF::SWITCH_OFF);
state = WAIT_OFF;
}
bool PowerSwitcher::active() {
if (state == WAIT_OFF or state == WAIT_ON) {
return true;
}
return false;
}
PowerSwitcher::SwitchReturn_t PowerSwitcher::howManySwitches() {
if (secondSwitch == NO_SWITCH) {
if (secondSwitch == power::NO_SWITCH) {
return ONE_SWITCH;
} else {
return TWO_SWITCHES;

View File

@ -14,28 +14,29 @@ class PowerSwitcher : public HasReturnvaluesIF {
SWITCH_IS_OFF,
SWITCH_IS_ON,
};
State_t state;
static const uint8_t INTERFACE_ID = CLASS_ID::POWER_SWITCHER;
static const ReturnValue_t IN_POWER_TRANSITION = MAKE_RETURN_CODE(1);
static const ReturnValue_t SWITCH_STATE_MISMATCH = MAKE_RETURN_CODE(2);
PowerSwitcher(uint8_t setSwitch1, uint8_t setSwitch2 = NO_SWITCH,
PowerSwitcher(PowerSwitchIF* switcher, power::Switch_t setSwitch1,
power::Switch_t setSwitch2 = power::NO_SWITCH,
State_t setStartState = SWITCH_IS_OFF);
ReturnValue_t initialize(object_id_t powerSwitchId);
void turnOn();
void turnOff();
void turnOn(bool checkCurrentState = true);
void turnOff(bool checkCurrentState = true);
bool active();
void doStateMachine();
State_t getState();
ReturnValue_t checkSwitchState();
uint32_t getSwitchDelay();
uint8_t getFirstSwitch() const;
uint8_t getSecondSwitch() const;
power::Switch_t getFirstSwitch() const;
power::Switch_t getSecondSwitch() const;
private:
uint8_t firstSwitch;
uint8_t secondSwitch;
PowerSwitchIF* power = nullptr;
State_t state;
power::Switch_t firstSwitch = power::NO_SWITCH;
power::Switch_t secondSwitch = power::NO_SWITCH;
static const uint8_t NO_SWITCH = 0xFF;
enum SwitchReturn_t { ONE_SWITCH = 1, TWO_SWITCHES = 2 };
ReturnValue_t getStateOfSwitches();
void commandSwitches(ReturnValue_t onOff);

View File

@ -0,0 +1,107 @@
#include "PowerSwitcherComponent.h"
#include <fsfw/ipc/QueueFactory.h>
#include <fsfw/power/PowerSwitchIF.h>
PowerSwitcherComponent::PowerSwitcherComponent(object_id_t objectId, PowerSwitchIF *pwrSwitcher,
power::Switch_t pwrSwitch)
: SystemObject(objectId),
switcher(pwrSwitcher, pwrSwitch),
modeHelper(this),
healthHelper(this, objectId) {
queue = QueueFactory::instance()->createMessageQueue();
}
ReturnValue_t PowerSwitcherComponent::performOperation(uint8_t opCode) {
ReturnValue_t result;
CommandMessage command;
for (result = queue->receiveMessage(&command); result == RETURN_OK;
result = queue->receiveMessage(&command)) {
result = healthHelper.handleHealthCommand(&command);
if (result == RETURN_OK) {
continue;
}
result = modeHelper.handleModeCommand(&command);
if (result == RETURN_OK) {
continue;
}
}
if (switcher.active()) {
switcher.doStateMachine();
auto currState = switcher.getState();
if (currState == PowerSwitcher::SWITCH_IS_OFF) {
setMode(MODE_OFF, 0);
} else if (currState == PowerSwitcher::SWITCH_IS_ON) {
setMode(MODE_ON, 0);
}
}
return RETURN_OK;
}
ReturnValue_t PowerSwitcherComponent::initialize() {
ReturnValue_t result = modeHelper.initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = healthHelper.initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return SystemObject::initialize();
}
MessageQueueId_t PowerSwitcherComponent::getCommandQueue() const { return queue->getId(); }
void PowerSwitcherComponent::getMode(Mode_t *mode, Submode_t *submode) {
*mode = this->mode;
*submode = this->submode;
}
ReturnValue_t PowerSwitcherComponent::setHealth(HealthState health) {
healthHelper.setHealth(health);
return RETURN_OK;
}
ReturnValue_t PowerSwitcherComponent::checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode) {
*msToReachTheMode = 5000;
if (mode != MODE_ON and mode != MODE_OFF) {
return TRANS_NOT_ALLOWED;
}
return RETURN_OK;
}
void PowerSwitcherComponent::startTransition(Mode_t mode, Submode_t submode) {
if (mode == MODE_OFF) {
switcher.turnOff(true);
switcher.doStateMachine();
if (switcher.getState() == PowerSwitcher::SWITCH_IS_OFF) {
setMode(MODE_OFF, 0);
}
} else if (mode == MODE_ON) {
switcher.turnOn(true);
switcher.doStateMachine();
if (switcher.getState() == PowerSwitcher::SWITCH_IS_ON) {
setMode(MODE_ON, 0);
}
}
}
void PowerSwitcherComponent::setToExternalControl() {
healthHelper.setHealth(HasHealthIF::EXTERNAL_CONTROL);
}
void PowerSwitcherComponent::announceMode(bool recursive) {
triggerEvent(MODE_INFO, mode, submode);
}
void PowerSwitcherComponent::setMode(Mode_t newMode, Submode_t newSubmode) {
this->mode = newMode;
this->submode = newSubmode;
modeHelper.modeChanged(mode, submode);
announceMode(false);
}
HasHealthIF::HealthState PowerSwitcherComponent::getHealth() { return healthHelper.getHealth(); }

View File

@ -0,0 +1,62 @@
#ifndef _FSFW_POWER_POWERSWITCHERCOMPONENT_H_
#define _FSFW_POWER_POWERSWITCHERCOMPONENT_H_
#include <fsfw/health/HasHealthIF.h>
#include <fsfw/health/HealthHelper.h>
#include <fsfw/modes/HasModesIF.h>
#include <fsfw/modes/ModeHelper.h>
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/power/PowerSwitcher.h>
#include <fsfw/power/definitions.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
class PowerSwitchIF;
/**
* @brief Allows to create an power switch object with its own mode and health
* @details
* This basic component allows to create an object which is solely responsible for managing a
* switch. It also has a mode and a health by implementing the respective interface components
* which allows integrating this component into a system mode tree.
*
* Commanding this component to MODE_OFF will cause the switcher to turn the switch off while
* commanding in to MODE_ON will cause the switcher to turn the switch on.
*/
class PowerSwitcherComponent : public SystemObject,
public HasReturnvaluesIF,
public ExecutableObjectIF,
public HasModesIF,
public HasHealthIF {
public:
PowerSwitcherComponent(object_id_t objectId, PowerSwitchIF *pwrSwitcher,
power::Switch_t pwrSwitch);
private:
MessageQueueIF *queue = nullptr;
PowerSwitcher switcher;
Mode_t mode = MODE_OFF;
Submode_t submode = 0;
ModeHelper modeHelper;
HealthHelper healthHelper;
void setMode(Mode_t newMode, Submode_t newSubmode);
virtual ReturnValue_t performOperation(uint8_t opCode) override;
ReturnValue_t initialize() override;
MessageQueueId_t getCommandQueue() const override;
void getMode(Mode_t *mode, Submode_t *submode) override;
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode) override;
void startTransition(Mode_t mode, Submode_t submode) override;
void setToExternalControl() override;
void announceMode(bool recursive) override;
ReturnValue_t setHealth(HealthState health) override;
HasHealthIF::HealthState getHealth() override;
};
#endif /* _FSFW_POWER_POWERSWITCHERCOMPONENT_H_ */

View File

@ -0,0 +1,13 @@
#ifndef FSFW_SRC_FSFW_POWER_DEFINITIONS_H_
#define FSFW_SRC_FSFW_POWER_DEFINITIONS_H_
#include <cstdint>
namespace power {
using Switch_t = uint8_t;
static constexpr Switch_t NO_SWITCH = 0xFF;
} // namespace power
#endif /* FSFW_SRC_FSFW_POWER_DEFINITIONS_H_ */

View File

@ -1,12 +1,12 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
Service1TelecommandVerification.cpp
Service2DeviceAccess.cpp
Service3Housekeeping.cpp
Service5EventReporting.cpp
Service8FunctionManagement.cpp
Service9TimeManagement.cpp
Service17Test.cpp
Service20ParameterManagement.cpp
CService200ModeCommanding.cpp
CService201HealthCommanding.cpp
)
target_sources(
${LIB_FSFW_NAME}
PRIVATE Service1TelecommandVerification.cpp
Service2DeviceAccess.cpp
Service3Housekeeping.cpp
Service5EventReporting.cpp
Service8FunctionManagement.cpp
Service9TimeManagement.cpp
Service17Test.cpp
Service20ParameterManagement.cpp
CService200ModeCommanding.cpp
CService201HealthCommanding.cpp)

View File

@ -13,8 +13,6 @@ CService201HealthCommanding::CService201HealthCommanding(object_id_t objectId, u
: CommandingServiceBase(objectId, apid, serviceId, numParallelCommands, commandTimeoutSeconds) {
}
CService201HealthCommanding::~CService201HealthCommanding() {}
ReturnValue_t CService201HealthCommanding::isValidSubservice(uint8_t subservice) {
switch (subservice) {
case (Subservice::COMMAND_SET_HEALTH):
@ -43,8 +41,8 @@ ReturnValue_t CService201HealthCommanding::getMessageQueueAndObject(uint8_t subs
}
ReturnValue_t CService201HealthCommanding::checkInterfaceAndAcquireMessageQueue(
MessageQueueId_t *messageQueueToSet, object_id_t *objectId) {
HasHealthIF *destination = ObjectManager::instance()->get<HasHealthIF>(*objectId);
MessageQueueId_t *messageQueueToSet, const object_id_t *objectId) {
auto *destination = ObjectManager::instance()->get<HasHealthIF>(*objectId);
if (destination == nullptr) {
return CommandingServiceBase::INVALID_OBJECT;
}
@ -77,6 +75,10 @@ ReturnValue_t CService201HealthCommanding::prepareCommand(CommandMessage *messag
HealthMessage::setHealthMessage(message, HealthMessage::HEALTH_ANNOUNCE_ALL);
break;
}
default: {
// Should never happen, subservice was already checked
result = RETURN_FAILED;
}
}
return result;
}
@ -95,10 +97,10 @@ ReturnValue_t CService201HealthCommanding::handleReply(const CommandMessage *rep
}
// Not used for now, health state already reported by event
ReturnValue_t CService201HealthCommanding::prepareHealthSetReply(const CommandMessage *reply) {
prepareHealthSetReply(reply);
uint8_t health = static_cast<uint8_t>(HealthMessage::getHealth(reply));
uint8_t oldHealth = static_cast<uint8_t>(HealthMessage::getOldHealth(reply));
[[maybe_unused]] ReturnValue_t CService201HealthCommanding::prepareHealthSetReply(
const CommandMessage *reply) {
auto health = static_cast<uint8_t>(HealthMessage::getHealth(reply));
auto oldHealth = static_cast<uint8_t>(HealthMessage::getOldHealth(reply));
HealthSetReply healthSetReply(health, oldHealth);
return sendTmPacket(Subservice::REPLY_HEALTH_SET, &healthSetReply);
}

View File

@ -1,7 +1,7 @@
#ifndef FSFW_PUS_CSERVICE201HEALTHCOMMANDING_H_
#define FSFW_PUS_CSERVICE201HEALTHCOMMANDING_H_
#include "../tmtcservices/CommandingServiceBase.h"
#include "fsfw/tmtcservices/CommandingServiceBase.h"
/**
* @brief Custom PUS service to set health of all objects
@ -21,7 +21,7 @@ class CService201HealthCommanding : public CommandingServiceBase {
public:
CService201HealthCommanding(object_id_t objectId, uint16_t apid, uint8_t serviceId,
uint8_t numParallelCommands = 4, uint16_t commandTimeoutSeconds = 60);
virtual ~CService201HealthCommanding();
~CService201HealthCommanding() override = default;
protected:
/* CSB abstract function implementations */
@ -38,12 +38,10 @@ class CService201HealthCommanding : public CommandingServiceBase {
bool *isStep) override;
private:
ReturnValue_t checkAndAcquireTargetID(object_id_t *objectIdToSet, const uint8_t *tcData,
size_t tcDataLen);
ReturnValue_t checkInterfaceAndAcquireMessageQueue(MessageQueueId_t *MessageQueueToSet,
object_id_t *objectId);
static ReturnValue_t checkInterfaceAndAcquireMessageQueue(MessageQueueId_t *MessageQueueToSet,
const object_id_t *objectId);
ReturnValue_t prepareHealthSetReply(const CommandMessage *reply);
[[maybe_unused]] ReturnValue_t prepareHealthSetReply(const CommandMessage *reply);
enum Subservice {
//! [EXPORT] : [TC] Set health of target object

View File

@ -0,0 +1,203 @@
#ifndef MISSION_PUS_SERVICE11TELECOMMANDSCHEDULING_H_
#define MISSION_PUS_SERVICE11TELECOMMANDSCHEDULING_H_
#include <etl/multimap.h>
#include <fsfw/tmtcservices/PusServiceBase.h>
#include <fsfw/tmtcservices/TmTcMessage.h>
#include "fsfw/FSFW.h"
#include "fsfw/returnvalues/FwClassIds.h"
/**
* @brief: PUS-Service 11 - Telecommand scheduling.
* @details:
* PUS-Service 11 - Telecommand scheduling.
* Full documentation: ECSS-E-ST-70-41C, p. 168:
* ST[11] time-based scheduling
*
* This service provides the capability to command pre-loaded
* application processes (telecommands) by releasing them at their
* due-time.
* References to telecommands are stored together with their due-timepoints
* and are released at their corresponding due-time.
*
* Necessary subservice functionalities are implemented.
* Those are:
* TC[11,4] activity insertion
* TC[11,5] activity deletion
* TC[11,6] filter-based activity deletion
* TC[11,7] activity time-shift
* TC[11,8] filter-based activity time-shift
*
* Groups are not supported.
* This service remains always enabled. Sending a disable-request has no effect.
*/
template <size_t MAX_NUM_TCS>
class Service11TelecommandScheduling final : public PusServiceBase {
public:
static constexpr uint8_t CLASS_ID = CLASS_ID::PUS_SERVICE_11;
static constexpr ReturnValue_t INVALID_TYPE_TIME_WINDOW =
HasReturnvaluesIF::makeReturnCode(CLASS_ID, 1);
static constexpr ReturnValue_t TIMESHIFTING_NOT_POSSIBLE =
HasReturnvaluesIF::makeReturnCode(CLASS_ID, 2);
static constexpr ReturnValue_t INVALID_RELATIVE_TIME =
HasReturnvaluesIF::makeReturnCode(CLASS_ID, 3);
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_11;
//! [EXPORT] : [COMMENT] Deletion of a TC from the map failed.
//! P1: First 32 bit of request ID, P2. Last 32 bit of Request ID
static constexpr Event TC_DELETION_FAILED = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);
// The types of PUS-11 subservices
enum Subservice : uint8_t {
ENABLE_SCHEDULING = 1,
DISABLE_SCHEDULING = 2,
RESET_SCHEDULING = 3,
INSERT_ACTIVITY = 4,
DELETE_ACTIVITY = 5,
FILTER_DELETE_ACTIVITY = 6,
TIMESHIFT_ACTIVITY = 7,
FILTER_TIMESHIFT_ACTIVITY = 8,
DETAIL_REPORT = 9,
TIMEBASE_SCHEDULE_DETAIL_REPORT = 10,
TIMESHIFT_ALL_SCHEDULE_ACTIVITIES = 15
};
// The types of time windows for TC[11,6] and TC[11,8], as defined in ECSS-E-ST-70-41C,
// requirement 8.11.3c (p. 507)
enum TypeOfTimeWindow : uint32_t {
SELECT_ALL = 0,
FROM_TIMETAG_TO_TIMETAG = 1,
FROM_TIMETAG = 2,
TO_TIMETAG = 3
};
Service11TelecommandScheduling(object_id_t objectId, uint16_t apid, uint8_t serviceId,
AcceptsTelecommandsIF* tcRecipient,
uint16_t releaseTimeMarginSeconds = DEFAULT_RELEASE_TIME_MARGIN,
bool debugMode = false);
~Service11TelecommandScheduling() override;
void enableExpiredTcDeletion();
void disableExpiredTcDeletion();
/** PusServiceBase overrides */
ReturnValue_t handleRequest(uint8_t subservice) override;
ReturnValue_t performService() override;
ReturnValue_t initialize() override;
private:
struct TelecommandStruct {
uint64_t requestId{};
uint32_t seconds{};
store_address_t storeAddr; // uint16
};
static constexpr uint16_t DEFAULT_RELEASE_TIME_MARGIN = 5;
// minimum release time offset to insert into schedule
const uint16_t RELEASE_TIME_MARGIN_SECONDS = 5;
/**
* By default, the scheduling will be disabled. This is a standard requirement
*/
bool schedulingEnabled = false;
bool deleteExpiredTcWhenDisabled = true;
bool debugMode = false;
StorageManagerIF* tcStore = nullptr;
AcceptsTelecommandsIF* tcRecipient = nullptr;
MessageQueueId_t recipientMsgQueueId = 0;
/**
* The telecommand map uses the exectution time as a Unix time stamp as
* the key. This is mapped to a generic telecommand struct.
*/
using TelecommandMap = etl::multimap<uint32_t, TelecommandStruct, MAX_NUM_TCS>;
using TcMapIter = typename TelecommandMap::iterator;
TelecommandMap telecommandMap;
ReturnValue_t handleResetCommand();
/**
* @brief Logic to be performed on an incoming TC[11,4].
* @return RETURN_OK if successful
*/
ReturnValue_t doInsertActivity(const uint8_t* data, size_t size);
/**
* @brief Logic to be performed on an incoming TC[11,5].
* @return RETURN_OK if successful
*/
ReturnValue_t doDeleteActivity(const uint8_t* data, size_t size);
/**
* @brief Logic to be performed on an incoming TC[11,6].
* @return RETURN_OK if successful
*/
ReturnValue_t doFilterDeleteActivity(const uint8_t* data, size_t size);
/**
* @brief Logic to be performed on an incoming TC[11,7].
* @return RETURN_OK if successful
*/
ReturnValue_t doTimeshiftActivity(const uint8_t* data, size_t size);
/**
* @brief Logic to be performed on an incoming TC[11,8].
* @return RETURN_OK if successful
*/
ReturnValue_t doFilterTimeshiftActivity(const uint8_t* data, size_t size);
/**
* @brief Extracts the Request ID from the Application Data of a TC by utilizing a ctor of the
* class TcPacketPus.
* NOTE: This only works if the payload data is a TC (e.g. not for TC[11,5] which does not
* send a TC as payload)!
* @param data The Application data of the TC (get via getApplicationData()).
* @return requestId
*/
uint64_t getRequestIdFromDataTC(const uint8_t* data) const;
/**
* @brief Extracts the Request ID from the Application Data directly, assuming it is packed
* as follows (acc. to ECSS): | source ID (uint32) | apid (uint32) | ssc (uint32) |.
* @param data Pointer to first byte described data
* @param dataSize Remaining size of data NOTE: non-const, this is modified by the function
* @param [out] requestId Request ID
* @return RETURN_OK if successful
*/
ReturnValue_t getRequestIdFromData(const uint8_t*& data, size_t& dataSize, uint64_t& requestId);
/**
* @brief Builds the Request ID from its three elements.
* @param sourceId Source ID
* @param apid Application Process ID (APID)
* @param ssc Source Sequence Count
* @return Request ID
*/
[[nodiscard]] uint64_t buildRequestId(uint32_t sourceId, uint16_t apid, uint16_t ssc) const;
/**
* @brief Gets the filter range for filter TCs from a data packet
* @param data TC data
* @param dataSize TC data size
* @param [out] itBegin Begin of filter range
* @param [out] itEnd End of filter range
* @return RETURN_OK if successful
*/
ReturnValue_t getMapFilterFromData(const uint8_t*& data, size_t& size, TcMapIter& itBegin,
TcMapIter& itEnd);
ReturnValue_t handleInvalidData(const char* ctx);
/**
* @brief Prints content of multimap. Use for simple debugging only.
*/
void debugPrintMultimapContent() const;
};
#include "Service11TelecommandScheduling.tpp"
#endif /* MISSION_PUS_SERVICE11TELECOMMANDSCHEDULING_H_ */

View File

@ -0,0 +1,645 @@
#pragma once
#include <cstddef>
#include "fsfw/objectmanager/ObjectManager.h"
#include "fsfw/serialize/SerializeAdapter.h"
#include "fsfw/serviceinterface.h"
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
static constexpr auto DEF_END = SerializeIF::Endianness::BIG;
template <size_t MAX_NUM_TCS>
inline Service11TelecommandScheduling<MAX_NUM_TCS>::Service11TelecommandScheduling(
object_id_t objectId, uint16_t apid, uint8_t serviceId, AcceptsTelecommandsIF *tcRecipient,
uint16_t releaseTimeMarginSeconds, bool debugMode)
: PusServiceBase(objectId, apid, serviceId),
RELEASE_TIME_MARGIN_SECONDS(releaseTimeMarginSeconds),
debugMode(debugMode),
tcRecipient(tcRecipient) {}
template <size_t MAX_NUM_TCS>
inline Service11TelecommandScheduling<MAX_NUM_TCS>::~Service11TelecommandScheduling() = default;
template <size_t MAX_NUM_TCS>
inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::handleRequest(
uint8_t subservice) {
if (debugMode) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::info << "PUS11::handleRequest: Handling request " << static_cast<int>(subservice);
#else
sif::printInfo("PUS11::handleRequest: Handling request %d\n", subservice);
#endif
}
// Get de-serialized Timestamp
const uint8_t *data = currentPacket.getApplicationData();
size_t size = currentPacket.getApplicationDataSize();
if (data == nullptr) {
return handleInvalidData("handleRequest");
}
switch (subservice) {
case Subservice::ENABLE_SCHEDULING: {
schedulingEnabled = true;
break;
}
case Subservice::DISABLE_SCHEDULING: {
schedulingEnabled = false;
break;
}
case Subservice::RESET_SCHEDULING: {
return handleResetCommand();
}
case Subservice::INSERT_ACTIVITY:
return doInsertActivity(data, size);
case Subservice::DELETE_ACTIVITY:
return doDeleteActivity(data, size);
case Subservice::FILTER_DELETE_ACTIVITY:
return doFilterDeleteActivity(data, size);
case Subservice::TIMESHIFT_ACTIVITY:
return doTimeshiftActivity(data, size);
case Subservice::FILTER_TIMESHIFT_ACTIVITY:
return doFilterTimeshiftActivity(data, size);
default:
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
}
return RETURN_OK;
}
template <size_t MAX_NUM_TCS>
inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::performService() {
if (not schedulingEnabled) {
return RETURN_OK;
}
// get current time as UNIX timestamp
timeval tNow = {};
Clock::getClock_timeval(&tNow);
// TODO: Optionally limit the max number of released TCs per cycle?
// NOTE: The iterator is increased in the loop here. Increasing the iterator as for-loop arg
// does not work in this case as we are deleting the current element here.
for (auto it = telecommandMap.begin(); it != telecommandMap.end();) {
if (it->first <= tNow.tv_sec) {
if (schedulingEnabled) {
// release tc
TmTcMessage releaseMsg(it->second.storeAddr);
auto sendRet = this->requestQueue->sendMessage(recipientMsgQueueId, &releaseMsg, false);
if (sendRet != HasReturnvaluesIF::RETURN_OK) {
return sendRet;
}
if (debugMode) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::info << "Released TC & erased it from TC map" << std::endl;
#else
sif::printInfo("Released TC & erased it from TC map\n");
#endif
}
telecommandMap.erase(it++);
} else if (deleteExpiredTcWhenDisabled) {
telecommandMap.erase(it++);
}
continue;
}
it++;
}
return HasReturnvaluesIF::RETURN_OK;
}
template <size_t MAX_NUM_TCS>
inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::initialize() {
ReturnValue_t res = PusServiceBase::initialize();
if (res != HasReturnvaluesIF::RETURN_OK) {
return res;
}
tcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::TC_STORE);
if (!tcStore) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
if (tcRecipient == nullptr) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
recipientMsgQueueId = tcRecipient->getRequestQueue();
return res;
}
template <size_t MAX_NUM_TCS>
inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::handleResetCommand() {
for (auto it = telecommandMap.begin(); it != telecommandMap.end(); it++) {
ReturnValue_t result = tcStore->deleteData(it->second.storeAddr);
if (result != RETURN_OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
// This should not happen
sif::warning << "Service11TelecommandScheduling::handleRequestDeleting: Deletion failed"
<< std::endl;
#else
sif::printWarning("Service11TelecommandScheduling::handleRequestDeleting: Deletion failed\n");
#endif
triggerEvent(TC_DELETION_FAILED, (it->second.requestId >> 32) & 0xffffffff,
it->second.requestId & 0xffffffff);
}
}
telecommandMap.clear();
return RETURN_OK;
}
template <size_t MAX_NUM_TCS>
inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::doInsertActivity(
const uint8_t *data, size_t size) {
uint32_t timestamp = 0;
ReturnValue_t result = SerializeAdapter::deSerialize(&timestamp, &data, &size, DEF_END);
if (result != RETURN_OK) {
return result;
}
// Insert possible if sched. time is above margin
// (See requirement for Time margin)
timeval tNow = {};
Clock::getClock_timeval(&tNow);
if (timestamp - tNow.tv_sec <= RELEASE_TIME_MARGIN_SECONDS) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "Service11TelecommandScheduling::doInsertActivity: Release time too close to "
"current time"
<< std::endl;
#else
sif::printWarning(
"Service11TelecommandScheduling::doInsertActivity: Release time too close to current "
"time\n");
#endif
return RETURN_FAILED;
}
// store currentPacket and receive the store address
store_address_t addr{};
if (tcStore->addData(&addr, data, size) != RETURN_OK ||
addr.raw == storeId::INVALID_STORE_ADDRESS) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Service11TelecommandScheduling::doInsertActivity: Adding data to TC Store failed"
<< std::endl;
#else
sif::printError(
"Service11TelecommandScheduling::doInsertActivity: Adding data to TC Store failed\n");
#endif
return RETURN_FAILED;
}
// insert into multimap with new store address
TelecommandStruct tc;
tc.seconds = timestamp;
tc.storeAddr = addr;
tc.requestId =
getRequestIdFromDataTC(data); // TODO: Missing sanity check of the returned request id
auto it = telecommandMap.insert(std::pair<uint32_t, TelecommandStruct>(timestamp, tc));
if (it == telecommandMap.end()) {
return RETURN_FAILED;
}
if (debugMode) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::info << "PUS11::doInsertActivity: Inserted into Multimap:" << std::endl;
#else
sif::printInfo("PUS11::doInsertActivity: Inserted into Multimap:\n");
#endif
debugPrintMultimapContent();
}
return HasReturnvaluesIF::RETURN_OK;
}
template <size_t MAX_NUM_TCS>
inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::doDeleteActivity(
const uint8_t *data, size_t size) {
// Get request ID
uint64_t requestId;
ReturnValue_t result = getRequestIdFromData(data, size, requestId);
if (result != RETURN_OK) {
return result;
}
// DEBUG
if (debugMode) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::info << "PUS11::doDeleteActivity: requestId: " << requestId << std::endl;
#else
sif::printInfo("PUS11::doDeleteActivity: requestId: %d\n", requestId);
#endif
}
TcMapIter tcToDelete; // handle to the TC to be deleted, can be used if counter is valid
int tcToDeleteCount = 0; // counter of all found TCs. Should be 1.
for (auto it = telecommandMap.begin(); it != telecommandMap.end(); it++) {
if (it->second.requestId == requestId) {
tcToDelete = it;
tcToDeleteCount++;
}
}
// check if 1 explicit TC is found via request ID
if (tcToDeleteCount == 0 || tcToDeleteCount > 1) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "Service11TelecommandScheduling::doDeleteActivity: No or more than 1 TC found. "
"Cannot explicitly delete TC"
<< std::endl;
#else
sif::printWarning(
"Service11TelecommandScheduling::doDeleteActivity: No or more than 1 TC found. "
"Cannot explicitly delete TC");
#endif
return RETURN_FAILED;
}
// delete packet from store
if (tcStore->deleteData(tcToDelete->second.storeAddr) != RETURN_OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Service11TelecommandScheduling::doDeleteActivity: Could not delete TC from Store"
<< std::endl;
#else
sif::printError(
"Service11TelecommandScheduling::doDeleteActivity: Could not delete TC from Store\n");
#endif
return RETURN_FAILED;
}
telecommandMap.erase(tcToDelete);
if (debugMode) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::info << "PUS11::doDeleteActivity: Deleted TC from map" << std::endl;
#else
sif::printInfo("PUS11::doDeleteActivity: Deleted TC from map\n");
#endif
}
return RETURN_OK;
}
template <size_t MAX_NUM_TCS>
inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::doFilterDeleteActivity(
const uint8_t *data, size_t size) {
TcMapIter itBegin;
TcMapIter itEnd;
ReturnValue_t result = getMapFilterFromData(data, size, itBegin, itEnd);
// get the filter window as map range via dedicated method
if (result != RETURN_OK) {
return result;
}
int deletedTCs = 0;
for (TcMapIter it = itBegin; it != itEnd; it++) {
// delete packet from store
if (tcStore->deleteData(it->second.storeAddr) != RETURN_OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Service11TelecommandScheduling::doFilterDeleteActivity: Could not delete TC "
"from Store"
<< std::endl;
#else
sif::printError(
"Service11TelecommandScheduling::doFilterDeleteActivity: Could not delete TC from "
"Store\n");
#endif
continue;
}
deletedTCs++;
}
// NOTE: Spec says this function erases all elements including itBegin but not itEnd,
// see here: https://www.cplusplus.com/reference/map/multimap/erase/
// Therefore we need to increase itEnd by 1. (Note that end() returns the "past-the-end" iterator)
if (itEnd != telecommandMap.end()) {
itEnd++;
}
telecommandMap.erase(itBegin, itEnd);
if (debugMode) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::info << "PUS11::doFilterDeleteActivity: Deleted " << deletedTCs << " TCs" << std::endl;
#else
sif::printInfo("PUS11::doFilterDeleteActivity: Deleted %d TCs\n", deletedTCs);
#endif
}
return RETURN_OK;
}
template <size_t MAX_NUM_TCS>
inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::doTimeshiftActivity(
const uint8_t *data, size_t size) {
// Get relative time
uint32_t relativeTime = 0;
ReturnValue_t result = SerializeAdapter::deSerialize(&relativeTime, &data, &size, DEF_END);
if (result != RETURN_OK) {
return result;
}
if (relativeTime == 0) {
return INVALID_RELATIVE_TIME;
}
// TODO further check sanity of the relative time?
// Get request ID
uint64_t requestId;
result = getRequestIdFromData(data, size, requestId);
if (result != RETURN_OK) {
return result;
}
if (debugMode) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::info << "PUS11::doTimeshiftActivity: requestId: " << requestId << std::endl;
#else
sif::printInfo("PUS11::doTimeshiftActivity: requestId: %d\n", requestId);
#endif
}
// NOTE: Despite having C++17 ETL multimap has no member function extract :(
TcMapIter tcToTimeshiftIt;
int tcToTimeshiftCount = 0;
for (auto it = telecommandMap.begin(); it != telecommandMap.end(); it++) {
if (it->second.requestId == requestId) {
tcToTimeshiftIt = it;
tcToTimeshiftCount++;
}
}
if (tcToTimeshiftCount == 0 || tcToTimeshiftCount > 1) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "Service11TelecommandScheduling::doTimeshiftActivity: Either 0 or more than 1 "
"TCs found. No explicit timeshifting "
"possible"
<< std::endl;
#else
sif::printWarning(
"Service11TelecommandScheduling::doTimeshiftActivity: Either 0 or more than 1 TCs found. "
"No explicit timeshifting possible\n");
#endif
return TIMESHIFTING_NOT_POSSIBLE;
}
// temporarily hold the item
TelecommandStruct tempTc(tcToTimeshiftIt->second);
uint32_t tempKey = tcToTimeshiftIt->first + relativeTime;
// delete old entry from the mm
telecommandMap.erase(tcToTimeshiftIt);
// and then insert it again as new entry
telecommandMap.insert(std::make_pair(tempKey, tempTc));
if (debugMode) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::info << "PUS11::doTimeshiftActivity: Shifted TC" << std::endl;
#else
sif::printDebug("PUS11::doTimeshiftActivity: Shifted TC\n");
#endif
debugPrintMultimapContent();
}
return RETURN_OK;
}
template <size_t MAX_NUM_TCS>
inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::doFilterTimeshiftActivity(
const uint8_t *data, size_t size) {
// Get relative time
uint32_t relativeTime = 0;
ReturnValue_t result = SerializeAdapter::deSerialize(&relativeTime, &data, &size, DEF_END);
if (result != RETURN_OK) {
return result;
}
if (relativeTime == 0) {
return INVALID_RELATIVE_TIME;
}
// Do time window
TcMapIter itBegin;
TcMapIter itEnd;
result = getMapFilterFromData(data, size, itBegin, itEnd);
if (result != RETURN_OK) {
return result;
}
int shiftedItemsCount = 0;
for (auto it = itBegin; it != itEnd;) {
// temporarily hold the item
TelecommandStruct tempTc(it->second);
uint32_t tempKey = it->first + relativeTime;
// delete the old entry from the mm
telecommandMap.erase(it++);
// and then insert it again as new entry
telecommandMap.insert(std::make_pair(tempKey, tempTc));
shiftedItemsCount++;
}
if (debugMode) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::info << "PUS11::doFilterTimeshiftActivity: shiftedItemsCount: " << shiftedItemsCount
<< std::endl;
#else
sif::printInfo("PUS11::doFilterTimeshiftActivity: shiftedItemsCount: %d\n", shiftedItemsCount);
#endif
debugPrintMultimapContent();
}
if (shiftedItemsCount > 0) {
return RETURN_OK;
}
return RETURN_FAILED;
}
template <size_t MAX_NUM_TCS>
inline uint64_t Service11TelecommandScheduling<MAX_NUM_TCS>::getRequestIdFromDataTC(
const uint8_t *data) const {
TcPacketPus mask(data);
uint32_t sourceId = mask.getSourceId();
uint16_t apid = mask.getAPID();
uint16_t sequenceCount = mask.getPacketSequenceCount();
return buildRequestId(sourceId, apid, sequenceCount);
}
template <size_t MAX_NUM_TCS>
inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::getRequestIdFromData(
const uint8_t *&data, size_t &dataSize, uint64_t &requestId) {
uint32_t srcId = 0;
uint16_t apid = 0;
uint16_t ssc = 0;
ReturnValue_t result = SerializeAdapter::deSerialize(&srcId, &data, &dataSize, DEF_END);
if (result != RETURN_OK) {
return result;
}
result = SerializeAdapter::deSerialize(&apid, &data, &dataSize, DEF_END);
if (result != RETURN_OK) {
return result;
}
result = SerializeAdapter::deSerialize(&ssc, &data, &dataSize, DEF_END);
if (result != RETURN_OK) {
return result;
}
requestId = buildRequestId(srcId, apid, ssc);
return RETURN_OK;
}
template <size_t MAX_NUM_TCS>
inline uint64_t Service11TelecommandScheduling<MAX_NUM_TCS>::buildRequestId(uint32_t sourceId,
uint16_t apid,
uint16_t ssc) const {
auto sourceId64 = static_cast<uint64_t>(sourceId);
auto apid64 = static_cast<uint64_t>(apid);
auto ssc64 = static_cast<uint64_t>(ssc);
return (sourceId64 << 32) | (apid64 << 16) | ssc64;
}
template <size_t MAX_NUM_TCS>
inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::getMapFilterFromData(
const uint8_t *&data, size_t &dataSize, TcMapIter &itBegin, TcMapIter &itEnd) {
// get filter type first
uint32_t typeRaw = 0;
ReturnValue_t result = SerializeAdapter::deSerialize(&typeRaw, &data, &dataSize, DEF_END);
if (result != RETURN_OK) {
return result;
}
if (typeRaw > 3) {
return INVALID_TYPE_TIME_WINDOW;
}
auto type = static_cast<TypeOfTimeWindow>(typeRaw);
// we now have the type of delete activity - so now we set the range to delete,
// according to the type of time window.
// NOTE: Blocks are used in this switch-case statement so that timestamps can be
// cleanly redefined for each case.
switch (type) {
case TypeOfTimeWindow::SELECT_ALL: {
itBegin = telecommandMap.begin();
itEnd = telecommandMap.end();
break;
}
case TypeOfTimeWindow::FROM_TIMETAG: {
uint32_t fromTimestamp = 0;
result = SerializeAdapter::deSerialize(&fromTimestamp, &data, &dataSize, DEF_END);
if (result != RETURN_OK) {
return result;
}
itBegin = telecommandMap.begin();
while (itBegin->first < fromTimestamp && itBegin != telecommandMap.end()) {
itBegin++;
}
itEnd = telecommandMap.end();
break;
}
case TypeOfTimeWindow::TO_TIMETAG: {
uint32_t toTimestamp;
result = SerializeAdapter::deSerialize(&toTimestamp, &data, &dataSize, DEF_END);
if (result != RETURN_OK) {
return result;
}
itBegin = telecommandMap.begin();
itEnd = telecommandMap.begin();
while (itEnd->first <= toTimestamp && itEnd != telecommandMap.end()) {
itEnd++;
}
break;
}
case TypeOfTimeWindow::FROM_TIMETAG_TO_TIMETAG: {
uint32_t fromTimestamp;
uint32_t toTimestamp;
result = SerializeAdapter::deSerialize(&fromTimestamp, &data, &dataSize,
SerializeIF::Endianness::BIG);
if (result != RETURN_OK) {
return result;
}
result = SerializeAdapter::deSerialize(&toTimestamp, &data, &dataSize,
SerializeIF::Endianness::BIG);
if (result != RETURN_OK) {
return result;
}
itBegin = telecommandMap.begin();
itEnd = telecommandMap.begin();
while (itBegin->first < fromTimestamp && itBegin != telecommandMap.end()) {
itBegin++;
}
while (itEnd->first <= toTimestamp && itEnd != telecommandMap.end()) {
itEnd++;
}
break;
}
default:
return RETURN_FAILED;
}
// additional security check, this should never be true
if (itBegin->first > itEnd->first) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
#else
sif::printError("11::GetMapFilterFromData: itBegin > itEnd\n");
#endif
return RETURN_FAILED;
}
// the map range should now be set according to the sent filter.
return RETURN_OK;
}
template <size_t MAX_NUM_TCS>
inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::handleInvalidData(
const char *ctx) {
#if FSFW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "Service11TelecommandScheduling:: " << ctx << ": Invalid buffer" << std::endl;
#else
sif::printWarning("Service11TelecommandScheduling::%s: Invalid buffer\n", ctx);
#endif
#endif
return RETURN_FAILED;
}
template <size_t MAX_NUM_TCS>
inline void Service11TelecommandScheduling<MAX_NUM_TCS>::debugPrintMultimapContent() const {
for ([[maybe_unused]] const auto &dit : telecommandMap) {
#if FSFW_DISABLE_PRINTOUT == 0
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::debug << "Service11TelecommandScheduling::debugPrintMultimapContent: Multimap Content"
<< std::endl;
sif::debug << "[" << dit.first << "]: Request ID: " << dit.second.requestId << " | "
<< "Store Address: " << dit.second.storeAddr.raw << std::endl;
#else
sif::printDebug(
"Service11TelecommandScheduling::debugPrintMultimapContent: Multimap Content\n");
for (auto dit = telecommandMap.begin(); dit != telecommandMap.end(); ++dit) {
sif::printDebug("[%d]: Request ID: %d | Store Address: %d\n", dit->first,
dit->second.requestId, dit->second.storeAddr);
}
#endif
#endif
}
}
template <size_t MAX_NUM_TCS>
inline void Service11TelecommandScheduling<MAX_NUM_TCS>::enableExpiredTcDeletion() {
deleteExpiredTcWhenDisabled = true;
}
template <size_t MAX_NUM_TCS>
inline void Service11TelecommandScheduling<MAX_NUM_TCS>::disableExpiredTcDeletion() {
deleteExpiredTcWhenDisabled = false;
}

View File

@ -86,8 +86,8 @@ ReturnValue_t Service5EventReporting::handleRequest(uint8_t subservice) {
// In addition to the default PUSServiceBase initialization, this service needs
// to be registered to the event manager to listen for events.
ReturnValue_t Service5EventReporting::initialize() {
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
if (manager == NULL) {
auto* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
if (manager == nullptr) {
return RETURN_FAILED;
}
// register Service 5 as listener for events

View File

@ -72,6 +72,7 @@ enum : uint8_t {
DLE_ENCODER, // DLEE
PUS_SERVICE_3, // PUS3
PUS_SERVICE_9, // PUS9
PUS_SERVICE_11, // PUS11
FILE_SYSTEM, // FILS
LINUX_OSAL, // UXOS
HAL_SPI, // HSPI

View File

@ -1,7 +1,2 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
RMAP.cpp
RMAPCookie.cpp
RmapDeviceCommunicationIF.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE RMAP.cpp RMAPCookie.cpp
RmapDeviceCommunicationIF.cpp)

View File

@ -1,4 +1 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
SerialBufferAdapter.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE SerialBufferAdapter.cpp)

View File

@ -1,5 +1,4 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
ServiceInterfaceStream.cpp
ServiceInterfaceBuffer.cpp
ServiceInterfacePrinter.cpp
)
target_sources(
${LIB_FSFW_NAME}
PRIVATE ServiceInterfaceStream.cpp ServiceInterfaceBuffer.cpp
ServiceInterfacePrinter.cpp)

View File

@ -1,7 +1,3 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
ConstStorageAccessor.cpp
StorageAccessor.cpp
LocalPool.cpp
PoolManager.cpp
)
target_sources(
${LIB_FSFW_NAME} PRIVATE ConstStorageAccessor.cpp StorageAccessor.cpp
LocalPool.cpp PoolManager.cpp)

View File

@ -1,7 +1,3 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
Subsystem.cpp
SubsystemBase.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE Subsystem.cpp SubsystemBase.cpp)
add_subdirectory(modes)
add_subdirectory(modes)

View File

@ -307,6 +307,11 @@ void Subsystem::replyToCommand(ReturnValue_t status, uint32_t parameter) {
}
}
ReturnValue_t Subsystem::addSequence(SequenceEntry sequence) {
return addSequence(sequence.table, sequence.mode, sequence.fallbackMode, sequence.inStore,
sequence.preInit);
}
ReturnValue_t Subsystem::addSequence(ArrayList<ModeListEntry> *sequence, Mode_t id,
Mode_t fallbackSequence, bool inStore, bool preInit) {
ReturnValue_t result;
@ -350,6 +355,10 @@ ReturnValue_t Subsystem::addSequence(ArrayList<ModeListEntry> *sequence, Mode_t
return result;
}
ReturnValue_t Subsystem::addTable(TableEntry table) {
return addTable(table.table, table.mode, table.inStore, table.preInit);
}
ReturnValue_t Subsystem::addTable(ArrayList<ModeListEntry> *table, Mode_t id, bool inStore,
bool preInit) {
ReturnValue_t result;
@ -458,6 +467,7 @@ ReturnValue_t Subsystem::initialize() {
}
mode = initialMode;
submode = initSubmode;
return RETURN_OK;
}
@ -595,7 +605,10 @@ ReturnValue_t Subsystem::checkObjectConnections() {
return RETURN_OK;
}
void Subsystem::setInitialMode(Mode_t mode) { initialMode = mode; }
void Subsystem::setInitialMode(Mode_t mode, Submode_t submode) {
this->initialMode = mode;
this->initSubmode = submode;
}
void Subsystem::cantKeepMode() {
ReturnValue_t result;

View File

@ -10,6 +10,28 @@
#include "fsfw/FSFW.h"
#include "modes/ModeDefinitions.h"
struct TableSequenceBase {
public:
TableSequenceBase(Mode_t mode, ArrayList<ModeListEntry> *table) : mode(mode), table(table){};
Mode_t mode;
ArrayList<ModeListEntry> *table;
bool inStore = false;
bool preInit = true;
};
struct TableEntry : public TableSequenceBase {
public:
TableEntry(Mode_t mode, ArrayList<ModeListEntry> *table) : TableSequenceBase(mode, table){};
};
struct SequenceEntry : public TableSequenceBase {
public:
SequenceEntry(Mode_t mode, ArrayList<ModeListEntry> *table, Mode_t fallbackMode)
: TableSequenceBase(mode, table), fallbackMode(fallbackMode) {}
Mode_t fallbackMode;
};
/**
* @brief TODO: documentation missing
* @details
@ -44,13 +66,15 @@ class Subsystem : public SubsystemBase, public HasModeSequenceIF {
uint32_t maxNumberOfTables);
virtual ~Subsystem();
ReturnValue_t addSequence(SequenceEntry sequence);
ReturnValue_t addSequence(ArrayList<ModeListEntry> *sequence, Mode_t id, Mode_t fallbackSequence,
bool inStore = true, bool preInit = true);
ReturnValue_t addTable(TableEntry table);
ReturnValue_t addTable(ArrayList<ModeListEntry> *table, Mode_t id, bool inStore = true,
bool preInit = true);
void setInitialMode(Mode_t mode);
void setInitialMode(Mode_t mode, Submode_t submode = SUBMODE_NONE);
virtual ReturnValue_t initialize() override;
@ -89,6 +113,7 @@ class Subsystem : public SubsystemBase, public HasModeSequenceIF {
Submode_t targetSubmode;
Mode_t initialMode = 0;
Submode_t initSubmode = SUBMODE_NONE;
HybridIterator<ModeListEntry> currentSequenceIterator;

View File

@ -1,5 +1 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
ModeSequenceMessage.cpp
ModeStore.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE ModeSequenceMessage.cpp ModeStore.cpp)

View File

@ -1,5 +1,2 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
FixedSequenceSlot.cpp
FixedSlotSequence.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE FixedSequenceSlot.cpp
FixedSlotSequence.cpp)

View File

@ -9,7 +9,7 @@
CCSDSDistributor::CCSDSDistributor(uint16_t setDefaultApid, object_id_t setObjectId)
: TcDistributor(setObjectId), defaultApid(setDefaultApid) {}
CCSDSDistributor::~CCSDSDistributor() {}
CCSDSDistributor::~CCSDSDistributor() = default;
TcDistributor::TcMqMapIter CCSDSDistributor::selectDestination() {
#if CCSDS_DISTRIBUTOR_DEBUGGING == 1
@ -38,6 +38,7 @@ TcDistributor::TcMqMapIter CCSDSDistributor::selectDestination() {
" store failed!\n");
#endif
#endif
return queueMap.end();
}
SpacePacketBase currentPacket(packet);
@ -45,7 +46,7 @@ TcDistributor::TcMqMapIter CCSDSDistributor::selectDestination() {
sif::info << "CCSDSDistributor::selectDestination has packet with APID " << std::hex
<< currentPacket.getAPID() << std::dec << std::endl;
#endif
TcMqMapIter position = this->queueMap.find(currentPacket.getAPID());
auto position = this->queueMap.find(currentPacket.getAPID());
if (position != this->queueMap.end()) {
return position;
} else {

View File

@ -1,9 +1,4 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
CCSDSDistributor.cpp
PUSDistributor.cpp
TcDistributor.cpp
TcPacketCheckPUS.cpp
TcPacketCheckCFDP.cpp
CFDPDistributor.cpp
)
target_sources(
${LIB_FSFW_NAME}
PRIVATE CCSDSDistributor.cpp PUSDistributor.cpp TcDistributor.cpp
TcPacketCheckPUS.cpp TcPacketCheckCFDP.cpp CFDPDistributor.cpp)

View File

@ -15,7 +15,7 @@ PUSDistributor::PUSDistributor(uint16_t setApid, object_id_t setObjectId,
tcStatus(RETURN_FAILED),
packetSource(setPacketSource) {}
PUSDistributor::~PUSDistributor() {}
PUSDistributor::~PUSDistributor() = default;
PUSDistributor::TcMqMapIter PUSDistributor::selectDestination() {
#if FSFW_CPP_OSTREAM_ENABLED == 1 && PUS_DISTRIBUTOR_DEBUGGING == 1
@ -23,7 +23,7 @@ PUSDistributor::TcMqMapIter PUSDistributor::selectDestination() {
sif::debug << "PUSDistributor::handlePacket received: " << storeId.poolIndex << ", "
<< storeId.packetIndex << std::endl;
#endif
TcMqMapIter queueMapIt = this->queueMap.end();
auto queueMapIt = this->queueMap.end();
if (this->currentPacket == nullptr) {
return queueMapIt;
}
@ -48,10 +48,8 @@ PUSDistributor::TcMqMapIter PUSDistributor::selectDestination() {
sif::warning << "PUSDistributor::handlePacket: Packet format invalid, " << keyword
<< " error" << std::endl;
#else
sif::printWarning(
"PUSDistributor::handlePacket: Packet format invalid, "
"%s error\n",
keyword);
sif::printWarning("PUSDistributor::handlePacket: Packet format invalid, %s error\n",
keyword);
#endif
#endif
}
@ -133,8 +131,7 @@ ReturnValue_t PUSDistributor::initialize() {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
CCSDSDistributorIF* ccsdsDistributor =
ObjectManager::instance()->get<CCSDSDistributorIF>(packetSource);
auto* ccsdsDistributor = ObjectManager::instance()->get<CCSDSDistributorIF>(packetSource);
if (ccsdsDistributor == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "PUSDistributor::initialize: Packet source invalid" << std::endl;

View File

@ -1,10 +1,9 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
AbstractTemperatureSensor.cpp
Heater.cpp
RedundantHeater.cpp
ThermalComponentCore.cpp
ThermalComponent.cpp
ThermalModule.cpp
ThermalMonitorReporter.cpp
)
target_sources(
${LIB_FSFW_NAME}
PRIVATE AbstractTemperatureSensor.cpp
Heater.cpp
RedundantHeater.cpp
ThermalComponentCore.cpp
ThermalComponent.cpp
ThermalModule.cpp
ThermalMonitorReporter.cpp)

View File

@ -1,8 +1,3 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
CCSDSTime.cpp
Countdown.cpp
Stopwatch.cpp
TimeMessage.cpp
TimeStamper.cpp
ClockCommon.cpp
)
target_sources(
${LIB_FSFW_NAME} PRIVATE CCSDSTime.cpp Countdown.cpp Stopwatch.cpp
TimeMessage.cpp TimeStamper.cpp ClockCommon.cpp)

View File

@ -1,4 +1 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
TmStoreMessage.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE TmStoreMessage.cpp)

View File

@ -1,8 +1,5 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
SpacePacket.cpp
SpacePacketBase.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE SpacePacket.cpp SpacePacketBase.cpp)
add_subdirectory(cfdp)
add_subdirectory(packetmatcher)
add_subdirectory(pus)
add_subdirectory(pus)

View File

@ -1,4 +1 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
CFDPPacket.cpp
CFDPPacketStored.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE CFDPPacket.cpp CFDPPacketStored.cpp)

View File

@ -1,4 +1 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
PacketMatchTree.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE PacketMatchTree.cpp)

View File

@ -1,6 +1,3 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
TcPacketPusBase.cpp
TcPacketPus.cpp
TcPacketStoredBase.cpp
TcPacketStoredPus.cpp
)
target_sources(
${LIB_FSFW_NAME} PRIVATE TcPacketPusBase.cpp TcPacketPus.cpp
TcPacketStoredBase.cpp TcPacketStoredPus.cpp)

View File

@ -6,20 +6,20 @@
#include "fsfw/objectmanager/frameworkObjects.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
StorageManagerIF* TcPacketStoredBase::store = nullptr;
StorageManagerIF* TcPacketStoredBase::STORE = nullptr;
TcPacketStoredBase::TcPacketStoredBase() {
this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
this->checkAndSetStore();
TcPacketStoredBase::checkAndSetStore();
}
TcPacketStoredBase::~TcPacketStoredBase() {}
TcPacketStoredBase::~TcPacketStoredBase() = default;
ReturnValue_t TcPacketStoredBase::getData(const uint8_t** dataPtr, size_t* dataSize) {
auto result = this->store->getData(storeAddress, dataPtr, dataSize);
auto result = TcPacketStoredBase::STORE->getData(storeAddress, dataPtr, dataSize);
if (result != HasReturnvaluesIF::RETURN_OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "TcPacketStoredBase: Could not get data!" << std::endl;
sif::warning << "TcPacketStoredBase: Could not get data" << std::endl;
#else
sif::printWarning("TcPacketStoredBase: Could not get data!\n");
#endif
@ -28,11 +28,13 @@ ReturnValue_t TcPacketStoredBase::getData(const uint8_t** dataPtr, size_t* dataS
}
bool TcPacketStoredBase::checkAndSetStore() {
if (this->store == nullptr) {
this->store = ObjectManager::instance()->get<StorageManagerIF>(objects::TC_STORE);
if (this->store == nullptr) {
if (TcPacketStoredBase::STORE == nullptr) {
TcPacketStoredBase::STORE = ObjectManager::instance()->get<StorageManagerIF>(objects::TC_STORE);
if (TcPacketStoredBase::STORE == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "TcPacketStoredBase::TcPacketStoredBase: TC Store not found!" << std::endl;
sif::error << "TcPacketStoredBase::TcPacketStoredBase: TC Store not found" << std::endl;
#else
sif::printError("TcPacketStoredBase::TcPacketStoredBase: TC Store not found\n");
#endif
return false;
}
@ -47,7 +49,7 @@ void TcPacketStoredBase::setStoreAddress(store_address_t setAddress,
size_t tempSize;
ReturnValue_t status = StorageManagerIF::RETURN_FAILED;
if (this->checkAndSetStore()) {
status = this->store->getData(this->storeAddress, &tempData, &tempSize);
status = TcPacketStoredBase::STORE->getData(this->storeAddress, &tempData, &tempSize);
}
if (status == StorageManagerIF::RETURN_OK) {

View File

@ -65,7 +65,7 @@ class TcPacketStoredBase : public TcPacketStoredIF {
* call tries to set it and throws an error message in case of failures.
* The default store is objects::TC_STORE.
*/
static StorageManagerIF* store;
static StorageManagerIF* STORE;
/**
* The address where the packet data of the object instance is stored.
*/
@ -77,7 +77,7 @@ class TcPacketStoredBase : public TcPacketStoredIF {
* @return @li @c true if the store is linked or could be created.
* @li @c false otherwise.
*/
bool checkAndSetStore();
static bool checkAndSetStore();
};
#endif /* TMTCPACKET_PUS_TcPacketStoredBase_H_ */
#endif /* TMTCPACKET_PUS_TCPACKETSTORED_H_ */

View File

@ -9,7 +9,8 @@
class TcPacketStoredIF {
public:
virtual ~TcPacketStoredIF(){};
virtual ~TcPacketStoredIF() = default;
;
/**
* With this call, the stored packet can be set to another packet in a store. This is useful

View File

@ -14,8 +14,8 @@ TcPacketStoredPus::TcPacketStoredPus(uint16_t apid, uint8_t service, uint8_t sub
}
uint8_t* pData = nullptr;
ReturnValue_t returnValue =
this->store->getFreeElement(&this->storeAddress, (TC_PACKET_MIN_SIZE + size), &pData);
if (returnValue != this->store->RETURN_OK) {
this->STORE->getFreeElement(&this->storeAddress, (TC_PACKET_MIN_SIZE + size), &pData);
if (returnValue != this->STORE->RETURN_OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "TcPacketStoredBase: Could not get free element from store!" << std::endl;
#endif
@ -44,19 +44,19 @@ TcPacketStoredPus::TcPacketStoredPus(const uint8_t* data, size_t size) : TcPacke
return;
}
if (this->checkAndSetStore()) {
ReturnValue_t status = store->addData(&storeAddress, data, size);
ReturnValue_t status = STORE->addData(&storeAddress, data, size);
if (status != HasReturnvaluesIF::RETURN_OK) {
this->setData(nullptr, size);
}
const uint8_t* storePtr = nullptr;
// Repoint base data pointer to the data in the store.
store->getData(storeAddress, &storePtr, &size);
STORE->getData(storeAddress, &storePtr, &size);
this->setData(const_cast<uint8_t*>(storePtr), size);
}
}
ReturnValue_t TcPacketStoredPus::deletePacket() {
ReturnValue_t result = this->store->deleteData(this->storeAddress);
ReturnValue_t result = this->STORE->deleteData(this->storeAddress);
this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
// To circumvent size checks
this->setData(nullptr, -1);
@ -68,7 +68,7 @@ TcPacketPusBase* TcPacketStoredPus::getPacketBase() { return this; }
bool TcPacketStoredPus::isSizeCorrect() {
const uint8_t* temp_data = nullptr;
size_t temp_size;
ReturnValue_t status = this->store->getData(this->storeAddress, &temp_data, &temp_size);
ReturnValue_t status = this->STORE->getData(this->storeAddress, &temp_data, &temp_size);
if (status == StorageManagerIF::RETURN_OK) {
if (this->getFullSize() == temp_size) {
return true;

View File

@ -1,9 +1,9 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
TmPacketStoredPusA.cpp
TmPacketStoredPusC.cpp
TmPacketPusA.cpp
TmPacketPusC.cpp
TmPacketStoredBase.cpp
TmPacketBase.cpp
TmPacketMinimal.cpp
)
target_sources(
${LIB_FSFW_NAME}
PRIVATE TmPacketStoredPusA.cpp
TmPacketStoredPusC.cpp
TmPacketPusA.cpp
TmPacketPusC.cpp
TmPacketStoredBase.cpp
TmPacketBase.cpp
TmPacketMinimal.cpp)

View File

@ -1,7 +1,7 @@
#ifndef FRAMEWORK_TMTCSERVICES_ACCEPTSTELECOMMANDSIF_H_
#define FRAMEWORK_TMTCSERVICES_ACCEPTSTELECOMMANDSIF_H_
#include "../ipc/MessageQueueSenderIF.h"
#include "fsfw/ipc/MessageQueueSenderIF.h"
/**
* @brief This interface is implemented by classes that are sinks for
@ -20,7 +20,7 @@ class AcceptsTelecommandsIF {
/**
* @brief The virtual destructor as it is mandatory for C++ interfaces.
*/
virtual ~AcceptsTelecommandsIF() {}
virtual ~AcceptsTelecommandsIF() = default;
/**
* @brief Getter for the service id.
* @details Any receiving service (at least any PUS service) shall have a

View File

@ -1,10 +1,9 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
CommandingServiceBase.cpp
PusServiceBase.cpp
PusVerificationReport.cpp
TmTcBridge.cpp
TmTcMessage.cpp
VerificationReporter.cpp
SpacePacketParser.cpp
)
target_sources(
${LIB_FSFW_NAME}
PRIVATE CommandingServiceBase.cpp
PusServiceBase.cpp
PusVerificationReport.cpp
TmTcBridge.cpp
TmTcMessage.cpp
VerificationReporter.cpp
SpacePacketParser.cpp)

View File

@ -166,7 +166,7 @@ class CommandingServiceBase : public SystemObject,
* @param objectId Target object ID
* @return
* - @c RETURN_OK to generate a verification start message
* - @c EXECUTION_COMPELTE Fire-and-forget command. Generate a completion
* - @c EXECUTION_COMPLETE Fire-and-forget command. Generate a completion
* verification message.
* - @c Anything else rejects the packets and generates a start failure
* verification.

View File

@ -13,11 +13,28 @@
#endif
const fsfw::Version fsfw::FSFW_VERSION = {FSFW_VERSION_MAJOR, FSFW_VERSION_MINOR,
FSFW_VERSION_REVISION};
FSFW_VERSION_REVISION, FSFW_VCS_INFO};
fsfw::Version::Version(uint32_t major, uint32_t minor, uint32_t revision)
: major(major), minor(minor), revision(revision) {}
fsfw::Version::Version(int major, int minor, int revision, const char* addInfo)
: major(major), minor(minor), revision(revision), addInfo(addInfo) {}
void fsfw::Version::getVersion(char* str, size_t maxLen) const {
snprintf(str, maxLen, "%d.%d.%d", major, minor, revision);
size_t len = snprintf(str, maxLen, "%d.%d.%d", major, minor, revision);
if (addInfo != nullptr) {
snprintf(str + len, maxLen - len, "-%s", addInfo);
}
}
namespace fsfw {
#if FSFW_CPP_OSTREAM_ENABLED == 1
std::ostream& operator<<(std::ostream& os, const Version& v) {
os << v.major << "." << v.minor << "." << v.revision;
if (v.addInfo != nullptr) {
os << "-" << v.addInfo;
}
return os;
}
#endif
} // namespace fsfw

View File

@ -12,10 +12,13 @@ namespace fsfw {
class Version {
public:
Version(uint32_t major, uint32_t minor, uint32_t revision);
uint32_t major = 0;
uint32_t minor = 0;
uint32_t revision = 0;
Version(int major, int minor, int revision, const char* addInfo = nullptr);
int major = -1;
int minor = -1;
int revision = -1;
// Additional information, e.g. a git SHA hash
const char* addInfo = nullptr;
friend bool operator==(const Version& v1, const Version& v2) {
return (v1.major == v2.major and v1.minor == v2.minor and v1.revision == v2.revision);
@ -43,10 +46,7 @@ class Version {
* @param v
* @return
*/
friend std::ostream& operator<<(std::ostream& os, const Version& v) {
os << v.major << "." << v.minor << "." << v.revision;
return os;
}
friend std::ostream& operator<<(std::ostream& os, const Version& v);
#endif
/**
@ -57,7 +57,7 @@ class Version {
void getVersion(char* str, size_t maxLen) const;
};
extern const fsfw::Version FSFW_VERSION;
extern const Version FSFW_VERSION;
} // namespace fsfw