Compare commits
75 Commits
master
...
developmen
Author | SHA1 | Date | |
---|---|---|---|
5084db6cd6 | |||
5739c4f357 | |||
dc1e7b30f4 | |||
d0aa857f0f | |||
15b165d6d8 | |||
bc4730b930 | |||
81174476be | |||
8001158c82 | |||
515c66a780 | |||
8c20417af9 | |||
ac817f296b | |||
622ad9ff18 | |||
f0e4eacac5 | |||
acc737feb2 | |||
c9281a3760 | |||
cc97c7f82d | |||
a3b102c0d0 | |||
5dd4f15b39 | |||
b5a3c0226e | |||
e925b8595c | |||
c5bf5389b8 | |||
7285dd6bac | |||
b53bf2ea12 | |||
610c196f6d | |||
ece47b4f2f | |||
3f777c54fe | |||
3d54895251 | |||
d91e1ecc0a | |||
e5910c77e9 | |||
1569416a8f | |||
278c8f1186 | |||
60f6ef5f1f | |||
4ecd9eb62e | |||
fb89d7a3b6 | |||
146c3471d0 | |||
1816c3f623 | |||
d03d5aa74c | |||
26e97ddf89 | |||
be3a57a795 | |||
13b97abf0d | |||
f95c373076 | |||
e03731bcf8 | |||
9fe8579377 | |||
2714e588d7 | |||
e905288adc | |||
3805ea50a7 | |||
699bd694cd | |||
4518fec65c | |||
dac1aacab2 | |||
0042f92fdf | |||
656faf8169 | |||
f84431e965 | |||
0cec9ebb73 | |||
a440b7c394 | |||
bbfc1b2b34 | |||
025b379e8b | |||
c35a0a8541 | |||
0f81d5e458 | |||
e0a072859b | |||
b50f092939 | |||
2f90e12179 | |||
8b77fac099 | |||
47503824d7 | |||
5e3f5c4121 | |||
1f36c082ef | |||
aa84e93603 | |||
8f63a0e747 | |||
6fc8f756a7 | |||
067cb7d0f8 | |||
d98ed40e3d | |||
2c17af4ef8 | |||
110fb43b9c | |||
b057250bfb | |||
066dd0d397 | |||
f735c2e9d4 |
36
CHANGELOG.md
36
CHANGELOG.md
@ -8,6 +8,42 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
# [unreleased]
|
||||
|
||||
## Fixes
|
||||
|
||||
- The `PusTmCreator` API only accepted 255 bytes of source data. It can now accept source
|
||||
data with a size limited only by the size of `size_t`.
|
||||
- Important bugfix in CFDP PDU header format: The entity length field and the transaction sequence
|
||||
number fields stored the actual length of the field instead of the length minus 1 like specified
|
||||
in the CFDP standard.
|
||||
- PUS Health Service: Size check for set health command.
|
||||
Perform operation completion for announce health command.
|
||||
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/746
|
||||
- Linux OSAL `getUptime` fix: Check validity of `/proc/uptime` file before reading uptime.
|
||||
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/745
|
||||
- Small tweak for version getter
|
||||
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/744
|
||||
- Important bugfix for `LocalPool::delete` function, where an overflow could possibly lead to UB.
|
||||
|
||||
## Added
|
||||
|
||||
- add CFDP subsystem ID
|
||||
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/742
|
||||
- New object ID for persistent TM store PUS 15
|
||||
- `EventManager`: Add function to print all listeners.
|
||||
|
||||
## Changed
|
||||
|
||||
- Bump ETL version to 20.35.14
|
||||
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/748
|
||||
- Renamed `PCDU_2` subsystem ID to `POWER_SWITCH_IF`.
|
||||
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/743
|
||||
- Add new `PowerSwitchIF::SWITCH_UNKNOWN` returnvalue.
|
||||
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/743
|
||||
- Assert that `FixedArrayList` is larger than 0 at compile time.
|
||||
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/740
|
||||
- `EventManager`: Queue depth is configurable now
|
||||
- `ActionHelper`: Allow execution of actions without additional data
|
||||
|
||||
# [v6.0.0] 2023-02-10
|
||||
|
||||
## Fixes
|
||||
|
@ -72,7 +72,7 @@ set(FSFW_ETL_LIB_MAJOR_VERSION
|
||||
20
|
||||
CACHE STRING "ETL library major version requirement")
|
||||
set(FSFW_ETL_LIB_VERSION
|
||||
${FSFW_ETL_LIB_MAJOR_VERSION}.28.0
|
||||
${FSFW_ETL_LIB_MAJOR_VERSION}.36.0
|
||||
CACHE STRING "ETL library exact version requirement")
|
||||
set(FSFW_ETL_LINK_TARGET etl::etl)
|
||||
|
||||
@ -80,7 +80,7 @@ set(FSFW_CATCH2_LIB_MAJOR_VERSION
|
||||
3
|
||||
CACHE STRING "Catch2 library major version requirement")
|
||||
set(FSFW_CATCH2_LIB_VERSION
|
||||
v${FSFW_CATCH2_LIB_MAJOR_VERSION}.1.0
|
||||
v${FSFW_CATCH2_LIB_MAJOR_VERSION}.3.2
|
||||
CACHE STRING "Catch2 library exact version requirement")
|
||||
|
||||
# Keep this off by default for now. See PR:
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM ubuntu:focal
|
||||
FROM ubuntu:latest
|
||||
|
||||
RUN apt-get update
|
||||
RUN apt-get --yes upgrade
|
||||
@ -7,7 +7,10 @@ RUN apt-get --yes upgrade
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get --yes install gcc g++ cmake make lcov git valgrind nano iputils-ping python3 pip doxygen graphviz rsync
|
||||
|
||||
RUN python3 -m pip install sphinx breathe
|
||||
# This should also install Sphinx
|
||||
COPY docs/requirements.txt .
|
||||
RUN python3 -m pip install -r requirements.txt
|
||||
RUN python3 -m pip install breathe
|
||||
|
||||
RUN git clone https://github.com/catchorg/Catch2.git && \
|
||||
cd Catch2 && \
|
||||
@ -26,4 +29,4 @@ RUN adduser --uid 114 jenkins
|
||||
|
||||
#add documentation server to known hosts
|
||||
RUN echo "|1|/LzCV4BuTmTb2wKnD146l9fTKgQ=|NJJtVjvWbtRt8OYqFgcYRnMQyVw= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNL8ssTonYtgiR/6RRlSIK9WU1ywOcJmxFTLcEblAwH7oifZzmYq3XRfwXrgfMpylEfMFYfCU8JRqtmi19xc21A=" >> /etc/ssh/ssh_known_hosts
|
||||
RUN echo "|1|CcBvBc3EG03G+XM5rqRHs6gK/Gg=|oGeJQ+1I8NGI2THIkJsW92DpTzs= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNL8ssTonYtgiR/6RRlSIK9WU1ywOcJmxFTLcEblAwH7oifZzmYq3XRfwXrgfMpylEfMFYfCU8JRqtmi19xc21A=" >> /etc/ssh/ssh_known_hosts
|
||||
RUN echo "|1|CcBvBc3EG03G+XM5rqRHs6gK/Gg=|oGeJQ+1I8NGI2THIkJsW92DpTzs= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNL8ssTonYtgiR/6RRlSIK9WU1ywOcJmxFTLcEblAwH7oifZzmYq3XRfwXrgfMpylEfMFYfCU8JRqtmi19xc21A=" >> /etc/ssh/ssh_known_hosts
|
||||
|
26
automation/Jenkinsfile
vendored
26
automation/Jenkinsfile
vendored
@ -6,7 +6,7 @@ pipeline {
|
||||
}
|
||||
agent {
|
||||
docker {
|
||||
image 'fsfw-ci:d6'
|
||||
image 'fsfw-ci:d12'
|
||||
args '--network host --sysctl fs.mqueue.msg_max=100'
|
||||
}
|
||||
}
|
||||
@ -87,38 +87,46 @@ pipeline {
|
||||
}
|
||||
stage('Documentation') {
|
||||
when {
|
||||
branch 'development'
|
||||
anyOf {
|
||||
branch 'development';
|
||||
branch pattern: 'development-doc-deployment*'
|
||||
}
|
||||
}
|
||||
steps {
|
||||
sh 'rsync --version'
|
||||
dir(DOCDDIR) {
|
||||
sh 'cmake -DFSFW_BUILD_DOCS=ON -DFSFW_OSAL=host ..'
|
||||
sh 'make Sphinx'
|
||||
sshagent(credentials: ['documentation-buildfix']) {
|
||||
sh 'rsync -r --delete docs/sphinx/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/development'
|
||||
sh 'rsync -r --delete docs/sphinx/* buildfix@documentation.irs.uni-stuttgart.de:/projects/fsfw/development'
|
||||
}
|
||||
}
|
||||
dir(BUILDDIR) {
|
||||
dir(BUILDDIR_LINUX) {
|
||||
sshagent(credentials: ['documentation-buildfix']) {
|
||||
sh 'rsync -r --delete fsfw-tests_coverage/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/coverage/development'
|
||||
sh 'rsync --mkpath -r --delete fsfw-tests_coverage/* buildfix@documentation.irs.uni-stuttgart.de:/projects/fsfw/coverage/development'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Master Documentation') {
|
||||
when {
|
||||
branch 'master'
|
||||
anyOf {
|
||||
branch 'master';
|
||||
branch pattern: 'master-doc-deployment*'
|
||||
}
|
||||
}
|
||||
steps {
|
||||
sh 'rsync --version'
|
||||
dir(DOCDDIR) {
|
||||
sh 'cmake -DFSFW_BUILD_DOCS=ON -DFSFW_OSAL=host ..'
|
||||
sh 'make Sphinx'
|
||||
sshagent(credentials: ['documentation-buildfix']) {
|
||||
sh 'rsync -r --delete docs/sphinx/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/master'
|
||||
sh 'rsync -r --delete docs/sphinx/* buildfix@documentation.irs.uni-stuttgart.de:/projects/fsfw/master'
|
||||
}
|
||||
}
|
||||
dir(BUILDDIR) {
|
||||
dir(BUILDDIR_LINUX) {
|
||||
sshagent(credentials: ['documentation-buildfix']) {
|
||||
sh 'rsync -r --delete fsfw-tests_coverage/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/coverage/master'
|
||||
sh 'rsync --mkpath -r --delete fsfw-tests_coverage/* buildfix@documentation.irs.uni-stuttgart.de:/projects/fsfw/coverage/master'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ project = "Flight Software Framework"
|
||||
copyright = "2021, Institute of Space Systems (IRS)"
|
||||
author = "Institute of Space Systems (IRS)"
|
||||
|
||||
# TODO: Should try to read this from CMakeLists.txt automatically..
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = "5.0.0"
|
||||
|
||||
@ -48,7 +49,7 @@ exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
html_theme = "alabaster"
|
||||
html_theme = "sphinx_rtd_theme"
|
||||
|
||||
html_theme_options = {
|
||||
"extra_nav_links": {"Impressum" : "https://www.uni-stuttgart.de/impressum", "Datenschutz": "https://info.irs.uni-stuttgart.de/datenschutz/datenschutzWebmit.html"}
|
||||
|
1
docs/requirements.txt
Normal file
1
docs/requirements.txt
Normal file
@ -0,0 +1 @@
|
||||
sphinx-rtd-theme==1.3.0
|
@ -59,17 +59,24 @@ void ActionHelper::setQueueToUse(MessageQueueIF* queue) { queueToUse = queue; }
|
||||
|
||||
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
|
||||
store_address_t dataAddress) {
|
||||
bool hasAdditionalData = false;
|
||||
const uint8_t* dataPtr = nullptr;
|
||||
size_t size = 0;
|
||||
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
||||
if (result != returnvalue::OK) {
|
||||
CommandMessage reply;
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
return;
|
||||
ReturnValue_t result;
|
||||
if (dataAddress != store_address_t::invalid()) {
|
||||
hasAdditionalData = true;
|
||||
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
||||
if (result != returnvalue::OK) {
|
||||
CommandMessage reply;
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
return;
|
||||
}
|
||||
}
|
||||
result = owner->executeAction(actionId, commandedBy, dataPtr, size);
|
||||
ipcStore->deleteData(dataAddress);
|
||||
if (hasAdditionalData) {
|
||||
ipcStore->deleteData(dataAddress);
|
||||
}
|
||||
if (result == HasActionsIF::EXECUTION_FINISHED) {
|
||||
CommandMessage reply;
|
||||
ActionMessage::setCompletionReply(&reply, actionId, true, result);
|
||||
|
@ -16,8 +16,8 @@ class CommandActionHelper {
|
||||
public:
|
||||
explicit CommandActionHelper(CommandsActionsIF* owner);
|
||||
virtual ~CommandActionHelper();
|
||||
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId, const uint8_t* data,
|
||||
uint32_t size);
|
||||
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId,
|
||||
const uint8_t* data = nullptr, uint32_t size = 0);
|
||||
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId, SerializeIF* data);
|
||||
ReturnValue_t initialize();
|
||||
ReturnValue_t handleReply(CommandMessage* reply);
|
||||
|
@ -51,8 +51,9 @@ class VarLenField : public SerializeIF {
|
||||
return os;
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
using SerializeIF::deSerialize; // we overloaded above, so this is needed to uncofuse the
|
||||
// compiler
|
||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
|
@ -24,8 +24,8 @@ ReturnValue_t HeaderCreator::serialize(uint8_t **buffer, size_t *size, size_t ma
|
||||
*buffer += 1;
|
||||
**buffer = pduDataFieldLen & 0x00ff;
|
||||
*buffer += 1;
|
||||
**buffer = segmentationCtrl << 7 | pduConf.sourceId.getWidth() << 4 | segmentMetadataFlag << 3 |
|
||||
pduConf.seqNum.getWidth();
|
||||
**buffer = segmentationCtrl << 7 | ((pduConf.sourceId.getWidth() - 1) << 4) |
|
||||
segmentMetadataFlag << 3 | (pduConf.seqNum.getWidth() - 1);
|
||||
*buffer += 1;
|
||||
*size += 4;
|
||||
ReturnValue_t result = pduConf.sourceId.serialize(buffer, size, maxSize, streamEndianness);
|
||||
|
@ -78,11 +78,11 @@ cfdp::SegmentationControl PduHeaderReader::getSegmentationControl() const {
|
||||
}
|
||||
|
||||
cfdp::WidthInBytes PduHeaderReader::getLenEntityIds() const {
|
||||
return static_cast<cfdp::WidthInBytes>((pointers.fixedHeader->fourthByte >> 4) & 0x07);
|
||||
return static_cast<cfdp::WidthInBytes>(((pointers.fixedHeader->fourthByte >> 4) & 0b111) + 1);
|
||||
}
|
||||
|
||||
cfdp::WidthInBytes PduHeaderReader::getLenSeqNum() const {
|
||||
return static_cast<cfdp::WidthInBytes>(pointers.fixedHeader->fourthByte & 0x07);
|
||||
return static_cast<cfdp::WidthInBytes>((pointers.fixedHeader->fourthByte & 0b111) + 1);
|
||||
}
|
||||
|
||||
cfdp::SegmentMetadataFlag PduHeaderReader::getSegmentMetadataFlag() const {
|
||||
|
@ -23,6 +23,8 @@ class EntityIdTlv : public TlvIF {
|
||||
*/
|
||||
ReturnValue_t deSerialize(cfdp::Tlv& tlv, Endianness endianness);
|
||||
|
||||
using SerializeIF::deSerialize; // we overloaded this function, so this is needed to unconfuse
|
||||
// the compiler
|
||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
|
@ -29,6 +29,8 @@ class FilestoreResponseTlv : public cfdp::FilestoreTlvBase {
|
||||
*/
|
||||
ReturnValue_t deSerialize(const cfdp::Tlv& tlv, Endianness endianness);
|
||||
|
||||
using SerializeIF::deSerialize; // we overloaded this function, so this is needed to unconfuse
|
||||
// the compiler
|
||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
|
@ -12,6 +12,7 @@ template <typename T, size_t MAX_SIZE, typename count_t = uint8_t>
|
||||
class FixedArrayList : public ArrayList<T, count_t> {
|
||||
static_assert(MAX_SIZE <= std::numeric_limits<count_t>::max(),
|
||||
"count_t is not large enough to hold MAX_SIZE");
|
||||
static_assert(MAX_SIZE > 0, "MAX_SIZE is 0");
|
||||
|
||||
private:
|
||||
T data[MAX_SIZE];
|
||||
|
@ -155,8 +155,8 @@ class FixedMap : public SerializeIF {
|
||||
|
||||
uint32_t maxSize() const { return theMap.maxSize(); }
|
||||
|
||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override {
|
||||
ReturnValue_t result =
|
||||
SerializeAdapter::serialize(&this->_size, buffer, size, maxSize, streamEndianness);
|
||||
uint32_t i = 0;
|
||||
@ -170,7 +170,7 @@ class FixedMap : public SerializeIF {
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual size_t getSerializedSize() const {
|
||||
size_t getSerializedSize() const override {
|
||||
uint32_t printSize = sizeof(_size);
|
||||
uint32_t i = 0;
|
||||
|
||||
@ -182,8 +182,8 @@ class FixedMap : public SerializeIF {
|
||||
return printSize;
|
||||
}
|
||||
|
||||
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
Endianness streamEndianness) {
|
||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
Endianness streamEndianness) override {
|
||||
ReturnValue_t result =
|
||||
SerializeAdapter::deSerialize(&this->_size, buffer, size, streamEndianness);
|
||||
if (this->_size > theMap.maxSize()) {
|
||||
|
@ -64,8 +64,8 @@ class PoolDataSetBase : public PoolDataSetIF, public SerializeIF {
|
||||
* - @c SET_WAS_ALREADY_READ if read() is called twice without calling
|
||||
* commit() in between
|
||||
*/
|
||||
virtual ReturnValue_t read(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||
uint32_t lockTimeout = 20) override;
|
||||
ReturnValue_t read(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||
uint32_t lockTimeout = 20) override;
|
||||
/**
|
||||
* @brief The commit call initializes writing back the registered variables.
|
||||
* @details
|
||||
@ -84,15 +84,15 @@ class PoolDataSetBase : public PoolDataSetIF, public SerializeIF {
|
||||
* - @c COMMITING_WITHOUT_READING if set was not read yet and
|
||||
* contains non write-only variables
|
||||
*/
|
||||
virtual ReturnValue_t commit(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||
uint32_t lockTimeout = 20) override;
|
||||
ReturnValue_t commit(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||
uint32_t lockTimeout = 20) override;
|
||||
|
||||
/**
|
||||
* Register the passed pool variable instance into the data set.
|
||||
* @param variable
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t registerVariable(PoolVariableIF* variable) override;
|
||||
ReturnValue_t registerVariable(PoolVariableIF* variable) override;
|
||||
|
||||
/**
|
||||
* Provides the means to lock the underlying data structure to ensure
|
||||
|
@ -87,9 +87,9 @@ class LocalPoolVariable : public LocalPoolObjectBase {
|
||||
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
SerializeIF::Endianness streamEndianness) const override;
|
||||
virtual size_t getSerializedSize() const override;
|
||||
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
SerializeIF::Endianness streamEndianness) override;
|
||||
size_t getSerializedSize() const override;
|
||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
SerializeIF::Endianness streamEndianness) override;
|
||||
|
||||
/**
|
||||
* @brief This is a call to read the array's values
|
||||
|
@ -98,11 +98,11 @@ class LocalPoolVector : public LocalPoolObjectBase {
|
||||
T& operator[](size_t i);
|
||||
const T& operator[](size_t i) const;
|
||||
|
||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, const size_t maxSize,
|
||||
SerializeIF::Endianness streamEndiannes) const override;
|
||||
virtual size_t getSerializedSize() const override;
|
||||
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
SerializeIF::Endianness streamEndianness) override;
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, const size_t maxSize,
|
||||
SerializeIF::Endianness streamEndiannes) const override;
|
||||
size_t getSerializedSize() const override;
|
||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
SerializeIF::Endianness streamEndianness) override;
|
||||
|
||||
/**
|
||||
* @brief This is a call to read the array's values
|
||||
|
@ -15,11 +15,12 @@ const LocalPool::LocalPoolConfig EventManager::poolConfig = {
|
||||
{fsfwconfig::FSFW_EVENTMGMT_EVENTIDMATCHERS, sizeof(EventIdRangeMatcher)},
|
||||
{fsfwconfig::FSFW_EVENTMGMR_RANGEMATCHERS, sizeof(ReporterRangeMatcher)}};
|
||||
|
||||
EventManager::EventManager(object_id_t setObjectId)
|
||||
EventManager::EventManager(object_id_t setObjectId, uint32_t eventQueueDepth)
|
||||
: SystemObject(setObjectId), factoryBackend(0, poolConfig, false, true) {
|
||||
mutex = MutexFactory::instance()->createMutex();
|
||||
eventReportQueue = QueueFactory::instance()->createMessageQueue(MAX_EVENTS_PER_CYCLE,
|
||||
EventMessage::EVENT_MESSAGE_SIZE);
|
||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||
eventReportQueue = QueueFactory::instance()->createMessageQueue(
|
||||
eventQueueDepth, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
|
||||
}
|
||||
|
||||
EventManager::~EventManager() {
|
||||
@ -47,9 +48,20 @@ ReturnValue_t EventManager::performOperation(uint8_t opCode) {
|
||||
|
||||
void EventManager::notifyListeners(EventMessage* message) {
|
||||
lockMutex();
|
||||
for (auto iter = listenerList.begin(); iter != listenerList.end(); ++iter) {
|
||||
if (iter->second.match(message)) {
|
||||
MessageQueueSenderIF::sendMessage(iter->first, message, message->getSender());
|
||||
for (auto& listener : listenerList) {
|
||||
if (listener.second.match(message)) {
|
||||
ReturnValue_t result =
|
||||
MessageQueueSenderIF::sendMessage(listener.first, message, message->getSender());
|
||||
if (result != returnvalue::OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << std::hex << "EventManager::notifyListeners: MSG to 0x" << std::setfill('0')
|
||||
<< std::setw(8) << listener.first << " failed with result 0x" << std::setw(4)
|
||||
<< result << std::setfill(' ') << std::endl;
|
||||
#else
|
||||
sif::printError("Sending message to listener 0x%08x failed with result %04x\n",
|
||||
listener.first, result);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
unlockMutex();
|
||||
@ -200,4 +212,19 @@ void EventManager::printUtility(sif::OutputTypes printType, EventMessage* messag
|
||||
}
|
||||
}
|
||||
|
||||
void EventManager::printListeners() {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::info << "Event manager listener MQ IDs:" << std::setfill('0') << std::hex << std::endl;
|
||||
for (auto& listener : listenerList) {
|
||||
sif::info << "0x" << std::setw(8) << listener.first << std::endl;
|
||||
}
|
||||
sif::info << std::dec << std::setfill(' ');
|
||||
#else
|
||||
sif::printInfo("Event manager listener MQ IDs:\n");
|
||||
for (auto& listener : listenerList) {
|
||||
sif::printInfo("0x%08x\n", listener.first);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* FSFW_OBJ_EVENT_TRANSLATION == 1 */
|
||||
|
@ -21,9 +21,7 @@ extern const char* translateEvents(Event event);
|
||||
|
||||
class EventManager : public EventManagerIF, public ExecutableObjectIF, public SystemObject {
|
||||
public:
|
||||
static const uint16_t MAX_EVENTS_PER_CYCLE = 80;
|
||||
|
||||
EventManager(object_id_t setObjectId);
|
||||
EventManager(object_id_t setObjectId, uint32_t eventQueueDepth);
|
||||
virtual ~EventManager();
|
||||
|
||||
void setMutexTimeout(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs);
|
||||
@ -44,6 +42,7 @@ class EventManager : public EventManagerIF, public ExecutableObjectIF, public Sy
|
||||
object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
|
||||
bool reporterInverted = false);
|
||||
ReturnValue_t performOperation(uint8_t opCode);
|
||||
void printListeners();
|
||||
|
||||
protected:
|
||||
MessageQueueIF* eventReportQueue = nullptr;
|
||||
|
@ -10,7 +10,7 @@ enum : uint8_t {
|
||||
CDH = 28,
|
||||
TCS_1 = 59,
|
||||
PCDU_1 = 42,
|
||||
PCDU_2 = 43,
|
||||
POWER_SWITCH_IF = 43,
|
||||
HEATER = 50,
|
||||
T_SENSORS = 52,
|
||||
FDIR = 70,
|
||||
@ -33,6 +33,7 @@ enum : uint8_t {
|
||||
PUS_SERVICE_23 = 103,
|
||||
MGM_LIS3MDL = 106,
|
||||
MGM_RM3100 = 107,
|
||||
CFDP = 108,
|
||||
|
||||
FW_SUBSYSTEM_ID_RANGE
|
||||
};
|
||||
|
@ -44,13 +44,13 @@ class Type : public SerializeIF {
|
||||
|
||||
static ActualType_t getActualType(uint8_t ptc, uint8_t pfc);
|
||||
|
||||
virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
virtual size_t getSerializedSize() const override;
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override;
|
||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
private:
|
||||
ActualType_t actualType;
|
||||
|
@ -54,8 +54,8 @@ class HousekeepingSnapshot : public SerializeIF {
|
||||
HousekeepingSnapshot(uint8_t* timeStamp, size_t timeStampSize, LocalPoolObjectBase* dataSetPtr)
|
||||
: timeStamp(timeStamp), timeStampSize(timeStampSize), updateData(dataSetPtr){};
|
||||
|
||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
if (timeStamp != nullptr) {
|
||||
/* Endianness will always be MACHINE, so we can simply use memcpy
|
||||
here. */
|
||||
@ -70,15 +70,15 @@ class HousekeepingSnapshot : public SerializeIF {
|
||||
return updateData->serialize(buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
|
||||
virtual size_t getSerializedSize() const {
|
||||
size_t getSerializedSize() const {
|
||||
if (updateData == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
return timeStampSize + updateData->getSerializedSize();
|
||||
}
|
||||
|
||||
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
SerializeIF::Endianness streamEndianness) override {
|
||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
SerializeIF::Endianness streamEndianness) override {
|
||||
if (*size < timeStampSize) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
|
@ -32,9 +32,9 @@ class AbsLimitMonitor : public MonitorBase<T> {
|
||||
return returnvalue::OK; // We're not out of range.
|
||||
}
|
||||
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex) {
|
||||
ReturnValue_t getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues,
|
||||
uint16_t startAtIndex) override {
|
||||
ReturnValue_t result = this->MonitorBase<T>::getParameter(
|
||||
domainId, parameterId, parameterWrapper, newValues, startAtIndex);
|
||||
// We'll reuse the DOMAIN_ID of MonitorReporter,
|
||||
|
@ -13,6 +13,7 @@ class MonitoringMessage : public CommandMessage {
|
||||
static const Command_t LIMIT_VIOLATION_REPORT = MAKE_COMMAND_ID(10);
|
||||
virtual ~MonitoringMessage();
|
||||
static void setLimitViolationReport(CommandMessage* message, store_address_t storeId);
|
||||
using CommandMessage::clear;
|
||||
static void clear(CommandMessage* message);
|
||||
static store_address_t getStoreId(const CommandMessage* message);
|
||||
static void setTypicalMessage(CommandMessage* message, Command_t type, store_address_t storeId);
|
||||
|
@ -15,6 +15,7 @@ enum framework_objects : object_id_t {
|
||||
PUS_SERVICE_8_FUNCTION_MGMT = 0x53000008,
|
||||
PUS_SERVICE_9_TIME_MGMT = 0x53000009,
|
||||
PUS_SERVICE_11_TC_SCHEDULER = 0x53000011,
|
||||
PUS_SERVICE_15_TM_STORAGE = 0x53000015,
|
||||
PUS_SERVICE_17_TEST = 0x53000017,
|
||||
PUS_SERVICE_20_PARAMETERS = 0x53000020,
|
||||
PUS_SERVICE_200_MODE_MGMT = 0x53000200,
|
||||
|
@ -40,6 +40,8 @@ int TcpIpBase::closeSocket(socket_t socket) {
|
||||
return closesocket(socket);
|
||||
#elif defined(PLATFORM_UNIX)
|
||||
return close(socket);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -48,5 +50,7 @@ int TcpIpBase::getLastSocketError() {
|
||||
return WSAGetLastError();
|
||||
#elif defined(PLATFORM_UNIX)
|
||||
return errno;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
@ -16,9 +16,9 @@
|
||||
|
||||
#endif
|
||||
|
||||
TcpTmTcBridge::TcpTmTcBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId,
|
||||
object_id_t tcStoreId)
|
||||
: TmTcBridge("TCP TMTC Bridge", objectId, tcDestination, tmStoreId, tcStoreId) {
|
||||
TcpTmTcBridge::TcpTmTcBridge(object_id_t objectId, object_id_t tcDestination,
|
||||
uint32_t msgQueueDepth, object_id_t tmStoreId, object_id_t tcStoreId)
|
||||
: TmTcBridge("TCP TMTC Bridge", objectId, tcDestination, msgQueueDepth, tmStoreId, tcStoreId) {
|
||||
mutex = MutexFactory::instance()->createMutex();
|
||||
// Connection is always up, TM is requested by connecting to server and receiving packets
|
||||
registerCommConnect();
|
||||
|
@ -38,7 +38,7 @@ class TcpTmTcBridge : public TmTcBridge {
|
||||
* @param tmStoreId TM store object ID. It is recommended to the default object ID
|
||||
* @param tcStoreId TC store object ID. It is recommended to the default object ID
|
||||
*/
|
||||
TcpTmTcBridge(object_id_t objectId, object_id_t tcDestination,
|
||||
TcpTmTcBridge(object_id_t objectId, object_id_t tcDestination, uint32_t msgQueueDepth,
|
||||
object_id_t tmStoreId = objects::TM_STORE,
|
||||
object_id_t tcStoreId = objects::TC_STORE);
|
||||
virtual ~TcpTmTcBridge();
|
||||
|
@ -20,9 +20,9 @@
|
||||
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,
|
||||
object_id_t tcStoreId)
|
||||
: TmTcBridge("UDP TMTC Bridge", objectId, tcDestination, tmStoreId, tcStoreId) {
|
||||
uint32_t msgQueueDepth, const std::string &udpServerPort_,
|
||||
object_id_t tmStoreId, object_id_t tcStoreId)
|
||||
: TmTcBridge("UDP TMTC Bridge", objectId, tcDestination, msgQueueDepth, tmStoreId, tcStoreId) {
|
||||
if (udpServerPort_.empty()) {
|
||||
udpServerPort = DEFAULT_SERVER_PORT;
|
||||
} else {
|
||||
@ -126,10 +126,7 @@ ReturnValue_t UdpTmTcBridge::sendTm(const uint8_t *data, size_t dataLen) {
|
||||
tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::SENDTO_CALL);
|
||||
}
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1
|
||||
sif::debug << "TmTcUdpBridge::sendTm: " << bytesSent
|
||||
<< " bytes were"
|
||||
" sent."
|
||||
<< std::endl;
|
||||
sif::debug << "TmTcUdpBridge::sendTm: " << bytesSent << " bytes were sent" << std::endl;
|
||||
#endif
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ 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,
|
||||
UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, uint32_t msgQueueDepth,
|
||||
const std::string& udpServerPort = "", object_id_t tmStoreId = objects::TM_STORE,
|
||||
object_id_t tcStoreId = objects::TC_STORE);
|
||||
~UdpTmTcBridge() override;
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <condition_variable>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "fsfw/objectmanager/ObjectManagerIF.h"
|
||||
#include "fsfw/tasks/FixedSlotSequence.h"
|
||||
|