Compare commits
175 Commits
mueller/re
...
mohr/dhb2n
Author | SHA1 | Date | |
---|---|---|---|
f805667779 | |||
bddc7a7ca6 | |||
11a22577be | |||
94f1f1f908 | |||
955579c856 | |||
c6585c8645 | |||
d8a4675842 | |||
1164c21ddd | |||
77b1a85b47 | |||
f3e9277e59 | |||
d592f1ecbc | |||
6ec18171a8 | |||
518dcdef4b | |||
d9730032fd | |||
b3ac72b7db | |||
cd0cb43412 | |||
32c12b3dbf | |||
3e9acf476e | |||
99101ce2bf | |||
6b991045f7 | |||
337cb0d6c9 | |||
c283e0c988 | |||
448d20f3bd | |||
2316728d74 | |||
6f562e5f3e | |||
176f243194 | |||
d964fa2107 | |||
7b5ae6a445 | |||
8e362a000c | |||
7877776e24 | |||
3de0ae5a48 | |||
95ac53c417 | |||
62f638a3d2 | |||
bd64591f30 | |||
e6a877f048 | |||
ea8c557ee8 | |||
0bdd780f82 | |||
9ec397c8b7 | |||
c54d9d7ba6 | |||
30c03c110c | |||
69f1be263a | |||
c7b5309dcb | |||
775d5632de | |||
4f3361eb2b | |||
9e6c1d60e5 | |||
12d0c23c13 | |||
5c3bb13834 | |||
292fe3e5e4 | |||
33530f2819 | |||
c0000a8635 | |||
5488ee715f | |||
0fea22d031 | |||
3b8ca09299 | |||
9a2146fa2d | |||
558550ecb9 | |||
72172a972b | |||
b4b11ebd3b | |||
bcbbc9763a | |||
0042372cb6 | |||
8dea13742f | |||
0f027d29d2 | |||
131e3ff1e3 | |||
423a9540ed | |||
ce7146e468 | |||
a681a4a797 | |||
83b7b8707c | |||
4002b74ea2 | |||
1a833e2d45 | |||
8df6d934d7 | |||
5363868120 | |||
8501477a78 | |||
6eea711d9f | |||
9a181aa6a8 | |||
655c944c0e | |||
2e310fca8d | |||
37390dfc74 | |||
1efc0d2855 | |||
237e29cc59 | |||
0849c8a08d | |||
9d626e0a5d | |||
0ce568ad26 | |||
6970068d56 | |||
af282c7d3e | |||
21a9d89fb3 | |||
3257935150 | |||
f34cf9095d | |||
24ecf125a3 | |||
6451a16888 | |||
fa5605c959 | |||
8e835be55f | |||
9bd600c488 | |||
9c7248e78e | |||
ecf51b2913 | |||
8bbde05413 | |||
d79b5348d8 | |||
92e3ab04f3 | |||
003a6d00fa | |||
9ee1896553 | |||
a5b5523111 | |||
62cd39e573 | |||
278ed36db8 | |||
aed30d54ef | |||
1126db2c8a | |||
a64a04d7fe | |||
80467bf097 | |||
6a6aa7fdd6 | |||
7e379d2159 | |||
6ae709acc3 | |||
d52f335455 | |||
04b619a15c | |||
282704e0fd | |||
07ef9a0ec3 | |||
80464f2a81 | |||
16688316a8 | |||
3583e30ee6 | |||
1e395dc402 | |||
f5421e9abd | |||
4c3f9feb93 | |||
b7ed8ff390 | |||
75dc7a405d | |||
b7a1f79d5b | |||
f0b7a103d4 | |||
ee93f4a4ca | |||
d64ad71529 | |||
26bc80964e | |||
eb03bf52a6 | |||
80355910ee | |||
04800df31e | |||
1e85cdadfd | |||
ebc02673dd | |||
9202c6c17f | |||
5f8c549993 | |||
04bff7a522 | |||
5c20cc804e | |||
eb8e236cd4 | |||
7dec45ccf2 | |||
2b01e86f9c | |||
60fd3d43c0 | |||
67980cb592 | |||
3010f2f925 | |||
01651f0521 | |||
c7f300671f | |||
7d3223d766 | |||
7ae82a5cb4 | |||
28ecd0e5c6 | |||
7345c18b04 | |||
158007fa7f | |||
ab719a3e59 | |||
64a7fde301 | |||
9131ca688b | |||
8e6cee7761 | |||
c756297e5c | |||
0f27c7e7e7 | |||
20d42add03 | |||
a9277622ce | |||
aea9db75cb | |||
9fedd03ed8 | |||
10fc4dd89d | |||
0cc8af5eb0 | |||
92d65aa3a5 | |||
342a56410c | |||
2cab73d972 | |||
cb23911ccd | |||
b499dedd76 | |||
1bb487373d | |||
3bffb4f968 | |||
6bcb208968 | |||
6c2b5ab39e | |||
a7039bad41 | |||
6605ffb6b1 | |||
e2e0190cae | |||
fd278e410b | |||
ff4cbea571 | |||
a46d8c34d9 | |||
ba5c6410d6 |
37
CHANGELOG.md
37
CHANGELOG.md
@ -10,7 +10,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
|
|
||||||
# [v6.0.0]
|
# [v6.0.0]
|
||||||
|
|
||||||
## Changes
|
## Fixes
|
||||||
|
|
||||||
|
- I2C Bugfixes: Do not keep iterator as member and fix some incorrect handling with the iterator.
|
||||||
|
Also properly reset the reply size for successfull transfers and erroneous transfers.
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/700
|
||||||
|
- Bugfix for Serial Buffer Stream: Setting `doActive` to false now
|
||||||
|
actually fully disables printing.
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/680
|
||||||
|
- `TcpTmTcServer.cpp`: The server was actually not able to handle
|
||||||
|
CCSDS packets which were clumped together. This has been fixed now.
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/673
|
||||||
|
|
||||||
## Added
|
## Added
|
||||||
|
|
||||||
@ -19,6 +29,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
|
|
||||||
## Changes
|
## Changes
|
||||||
|
|
||||||
|
- Remove default secondary header argument for
|
||||||
|
`uint16_t getTcSpacePacketIdFromApid(uint16_t apid, bool secondaryHeaderFlag)` and
|
||||||
|
`uint16_t getTmSpacePacketIdFromApid(uint16_t apid, bool secondaryHeaderFlag)`
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/689
|
||||||
- Removed `HasReturnvaluesIF` class in favor of `returnvalue` namespace with `OK` and `FAILED`
|
- Removed `HasReturnvaluesIF` class in favor of `returnvalue` namespace with `OK` and `FAILED`
|
||||||
constants.
|
constants.
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/659
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/659
|
||||||
@ -26,6 +40,27 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
for other modules
|
for other modules
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/655
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/655
|
||||||
which also includes a migration guide
|
which also includes a migration guide
|
||||||
|
- Bump Catch2 dependency to regular version `v3.1.0`
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/678
|
||||||
|
- `SerialBufferAdapter`: Rename `setBuffer` to `setConstBuffer` and update
|
||||||
|
API to expect `const uint8_t*` accordingly.
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/677
|
||||||
|
- Remove the following user includes from `fsfw/events/Event.h` and
|
||||||
|
`fsfw/returnvalues/returnvalue.h`:
|
||||||
|
- `#include "events/subsystemIdRanges.h"`
|
||||||
|
- `#include "returnvalues/classIds.h"`
|
||||||
|
The user has to include those themselves now
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/675
|
||||||
|
- `DeviceHandlerBase`: Set command sender before calling `buildCommandFromCommand`.
|
||||||
|
This allows finishing action commands immediately inside the function.
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/672
|
||||||
|
- `DeviceHandlerBase`: New signature of `handleDeviceTm` which expects
|
||||||
|
a `const SerializeIF&` and additional helper variant which expects `const uint8_t*`
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/671
|
||||||
|
- Improvements for `AcceptsTelemetryIF` and `AcceptsTelecommandsIF`:
|
||||||
|
- Make functions `const` where it makes sense
|
||||||
|
- Add `const char* getName const` abstract function
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/684
|
||||||
|
|
||||||
# [v5.0.0] 25.07.2022
|
# [v5.0.0] 25.07.2022
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ set(FSFW_CATCH2_LIB_MAJOR_VERSION
|
|||||||
3
|
3
|
||||||
CACHE STRING "Catch2 library major version requirement")
|
CACHE STRING "Catch2 library major version requirement")
|
||||||
set(FSFW_CATCH2_LIB_VERSION
|
set(FSFW_CATCH2_LIB_VERSION
|
||||||
v${FSFW_CATCH2_LIB_MAJOR_VERSION}.0.0-preview5
|
v${FSFW_CATCH2_LIB_MAJOR_VERSION}.1.0
|
||||||
CACHE STRING "Catch2 library exact version requirement")
|
CACHE STRING "Catch2 library exact version requirement")
|
||||||
|
|
||||||
# Keep this off by default for now. See PR:
|
# Keep this off by default for now. See PR:
|
||||||
@ -326,7 +326,8 @@ if(FSFW_BUILD_TESTS)
|
|||||||
"/usr/local/include/*"
|
"/usr/local/include/*"
|
||||||
"*/fsfw_tests/*"
|
"*/fsfw_tests/*"
|
||||||
"*/catch2-src/*"
|
"*/catch2-src/*"
|
||||||
"*/fsfw_hal/*")
|
"*/fsfw_hal/*"
|
||||||
|
"unittests/*")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_options(${FSFW_TEST_TGT} PRIVATE -fprofile-arcs
|
target_link_options(${FSFW_TEST_TGT} PRIVATE -fprofile-arcs
|
||||||
@ -344,8 +345,15 @@ if(FSFW_BUILD_TESTS)
|
|||||||
DEPENDENCIES ${FSFW_TEST_TGT})
|
DEPENDENCIES ${FSFW_TEST_TGT})
|
||||||
else()
|
else()
|
||||||
setup_target_for_coverage_lcov(
|
setup_target_for_coverage_lcov(
|
||||||
NAME ${FSFW_TEST_TGT}_coverage EXECUTABLE ${FSFW_TEST_TGT}
|
NAME
|
||||||
DEPENDENCIES ${FSFW_TEST_TGT})
|
${FSFW_TEST_TGT}_coverage
|
||||||
|
EXECUTABLE
|
||||||
|
${FSFW_TEST_TGT}
|
||||||
|
DEPENDENCIES
|
||||||
|
${FSFW_TEST_TGT}
|
||||||
|
GENHTML_ARGS
|
||||||
|
--html-epilog
|
||||||
|
${CMAKE_SOURCE_DIR}/unittests/lcov_epilog.html)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
@ -360,7 +368,8 @@ if(NOT FSFW_CONFIG_PATH)
|
|||||||
if(NOT FSFW_BUILD_DOCS)
|
if(NOT FSFW_BUILD_DOCS)
|
||||||
message(
|
message(
|
||||||
WARNING
|
WARNING
|
||||||
"${MSG_PREFIX} Flight Software Framework configuration path not set")
|
"${MSG_PREFIX} Flight Software Framework configuration path FSFW_CONFIG_PATH not set"
|
||||||
|
)
|
||||||
message(
|
message(
|
||||||
WARNING
|
WARNING
|
||||||
"${MSG_PREFIX} Setting default configuration from ${DEF_CONF_PATH} ..")
|
"${MSG_PREFIX} Setting default configuration from ${DEF_CONF_PATH} ..")
|
||||||
|
@ -175,7 +175,7 @@ cmake -DFSFW_BUILD_DOCS=ON -DFSFW_OSAL=host ..
|
|||||||
Then you can generate the documentation using
|
Then you can generate the documentation using
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cmake --build . -j
|
cmake --build . -- Sphinx -j
|
||||||
```
|
```
|
||||||
|
|
||||||
You can find the generated documentation inside the `docs/sphinx` folder inside the build
|
You can find the generated documentation inside the `docs/sphinx` folder inside the build
|
||||||
|
@ -5,16 +5,25 @@ RUN apt-get --yes upgrade
|
|||||||
|
|
||||||
#tzdata is a dependency, won't install otherwise
|
#tzdata is a dependency, won't install otherwise
|
||||||
ARG DEBIAN_FRONTEND=noninteractive
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
RUN apt-get --yes install gcc g++ cmake make lcov git valgrind nano iputils-ping
|
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
|
||||||
|
|
||||||
RUN git clone https://github.com/catchorg/Catch2.git && \
|
RUN git clone https://github.com/catchorg/Catch2.git && \
|
||||||
cd Catch2 && \
|
cd Catch2 && \
|
||||||
git checkout v3.0.0-preview5 && \
|
git checkout v3.1.0 && \
|
||||||
cmake -Bbuild -H. -DBUILD_TESTING=OFF && \
|
cmake -Bbuild -H. -DBUILD_TESTING=OFF && \
|
||||||
cmake --build build/ --target install
|
cmake --build build/ --target install
|
||||||
|
|
||||||
RUN git clone https://github.com/ETLCPP/etl.git && \
|
RUN git clone https://github.com/ETLCPP/etl.git && \
|
||||||
cd etl && \
|
cd etl && \
|
||||||
git checkout 20.28.0 && \
|
git checkout 20.28.0 && \
|
||||||
cmake -B build . && \
|
cmake -B build . && \
|
||||||
cmake --install build/
|
cmake --install build/
|
||||||
|
|
||||||
|
#ssh needs a valid user to work
|
||||||
|
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
|
44
automation/Jenkinsfile
vendored
44
automation/Jenkinsfile
vendored
@ -1,9 +1,13 @@
|
|||||||
pipeline {
|
pipeline {
|
||||||
environment {
|
environment {
|
||||||
BUILDDIR = 'cmake-build-tests'
|
BUILDDIR = 'cmake-build-tests'
|
||||||
|
DOCDDIR = 'cmake-build-documentation'
|
||||||
}
|
}
|
||||||
agent {
|
agent {
|
||||||
docker { image 'fsfw-ci:d3'}
|
docker {
|
||||||
|
image 'fsfw-ci:d6'
|
||||||
|
args '--network host'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stages {
|
stages {
|
||||||
stage('Clean') {
|
stage('Clean') {
|
||||||
@ -39,5 +43,43 @@ pipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stage('Documentation') {
|
||||||
|
when {
|
||||||
|
branch 'development'
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
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'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dir(BUILDDIR) {
|
||||||
|
sshagent(credentials: ['documentation-buildfix']) {
|
||||||
|
sh 'rsync -r --delete fsfw-tests_coverage/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/coverage/development'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Master Documentation') {
|
||||||
|
when {
|
||||||
|
branch 'master'
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
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'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dir(BUILDDIR) {
|
||||||
|
sshagent(credentials: ['documentation-buildfix']) {
|
||||||
|
sh 'rsync -r --delete fsfw-tests_coverage/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/coverage/master'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
Configuring the FSFW
|
|
||||||
======
|
|
||||||
|
|
||||||
The FSFW can be configured via the `fsfwconfig` folder. A template folder has
|
|
||||||
been provided to have a starting point for this. The folder should be added
|
|
||||||
to the include path. The primary configuration file is the `FSFWConfig.h` folder. Some
|
|
||||||
of the available options will be explained in more detail here.
|
|
||||||
|
|
||||||
# Auto-Translation of Events
|
|
||||||
|
|
||||||
The FSFW allows the automatic translation of events, which allows developers to track triggered
|
|
||||||
events directly via console output. Using this feature requires:
|
|
||||||
|
|
||||||
1. `FSFW_OBJ_EVENT_TRANSLATION` set to 1 in the configuration file.
|
|
||||||
2. Special auto-generated translation files which translate event IDs and object IDs into
|
|
||||||
human readable strings. These files can be generated using the
|
|
||||||
[modgen Python scripts](https://git.ksat-stuttgart.de/source/modgen.git).
|
|
||||||
3. The generated translation files for the object IDs should be named `translatesObjects.cpp`
|
|
||||||
and `translateObjects.h` and should be copied to the `fsfwconfig/objects` folder
|
|
||||||
4. The generated translation files for the event IDs should be named `translateEvents.cpp` and
|
|
||||||
`translateEvents.h` and should be copied to the `fsfwconfig/events` folder
|
|
||||||
|
|
||||||
An example implementations of these translation file generators can be found as part
|
|
||||||
of the [SOURCE project here](https://git.ksat-stuttgart.de/source/sourceobsw/-/tree/development/generators)
|
|
||||||
or the [FSFW example](https://egit.irs.uni-stuttgart.de/fsfw/fsfw_example_public/src/branch/master/generators)
|
|
||||||
|
|
||||||
## Configuring the Event Manager
|
|
||||||
|
|
||||||
The number of allowed subscriptions can be modified with the following
|
|
||||||
parameters:
|
|
||||||
|
|
||||||
``` c++
|
|
||||||
namespace fsfwconfig {
|
|
||||||
//! Configure the allocated pool sizes for the event manager.
|
|
||||||
static constexpr size_t FSFW_EVENTMGMR_MATCHTREE_NODES = 240;
|
|
||||||
static constexpr size_t FSFW_EVENTMGMT_EVENTIDMATCHERS = 120;
|
|
||||||
static constexpr size_t FSFW_EVENTMGMR_RANGEMATCHERS = 120;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
@ -1 +0,0 @@
|
|||||||
## Controllers
|
|
@ -1,55 +0,0 @@
|
|||||||
## FSFW Core Modules
|
|
||||||
|
|
||||||
These core modules provide the most important functionalities of the
|
|
||||||
Flight Software Framework
|
|
||||||
|
|
||||||
### Clock
|
|
||||||
|
|
||||||
* This is a class of static functions that can be used at anytime
|
|
||||||
* Leap Seconds must be set if any time conversions from UTC to other times is used
|
|
||||||
|
|
||||||
### ObjectManager
|
|
||||||
|
|
||||||
* Must be created during program startup
|
|
||||||
* The component which handles all references. All SystemObjects register at this component.
|
|
||||||
* Any SystemObject needs to have a unique ObjectId. Those can be managed like objects::framework_objects.
|
|
||||||
* A reference to an object can be get by calling the following function. T must be the specific Interface you want to call.
|
|
||||||
A nullptr check of the returning Pointer must be done. This function is based on Run-time type information.
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
template <typename T> T* ObjectManagerIF::get( object_id_t id )
|
|
||||||
```
|
|
||||||
* A typical way to create all objects on startup is a handing a static produce function to the
|
|
||||||
ObjectManager on creation. By calling objectManager->initialize() the produce function will be
|
|
||||||
called and all SystemObjects will be initialized afterwards.
|
|
||||||
|
|
||||||
### Event Manager
|
|
||||||
|
|
||||||
* Component which allows routing of events
|
|
||||||
* Other objects can subscribe to specific events, ranges of events or all events of an object.
|
|
||||||
* Subscriptions can be done during runtime but should be done during initialization
|
|
||||||
* Amounts of allowed subscriptions can be configured in `FSFWConfig.h`
|
|
||||||
|
|
||||||
### Health Table
|
|
||||||
|
|
||||||
* A component which holds every health state
|
|
||||||
* Provides a thread safe way to access all health states without the need of message exchanges
|
|
||||||
|
|
||||||
### Stores
|
|
||||||
|
|
||||||
* The message based communication can only exchange a few bytes of information inside the message
|
|
||||||
itself. Therefore, additional information can be exchanged with Stores. With this, only the
|
|
||||||
store address must be exchanged in the message.
|
|
||||||
* Internally, the FSFW uses an IPC Store to exchange data between processes. For incoming TCs a TC
|
|
||||||
Store is used. For outgoing TM a TM store is used.
|
|
||||||
* All of them should use the Thread Safe Class storagemanager/PoolManager
|
|
||||||
|
|
||||||
### Tasks
|
|
||||||
|
|
||||||
There are two different types of tasks:
|
|
||||||
* The PeriodicTask just executes objects that are of type ExecutableObjectIF in the order of the
|
|
||||||
insertion to the Tasks.
|
|
||||||
* FixedTimeslotTask executes a list of calls in the order of the given list. This is intended for
|
|
||||||
DeviceHandlers, where polling should be in a defined order. An example can be found in
|
|
||||||
`defaultcfg/fsfwconfig/pollingSequence` folder
|
|
||||||
|
|
@ -1 +0,0 @@
|
|||||||
## Device Handlers
|
|
@ -1,135 +0,0 @@
|
|||||||
High-level overview
|
|
||||||
======
|
|
||||||
|
|
||||||
# Structure
|
|
||||||
|
|
||||||
The general structure is driven by the usage of interfaces provided by objects.
|
|
||||||
The FSFW uses C++11 as baseline. The intention behind this is that this C++ Standard should be
|
|
||||||
widely available, even with older compilers.
|
|
||||||
The FSFW uses dynamic allocation during the initialization but provides static containers during runtime.
|
|
||||||
This simplifies the instantiation of objects and allows the usage of some standard containers.
|
|
||||||
Dynamic Allocation after initialization is discouraged and different solutions are provided in the
|
|
||||||
FSFW to achieve that. The fsfw uses run-time type information but exceptions are not allowed.
|
|
||||||
|
|
||||||
# Failure Handling
|
|
||||||
|
|
||||||
Functions should return a defined `ReturnValue_t` to signal to the caller that something has
|
|
||||||
gone wrong. Returnvalues must be unique. For this the function `returnvalue::makeCode`
|
|
||||||
or the macro `MAKE_RETURN` can be used. The `CLASS_ID` is a unique id for that type of object.
|
|
||||||
See `returnvalues/FwClassIds` folder. The user can add custom `CLASS_ID`s via the
|
|
||||||
`fsfwconfig` folder.
|
|
||||||
|
|
||||||
# OSAL
|
|
||||||
|
|
||||||
The FSFW provides operation system abstraction layers for Linux, FreeRTOS and RTEMS.
|
|
||||||
The OSAL provides periodic tasks, message queues, clocks and semaphores as well as mutexes.
|
|
||||||
The [OSAL README](doc/README-osal.md#top) provides more detailed information on provided components
|
|
||||||
and how to use them.
|
|
||||||
|
|
||||||
# Core Components
|
|
||||||
|
|
||||||
The FSFW has following core components. More detailed informations can be found in the
|
|
||||||
[core component section](doc/README-core.md#top):
|
|
||||||
|
|
||||||
1. Tasks: Abstraction for different (periodic) task types like periodic tasks or tasks
|
|
||||||
with fixed timeslots
|
|
||||||
2. ObjectManager: This module stores all `SystemObjects` by mapping a provided unique object ID
|
|
||||||
to the object handles.
|
|
||||||
3. Static Stores: Different stores are provided to store data of variable size (like telecommands
|
|
||||||
or small telemetry) in a pool structure without using dynamic memory allocation.
|
|
||||||
These pools are allocated up front.
|
|
||||||
3. Clock: This module provided common time related functions
|
|
||||||
4. EventManager: This module allows routing of events generated by `SystemObjects`
|
|
||||||
5. HealthTable: A component which stores the health states of objects
|
|
||||||
|
|
||||||
# Static IDs in the framework
|
|
||||||
|
|
||||||
Some parts of the framework use a static routing address for communication.
|
|
||||||
An example setup of ids can be found in the example config in `defaultcft/fsfwconfig/objects`
|
|
||||||
inside the function `Factory::setStaticFrameworkObjectIds()`.
|
|
||||||
|
|
||||||
# Events
|
|
||||||
|
|
||||||
Events are tied to objects. EventIds can be generated by calling the Macro MAKE_EVENT.
|
|
||||||
This works analog to the returnvalues. Every object that needs own EventIds has to get a
|
|
||||||
unique SUBSYSTEM_ID. Every SystemObject can call triggerEvent from the parent class.
|
|
||||||
Therefore, event messages contain the specific EventId and the objectId of the object that
|
|
||||||
has triggered.
|
|
||||||
|
|
||||||
# Internal Communication
|
|
||||||
|
|
||||||
Components communicate mostly via Messages through Queues.
|
|
||||||
Those queues are created by calling the singleton `QueueFactory::instance()->create()` which
|
|
||||||
will create `MessageQueue` instances for the used OSAL.
|
|
||||||
|
|
||||||
# External Communication
|
|
||||||
|
|
||||||
The external communication with the mission control system is mostly up to the user implementation.
|
|
||||||
The FSFW provides PUS Services which can be used to but don't need to be used.
|
|
||||||
The services can be seen as a conversion from a TC to a message based communication and back.
|
|
||||||
|
|
||||||
## TMTC Communication
|
|
||||||
|
|
||||||
The FSFW provides some components to facilitate TMTC handling via the PUS commands.
|
|
||||||
For example, a UDP or TCP PUS server socket can be opened on a specific port using the
|
|
||||||
files located in `osal/common`. The FSFW example uses this functionality to allow sending telecommands
|
|
||||||
and receiving telemetry using the [TMTC commander application](https://github.com/spacefisch/tmtccmd).
|
|
||||||
Simple commands like the PUS Service 17 ping service can be tested by simply running the
|
|
||||||
`tmtc_client_cli.py` or `tmtc_client_gui.py` utility in
|
|
||||||
the [example tmtc folder](https://egit.irs.uni-stuttgart.de/fsfw/fsfw_example_public/src/branch/master/tmtc)
|
|
||||||
while the `fsfw_example` application is running.
|
|
||||||
|
|
||||||
More generally, any class responsible for handling incoming telecommands and sending telemetry
|
|
||||||
can implement the generic `TmTcBridge` class located in `tmtcservices`. Many applications
|
|
||||||
also use a dedicated polling task for reading telecommands which passes telecommands
|
|
||||||
to the `TmTcBridge` implementation.
|
|
||||||
|
|
||||||
## CCSDS Frames, CCSDS Space Packets and PUS
|
|
||||||
|
|
||||||
If the communication is based on CCSDS Frames and Space Packets, several classes can be used to
|
|
||||||
distributed the packets to the corresponding services. Those can be found in `tcdistribution`.
|
|
||||||
If Space Packets are used, a timestamper has to be provided by the user.
|
|
||||||
An example can be found in the `timemanager` folder, which uses `CCSDSTime::CDS_short`.
|
|
||||||
|
|
||||||
# Device Handlers
|
|
||||||
|
|
||||||
DeviceHandlers are another important component of the FSFW.
|
|
||||||
The idea is, to have a software counterpart of every physical device to provide a simple mode,
|
|
||||||
health and commanding interface. By separating the underlying Communication Interface with
|
|
||||||
`DeviceCommunicationIF`, a device handler (DH) can be tested on different hardware.
|
|
||||||
The DH has mechanisms to monitor the communication with the physical device which allow
|
|
||||||
for FDIR reaction. Device Handlers can be created by implementing `DeviceHandlerBase`.
|
|
||||||
A standard FDIR component for the DH will be created automatically but can
|
|
||||||
be overwritten by the user. More information on DeviceHandlers can be found in the
|
|
||||||
related [documentation section](doc/README-devicehandlers.md#top).
|
|
||||||
|
|
||||||
# Modes and Health
|
|
||||||
|
|
||||||
The two interfaces `HasModesIF` and `HasHealthIF` provide access for commanding and monitoring
|
|
||||||
of components. On-board Mode Management is implement in hierarchy system.
|
|
||||||
DeviceHandlers and Controllers are the lowest part of the hierarchy.
|
|
||||||
The next layer are Assemblies. Those assemblies act as a component which handle
|
|
||||||
redundancies of handlers. Assemblies share a common core with the next level which
|
|
||||||
are the Subsystems.
|
|
||||||
|
|
||||||
Those Assemblies are intended to act as auto-generated components from a database which describes
|
|
||||||
the subsystem modes. The definitions contain transition and target tables which contain the DH,
|
|
||||||
Assembly and Controller Modes to be commanded.
|
|
||||||
Transition tables contain as many steps as needed to reach the mode from any other mode, e.g. a
|
|
||||||
switch into any higher AOCS mode might first turn on the sensors, than the actuators and the
|
|
||||||
controller as last component.
|
|
||||||
The target table is used to describe the state that is checked continuously by the subsystem.
|
|
||||||
All of this allows System Modes to be generated as Subsystem object as well from the same database.
|
|
||||||
This System contains list of subsystem modes in the transition and target tables.
|
|
||||||
Therefore, it allows a modular system to create system modes and easy commanding of those, because
|
|
||||||
only the highest components must be commanded.
|
|
||||||
|
|
||||||
The health state represents if the component is able to perform its tasks.
|
|
||||||
This can be used to signal the system to avoid using this component instead of a redundant one.
|
|
||||||
The on-board FDIR uses the health state for isolation and recovery.
|
|
||||||
|
|
||||||
# Unit Tests
|
|
||||||
|
|
||||||
Unit Tests are provided in the unittest folder. Those use the catch2 framework but do not include
|
|
||||||
catch2 itself. More information on how to run these tests can be found in the separate
|
|
||||||
[`fsfw_tests` reposoitory](https://egit.irs.uni-stuttgart.de/fsfw/fsfw_tests)
|
|
@ -1,174 +0,0 @@
|
|||||||
## Local Data Pools Developer Information
|
|
||||||
|
|
||||||
The following text is targeted towards mission software developers which would like
|
|
||||||
to use the local data pools provided by the FSFW to store data like sensor values so they can be
|
|
||||||
used by other software objects like controllers as well. If a custom class should have a local
|
|
||||||
pool which can be used by other software objects as well, following steps have to be performed:
|
|
||||||
|
|
||||||
1. Create a `LocalDataPoolManager` member object in the custom class
|
|
||||||
2. Implement the `HasLocalDataPoolIF` with specifies the interface between the local pool manager
|
|
||||||
and the class owning the local pool.
|
|
||||||
|
|
||||||
The local data pool manager is also able to process housekeeping service requests in form
|
|
||||||
of messages, generate periodic housekeeping packet, generate notification and snapshots of changed
|
|
||||||
variables and datasets and process notifications and snapshots coming from other objects.
|
|
||||||
The two former tasks are related to the external interface using telemetry and telecommands (TMTC)
|
|
||||||
while the later two are related to data consumers like controllers only acting on data change
|
|
||||||
detected by the data creator instead of checking the data manually each cycle. Two important
|
|
||||||
framework classes `DeviceHandlerBase` and `ExtendedControllerBase` already perform the two steps
|
|
||||||
shown above so the steps required are altered slightly.
|
|
||||||
|
|
||||||
### Storing and Accessing pool data
|
|
||||||
|
|
||||||
The pool manager is responsible for thread-safe access of the pool data, but the actual
|
|
||||||
access to the pool data from the point of view of a mission software developer happens via proxy
|
|
||||||
classes like pool variable classes. These classes store a copy
|
|
||||||
of the pool variable with the matching datatype and copy the actual data from the local pool
|
|
||||||
on a `read` call. Changed variables can then be written to the local pool with a `commit` call.
|
|
||||||
The `read` and `commit` calls are thread-safe and can be called concurrently from data creators
|
|
||||||
and data consumers. Generally, a user will create a dataset class which in turn groups all
|
|
||||||
cohesive pool variables. These sets simply iterator over the list of variables and call the
|
|
||||||
`read` and `commit` functions of each variable. The following diagram shows the
|
|
||||||
high-level architecture of the local data pools.
|
|
||||||
|
|
||||||
.. image:: ../misc/logo/FSFW_Logo_V3_bw.png
|
|
||||||
:alt: FSFW Logo
|
|
||||||
|
|
||||||
|
|
||||||
An example is shown for using the local data pools with a Gyroscope.
|
|
||||||
For example, the following code shows an implementation to access data from a Gyroscope taken
|
|
||||||
from the SOURCE CubeSat project:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
class GyroPrimaryDataset: public StaticLocalDataSet<3 * sizeof(float)> {
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Constructor for data users
|
|
||||||
* @param gyroId
|
|
||||||
*/
|
|
||||||
GyroPrimaryDataset(object_id_t gyroId):
|
|
||||||
StaticLocalDataSet(sid_t(gyroId, gyrodefs::GYRO_DATA_SET_ID)) {
|
|
||||||
setAllVariablesReadOnly();
|
|
||||||
}
|
|
||||||
|
|
||||||
lp_var_t<float> angVelocityX = lp_var_t<float>(sid.objectId,
|
|
||||||
gyrodefs::ANGULAR_VELOCITY_X, this);
|
|
||||||
lp_var_t<float> angVelocityY = lp_var_t<float>(sid.objectId,
|
|
||||||
gyrodefs::ANGULAR_VELOCITY_Y, this);
|
|
||||||
lp_var_t<float> angVelocityZ = lp_var_t<float>(sid.objectId,
|
|
||||||
gyrodefs::ANGULAR_VELOCITY_Z, this);
|
|
||||||
private:
|
|
||||||
|
|
||||||
friend class GyroHandler;
|
|
||||||
/**
|
|
||||||
* Constructor for data creator
|
|
||||||
* @param hkOwner
|
|
||||||
*/
|
|
||||||
GyroPrimaryDataset(HasLocalDataPoolIF* hkOwner):
|
|
||||||
StaticLocalDataSet(hkOwner, gyrodefs::GYRO_DATA_SET_ID) {}
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
There is a public constructor for users which sets all variables to read-only and there is a
|
|
||||||
constructor for the GyroHandler data creator by marking it private and declaring the `GyroHandler`
|
|
||||||
as a friend class. Both the atittude controller and the `GyroHandler` can now
|
|
||||||
use the same class definition to access the pool variables with `read` and `commit` semantics
|
|
||||||
in a thread-safe way. Generally, each class requiring access will have the set class as a member
|
|
||||||
class. The data creator will also be generally a `DeviceHandlerBase` subclass and some additional
|
|
||||||
steps are necessary to expose the set for housekeeping purposes.
|
|
||||||
|
|
||||||
### Using the local data pools in a `DeviceHandlerBase` subclass
|
|
||||||
|
|
||||||
It is very common to store data generated by devices like a sensor into a pool which can
|
|
||||||
then be used by other objects. Therefore, the `DeviceHandlerBase` already has a
|
|
||||||
local pool. Using the aforementioned example, our `GyroHandler` will now have the set class
|
|
||||||
as a member:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
class GyroHandler: ... {
|
|
||||||
|
|
||||||
public:
|
|
||||||
...
|
|
||||||
private:
|
|
||||||
...
|
|
||||||
GyroPrimaryDataset gyroData;
|
|
||||||
...
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
The constructor used for the creators expects the owner class as a parameter, so we initialize
|
|
||||||
the object in the `GyroHandler` constructor like this:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
GyroHandler::GyroHandler(object_id_t objectId, object_id_t comIF,
|
|
||||||
CookieIF *comCookie, uint8_t switchId):
|
|
||||||
DeviceHandlerBase(objectId, comIF, comCookie), switchId(switchId),
|
|
||||||
gyroData(this) {}
|
|
||||||
```
|
|
||||||
|
|
||||||
We need to assign the set to a reply ID used in the `DeviceHandlerBase`.
|
|
||||||
The combination of the `GyroHandler` object ID and the reply ID will be the 64-bit structure ID
|
|
||||||
`sid_t` and is used to globally identify the set, for example when requesting housekeeping data or
|
|
||||||
generating update messages. We need to assign our custom set class in some way so that the local
|
|
||||||
pool manager can access the custom data sets as well.
|
|
||||||
By default, the `getDataSetHandle` will take care of this tasks. The default implementation for a
|
|
||||||
`DeviceHandlerBase` subclass will use the internal command map to retrieve
|
|
||||||
a handle to a dataset from a given reply ID. Therefore,
|
|
||||||
we assign the set in the `fillCommandAndReplyMap` function:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
void GyroHandler::fillCommandAndReplyMap() {
|
|
||||||
...
|
|
||||||
this->insertInCommandAndReplyMap(gyrodefs::GYRO_DATA, 3, &gyroData);
|
|
||||||
...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Now, we need to create the actual pool entries as well, using the `initializeLocalDataPool`
|
|
||||||
function. Here, we also immediately subscribe for periodic housekeeping packets
|
|
||||||
with an interval of 4 seconds. They are still disabled in this example and can be enabled
|
|
||||||
with a housekeeping service command.
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
ReturnValue_t GyroHandler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
|
||||||
LocalDataPoolManager &poolManager) {
|
|
||||||
localDataPoolMap.emplace(gyrodefs::ANGULAR_VELOCITY_X,
|
|
||||||
new PoolEntry<float>({0.0}));
|
|
||||||
localDataPoolMap.emplace(gyrodefs::ANGULAR_VELOCITY_Y,
|
|
||||||
new PoolEntry<float>({0.0}));
|
|
||||||
localDataPoolMap.emplace(gyrodefs::ANGULAR_VELOCITY_Z,
|
|
||||||
new PoolEntry<float>({0.0}));
|
|
||||||
localDataPoolMap.emplace(gyrodefs::GENERAL_CONFIG_REG42,
|
|
||||||
new PoolEntry<uint8_t>({0}));
|
|
||||||
localDataPoolMap.emplace(gyrodefs::RANGE_CONFIG_REG43,
|
|
||||||
new PoolEntry<uint8_t>({0}));
|
|
||||||
|
|
||||||
poolManager.subscribeForPeriodicPacket(gyroData.getSid(), false, 4.0, false);
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Now, if we receive some sensor data and converted them into the right format,
|
|
||||||
we can write it into the pool like this, using a guard class to ensure the set is commited back
|
|
||||||
in any case:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
PoolReadGuard readHelper(&gyroData);
|
|
||||||
if(readHelper.getReadResult() == returnvalue::OK) {
|
|
||||||
if(not gyroData.isValid()) {
|
|
||||||
gyroData.setValidity(true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
gyroData.angVelocityX = angularVelocityX;
|
|
||||||
gyroData.angVelocityY = angularVelocityY;
|
|
||||||
gyroData.angVelocityZ = angularVelocityZ;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The guard class will commit the changed data on destruction automatically.
|
|
||||||
|
|
||||||
### Using the local data pools in a `ExtendedControllerBase` subclass
|
|
||||||
|
|
||||||
Coming soon
|
|
||||||
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
|||||||
# Operating System Abstraction Layer (OSAL)
|
|
||||||
|
|
||||||
Some specific information on the provided OSALs are provided.
|
|
||||||
|
|
||||||
## Linux OSAL
|
|
||||||
|
|
||||||
This OSAL can be used to compile for Linux host systems like Ubuntu 20.04 or for
|
|
||||||
embedded Linux targets like the Raspberry Pi. This OSAL generally requires threading support
|
|
||||||
and real-time functionalities. For most UNIX systems, this is done by adding `-lrt` and `-lpthread` to the linked libraries in the compilation process. The CMake build support provided will do this automatically for the `fsfw` target. It should be noted that most UNIX systems need to be configured specifically to allow the real-time functionalities required by the FSFW.
|
|
||||||
|
|
||||||
More information on how to set up a Linux system accordingly can be found in the
|
|
||||||
[Linux README of the FSFW example application](https://egit.irs.uni-stuttgart.de/fsfw/fsfw_example/src/branch/master/doc/README-linux.md#top)
|
|
||||||
|
|
||||||
## Hosted OSAL
|
|
||||||
|
|
||||||
This is the newest OSAL. Support for Semaphores has not been implemented yet and will propably be implemented as soon as C++20 with Semaphore support has matured. This OSAL can be used to run the FSFW on any host system, but currently has only been tested on Windows 10 and Ubuntu 20.04. Unlike the other OSALs, it uses dynamic memory allocation (e.g. for the message queue implementation). Cross-platform serial port (USB) support might be added soon.
|
|
||||||
|
|
||||||
## FreeRTOS OSAL
|
|
||||||
|
|
||||||
FreeRTOS is not included and the developer needs to take care of compiling the FreeRTOS sources and adding the `FreeRTOSConfig.h` file location to the include path. This OSAL has only been tested extensively with the pre-emptive scheduler configuration so far but it should in principle also be possible to use a cooperative scheduler. It is recommended to use the `heap_4` allocation scheme. When using newlib (nano), it is also recommended to add `#define configUSE_NEWLIB_REENTRANT` to the FreeRTOS configuration file to ensure thread-safety.
|
|
||||||
|
|
||||||
When using this OSAL, developers also need to provide an implementation for the `vRequestContextSwitchFromISR` function. This has been done because the call to request a context switch from an ISR is generally located in the `portmacro.h` header and is different depending on the target architecture or device.
|
|
||||||
|
|
||||||
## RTEMS OSAL
|
|
||||||
|
|
||||||
The RTEMS OSAL was the first implemented OSAL which is also used on the active satellite Flying Laptop.
|
|
||||||
|
|
||||||
## TCP/IP socket abstraction
|
|
||||||
|
|
||||||
The Linux and Host OSAL provide abstraction layers for the socket API. Currently, only UDP sockets have been imlemented. This is very useful to test TMTC handling either on the host computer directly (targeting localhost with a TMTC application) or on embedded Linux devices, sending TMTC packets via Ethernet.
|
|
||||||
|
|
||||||
|
|
@ -1 +0,0 @@
|
|||||||
## PUS Services
|
|
@ -50,6 +50,11 @@ exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
|||||||
#
|
#
|
||||||
html_theme = 'alabaster'
|
html_theme = 'alabaster'
|
||||||
|
|
||||||
|
html_theme_options = {
|
||||||
|
"extra_nav_links": {"Impressum" : "https://www.uni-stuttgart.de/impressum", "Datenschutz": "https://info.irs.uni-stuttgart.de/datenschutz/datenschutzWebmit.html"}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# Add any paths that contain custom static files (such as style sheets) here,
|
# Add any paths that contain custom static files (such as style sheets) here,
|
||||||
# relative to this directory. They are copied after the builtin static files,
|
# relative to this directory. They are copied after the builtin static files,
|
||||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||||
|
@ -6,13 +6,14 @@ High-level overview
|
|||||||
Structure
|
Structure
|
||||||
----------
|
----------
|
||||||
|
|
||||||
The general structure is driven by the usage of interfaces provided by objects.
|
The general structure is driven by the usage of interfaces provided by objects.
|
||||||
The FSFW uses C++11 as baseline. The intention behind this is that this C++ Standard should be
|
The FSFW uses C++17 as baseline. Most modern compilers like GCC should have support for this
|
||||||
widely available, even with older compilers.
|
standard, even for micocontrollers.
|
||||||
The FSFW uses dynamic allocation during the initialization but provides static containers during runtime.
|
|
||||||
This simplifies the instantiation of objects and allows the usage of some standard containers.
|
The FSFW might use dynamic allocation during program initialization but not during runtime.
|
||||||
Dynamic Allocation after initialization is discouraged and different solutions are provided in the
|
It offers pool objects, static containers and it also exposes the
|
||||||
FSFW to achieve that. The fsfw uses run-time type information but exceptions are not allowed.
|
`Embedded Template Library <https://www.etlcpp.com/>`_ to allow writing code which does not perform
|
||||||
|
allocation during runtime. The fsfw uses run-time type information but will not throw exceptions.
|
||||||
|
|
||||||
Failure Handling
|
Failure Handling
|
||||||
-----------------
|
-----------------
|
||||||
|
@ -4,6 +4,10 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
// It is assumed the user has a subsystem and class ID list in some user header files.
|
||||||
|
// #include "events/subsystemIdRanges.h"
|
||||||
|
// #include "returnvalues/classIds.h"
|
||||||
|
|
||||||
//! Used to determine whether C++ ostreams are used which can increase
|
//! Used to determine whether C++ ostreams are used which can increase
|
||||||
//! the binary size significantly. If this is disabled,
|
//! the binary size significantly. If this is disabled,
|
||||||
//! the C stdio functions can be used alternatively
|
//! the C stdio functions can be used alternatively
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||||
#include <fsfw/events/EventManager.h>
|
#include <fsfw/events/EventManager.h>
|
||||||
#include <fsfw/health/HealthTable.h>
|
#include <fsfw/health/HealthTable.h>
|
||||||
#include <fsfw/tmtcpacket/pus/tm/TmPacketStored.h>
|
|
||||||
#include <fsfw/tmtcservices/CommandingServiceBase.h>
|
#include <fsfw/tmtcservices/CommandingServiceBase.h>
|
||||||
#include <fsfw/tmtcservices/PusServiceBase.h>
|
#include <fsfw/tmtcservices/PusServiceBase.h>
|
||||||
#include <fsfw/internalerror/InternalErrorReporter.h>
|
#include <fsfw/internalerror/InternalErrorReporter.h>
|
||||||
@ -35,19 +34,15 @@ void Factory::produceFsfwObjects(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Factory::setStaticFrameworkObjectIds() {
|
void Factory::setStaticFrameworkObjectIds() {
|
||||||
PusServiceBase::packetSource = objects::NO_OBJECT;
|
PusServiceBase::PUS_DISTRIBUTOR = objects::NO_OBJECT;
|
||||||
PusServiceBase::PACKET_DESTINATION = objects::NO_OBJECT;
|
PusServiceBase::PACKET_DESTINATION = objects::NO_OBJECT;
|
||||||
|
|
||||||
CommandingServiceBase::defaultPacketSource = objects::NO_OBJECT;
|
CommandingServiceBase::defaultPacketSource = objects::NO_OBJECT;
|
||||||
CommandingServiceBase::defaultPacketDestination = objects::NO_OBJECT;
|
CommandingServiceBase::defaultPacketDestination = objects::NO_OBJECT;
|
||||||
|
|
||||||
VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION;
|
|
||||||
|
|
||||||
DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT;
|
DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT;
|
||||||
DeviceHandlerBase::rawDataReceiverId = objects::PUS_SERVICE_2_DEVICE_ACCESS;
|
DeviceHandlerBase::rawDataReceiverId = objects::PUS_SERVICE_2_DEVICE_ACCESS;
|
||||||
|
|
||||||
DeviceHandlerFailureIsolation::powerConfirmationId = objects::NO_OBJECT;
|
DeviceHandlerFailureIsolation::powerConfirmationId = objects::NO_OBJECT;
|
||||||
|
|
||||||
TmPacketBase::timeStamperId = objects::NO_OBJECT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,11 @@ if [[ ! -f README.md ]]; then
|
|||||||
cd ..
|
cd ..
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
folder_list=(
|
||||||
|
"./src"
|
||||||
|
"./unittests"
|
||||||
|
)
|
||||||
|
|
||||||
cmake_fmt="cmake-format"
|
cmake_fmt="cmake-format"
|
||||||
file_selectors="-iname CMakeLists.txt"
|
file_selectors="-iname CMakeLists.txt"
|
||||||
if command -v ${cmake_fmt} &> /dev/null; then
|
if command -v ${cmake_fmt} &> /dev/null; then
|
||||||
@ -15,8 +20,10 @@ fi
|
|||||||
cpp_format="clang-format"
|
cpp_format="clang-format"
|
||||||
file_selectors="-iname *.h -o -iname *.cpp -o -iname *.c -o -iname *.tpp"
|
file_selectors="-iname *.h -o -iname *.cpp -o -iname *.c -o -iname *.tpp"
|
||||||
if command -v ${cpp_format} &> /dev/null; then
|
if command -v ${cpp_format} &> /dev/null; then
|
||||||
find ./src ${file_selectors} | xargs ${cpp_format} --style=file -i
|
for dir in ${folder_list[@]}; do
|
||||||
find ./unittests ${file_selectors} | xargs ${cpp_format} --style=file -i
|
echo "Auto-formatting ${dir} recursively"
|
||||||
|
find ${dir} ${file_selectors} | xargs clang-format --style=file -i
|
||||||
|
done
|
||||||
else
|
else
|
||||||
echo "No ${cpp_format} tool found, not formatting C++/C files"
|
echo "No ${cpp_format} tool found, not formatting C++/C files"
|
||||||
fi
|
fi
|
||||||
|
@ -199,7 +199,7 @@ def check_for_cmake_build_dir(build_dir_list: list) -> list:
|
|||||||
def perform_lcov_operation(directory: str, chdir: bool):
|
def perform_lcov_operation(directory: str, chdir: bool):
|
||||||
if chdir:
|
if chdir:
|
||||||
os.chdir(directory)
|
os.chdir(directory)
|
||||||
cmd_runner("cmake --build . -- fsfw-tests_coverage -j")
|
cmd_runner("cmake --build . -j -- fsfw-tests_coverage")
|
||||||
|
|
||||||
|
|
||||||
def determine_build_dir(build_dir_list: List[str]):
|
def determine_build_dir(build_dir_list: List[str]):
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
#include "fsfw/cfdp/CfdpMessage.h"
|
#include "fsfw/cfdp/CfdpMessage.h"
|
||||||
#include "fsfw/ipc/CommandMessage.h"
|
#include "fsfw/ipc/CommandMessage.h"
|
||||||
#include "fsfw/ipc/QueueFactory.h"
|
#include "fsfw/ipc/QueueFactory.h"
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
|
||||||
#include "fsfw/storagemanager/storeAddress.h"
|
#include "fsfw/storagemanager/storeAddress.h"
|
||||||
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
|
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
|
||||||
|
|
||||||
@ -52,6 +51,6 @@ ReturnValue_t CfdpHandler::performOperation(uint8_t opCode) {
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t CfdpHandler::getIdentifier() { return 0; }
|
uint32_t CfdpHandler::getIdentifier() const { return 0; }
|
||||||
|
|
||||||
MessageQueueId_t CfdpHandler::getRequestQueue() { return this->requestQueue->getId(); }
|
MessageQueueId_t CfdpHandler::getRequestQueue() const { return this->requestQueue->getId(); }
|
||||||
|
@ -25,8 +25,8 @@ class CfdpHandler : public ExecutableObjectIF, public AcceptsTelecommandsIF, pub
|
|||||||
virtual ReturnValue_t handleRequest(store_address_t storeId);
|
virtual ReturnValue_t handleRequest(store_address_t storeId);
|
||||||
|
|
||||||
virtual ReturnValue_t initialize() override;
|
virtual ReturnValue_t initialize() override;
|
||||||
virtual uint16_t getIdentifier() override;
|
uint32_t getIdentifier() const override;
|
||||||
MessageQueueId_t getRequestQueue() override;
|
MessageQueueId_t getRequestQueue() const override;
|
||||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -21,7 +21,7 @@ cfdp::Lv& cfdp::Lv::operator=(const Lv& other) {
|
|||||||
if (value == nullptr or otherSize == 0) {
|
if (value == nullptr or otherSize == 0) {
|
||||||
this->zeroLen = true;
|
this->zeroLen = true;
|
||||||
}
|
}
|
||||||
this->value.setBuffer(value, otherSize);
|
this->value.setConstBuffer(value, otherSize);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ ReturnValue_t cfdp::Lv::deSerialize(const uint8_t** buffer, size_t* size,
|
|||||||
}
|
}
|
||||||
zeroLen = false;
|
zeroLen = false;
|
||||||
// Zero-copy implementation
|
// Zero-copy implementation
|
||||||
value.setBuffer(const_cast<uint8_t*>(*buffer + 1), lengthField);
|
value.setConstBuffer(*buffer + 1, lengthField);
|
||||||
*buffer += 1 + lengthField;
|
*buffer += 1 + lengthField;
|
||||||
*size -= 1 + lengthField;
|
*size -= 1 + lengthField;
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
|
@ -75,7 +75,7 @@ ReturnValue_t cfdp::Tlv::deSerialize(const uint8_t **buffer, size_t *size,
|
|||||||
}
|
}
|
||||||
zeroLen = false;
|
zeroLen = false;
|
||||||
// Zero-copy implementation
|
// Zero-copy implementation
|
||||||
value.setBuffer(const_cast<uint8_t *>(*buffer + 1), lengthField);
|
value.setConstBuffer(*buffer + 1, lengthField);
|
||||||
*buffer += 1 + lengthField;
|
*buffer += 1 + lengthField;
|
||||||
*size -= 1 + lengthField;
|
*size -= 1 + lengthField;
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
@ -96,7 +96,7 @@ void cfdp::Tlv::setValue(uint8_t *value, size_t len) {
|
|||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
zeroLen = false;
|
zeroLen = false;
|
||||||
}
|
}
|
||||||
this->value.setBuffer(value, len);
|
this->value.setConstBuffer(value, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t cfdp::Tlv::getLengthField() const { return this->value.getSerializedSize() - 1; }
|
uint8_t cfdp::Tlv::getLengthField() const { return this->value.getSerializedSize() - 1; }
|
||||||
|
@ -243,13 +243,14 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
|||||||
LocalDataPoolManager* getPoolManagerHandle() override;
|
LocalDataPoolManager* getPoolManagerHandle() override;
|
||||||
ReturnValue_t subscribeForRegularPeriodicPacket(subdp::RegularHkPeriodicParams params) override;
|
ReturnValue_t subscribeForRegularPeriodicPacket(subdp::RegularHkPeriodicParams params) override;
|
||||||
ReturnValue_t subscribeForDiagPeriodicPacket(subdp::DiagnosticsHkPeriodicParams params) override;
|
ReturnValue_t subscribeForDiagPeriodicPacket(subdp::DiagnosticsHkPeriodicParams params) override;
|
||||||
ReturnValue_t subscribeForPeriodicPacket(subdp::ParamsBase& params);
|
|
||||||
|
|
||||||
ReturnValue_t subscribeForRegularUpdatePacket(subdp::RegularHkUpdateParams params) override;
|
ReturnValue_t subscribeForRegularUpdatePacket(subdp::RegularHkUpdateParams params) override;
|
||||||
ReturnValue_t subscribeForDiagUpdatePacket(subdp::DiagnosticsHkUpdateParams params) override;
|
ReturnValue_t subscribeForDiagUpdatePacket(subdp::DiagnosticsHkUpdateParams params) override;
|
||||||
ReturnValue_t subscribeForUpdatePacket(subdp::ParamsBase& params);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
ReturnValue_t subscribeForPeriodicPacket(subdp::ParamsBase& params);
|
||||||
|
ReturnValue_t subscribeForUpdatePacket(subdp::ParamsBase& params);
|
||||||
|
|
||||||
/** Core data structure for the actual pool data */
|
/** Core data structure for the actual pool data */
|
||||||
localpool::DataPool localPoolMap;
|
localpool::DataPool localPoolMap;
|
||||||
/** Every housekeeping data manager has a mutex to protect access
|
/** Every housekeeping data manager has a mutex to protect access
|
||||||
|
@ -48,12 +48,12 @@ LocalPoolObjectBase::LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId,
|
|||||||
if (hkOwner == nullptr) {
|
if (hkOwner == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "LocalPoolVariable: The supplied pool owner 0x" << std::hex << poolOwner
|
sif::error << "LocalPoolVariable: The supplied pool owner 0x" << std::hex << poolOwner
|
||||||
<< std::dec << " did not implement the correct interface "
|
<< std::dec << " does not exist or does not implement the correct interface "
|
||||||
<< "HasLocalDataPoolIF" << std::endl;
|
<< "HasLocalDataPoolIF" << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printError(
|
sif::printError(
|
||||||
"LocalPoolVariable: The supplied pool owner 0x%08x did not implement the correct "
|
"LocalPoolVariable: The supplied pool owner 0x%08x does not exist or does not implement "
|
||||||
"interface HasLocalDataPoolIF\n",
|
"the correct interface HasLocalDataPoolIF\n",
|
||||||
poolOwner);
|
poolOwner);
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "fsfw/ipc/MessageQueueMessage.h"
|
#include "fsfw/ipc/MessageQueueMessage.h"
|
||||||
#include "fsfw/ipc/QueueFactory.h"
|
#include "fsfw/ipc/QueueFactory.h"
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
|
#include "fsfw/serialize/SerialBufferAdapter.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||||
#include "fsfw/subsystem/SubsystemBase.h"
|
#include "fsfw/subsystem/SubsystemBase.h"
|
||||||
@ -21,8 +22,6 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t device
|
|||||||
CookieIF* comCookie, FailureIsolationBase* fdirInstance,
|
CookieIF* comCookie, FailureIsolationBase* fdirInstance,
|
||||||
size_t cmdQueueSize)
|
size_t cmdQueueSize)
|
||||||
: SystemObject(setObjectId),
|
: SystemObject(setObjectId),
|
||||||
mode(MODE_OFF),
|
|
||||||
submode(SUBMODE_NONE),
|
|
||||||
wiretappingMode(OFF),
|
wiretappingMode(OFF),
|
||||||
storedRawData(StorageManagerIF::INVALID_ADDRESS),
|
storedRawData(StorageManagerIF::INVALID_ADDRESS),
|
||||||
deviceCommunicationId(deviceCommunication),
|
deviceCommunicationId(deviceCommunication),
|
||||||
@ -37,6 +36,8 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t device
|
|||||||
defaultFDIRUsed(fdirInstance == nullptr),
|
defaultFDIRUsed(fdirInstance == nullptr),
|
||||||
switchOffWasReported(false),
|
switchOffWasReported(false),
|
||||||
childTransitionDelay(5000),
|
childTransitionDelay(5000),
|
||||||
|
mode(MODE_OFF),
|
||||||
|
submode(SUBMODE_NONE),
|
||||||
transitionSourceMode(_MODE_POWER_DOWN),
|
transitionSourceMode(_MODE_POWER_DOWN),
|
||||||
transitionSourceSubMode(SUBMODE_NONE) {
|
transitionSourceSubMode(SUBMODE_NONE) {
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||||
@ -351,7 +352,6 @@ void DeviceHandlerBase::doStateMachine() {
|
|||||||
currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) {
|
currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) {
|
||||||
triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT, 0);
|
triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT, 0);
|
||||||
setMode(_MODE_POWER_DOWN);
|
setMode(_MODE_POWER_DOWN);
|
||||||
callChildStatemachine();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ReturnValue_t switchState = getStateOfSwitches();
|
ReturnValue_t switchState = getStateOfSwitches();
|
||||||
@ -457,7 +457,7 @@ ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceComm
|
|||||||
info.expectedReplies = 0;
|
info.expectedReplies = 0;
|
||||||
info.isExecuting = false;
|
info.isExecuting = false;
|
||||||
info.sendReplyTo = NO_COMMANDER;
|
info.sendReplyTo = NO_COMMANDER;
|
||||||
info.useAlternativeReplyId = alternativeReplyId;
|
info.useAlternativeReplyId = useAlternativeReply;
|
||||||
info.alternativeReplyId = alternativeReplyId;
|
info.alternativeReplyId = alternativeReplyId;
|
||||||
auto resultPair = deviceCommandMap.emplace(deviceCommand, info);
|
auto resultPair = deviceCommandMap.emplace(deviceCommand, info);
|
||||||
if (resultPair.second) {
|
if (resultPair.second) {
|
||||||
@ -516,16 +516,16 @@ ReturnValue_t DeviceHandlerBase::updatePeriodicReply(bool enable, DeviceCommandI
|
|||||||
if (enable) {
|
if (enable) {
|
||||||
info->active = true;
|
info->active = true;
|
||||||
if (info->countdown != nullptr) {
|
if (info->countdown != nullptr) {
|
||||||
info->delayCycles = info->maxDelayCycles;
|
|
||||||
} else {
|
|
||||||
info->countdown->resetTimer();
|
info->countdown->resetTimer();
|
||||||
|
} else {
|
||||||
|
info->delayCycles = info->maxDelayCycles;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
info->active = false;
|
info->active = false;
|
||||||
if (info->countdown != nullptr) {
|
if (info->countdown != nullptr) {
|
||||||
info->delayCycles = 0;
|
|
||||||
} else {
|
|
||||||
info->countdown->timeOut();
|
info->countdown->timeOut();
|
||||||
|
} else {
|
||||||
|
info->delayCycles = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -566,11 +566,23 @@ void DeviceHandlerBase::setTransition(Mode_t modeTo, Submode_t submodeTo) {
|
|||||||
void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
|
void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
|
||||||
/* TODO: This will probably be done by the LocalDataPoolManager now */
|
/* TODO: This will probably be done by the LocalDataPoolManager now */
|
||||||
// changeHK(mode, submode, false);
|
// changeHK(mode, submode, false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handle transition from OFF to NORMAL by continuing towards normal when ON is reached
|
||||||
|
*/
|
||||||
|
if (newMode == MODE_ON and continueToNormal) {
|
||||||
|
continueToNormal = false;
|
||||||
|
mode = _MODE_TO_NORMAL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
submode = newSubmode;
|
submode = newSubmode;
|
||||||
mode = newMode;
|
mode = newMode;
|
||||||
modeChanged();
|
modeChanged();
|
||||||
setNormalDatapoolEntriesInvalid();
|
setNormalDatapoolEntriesInvalid();
|
||||||
if (!isTransitionalMode()) {
|
if (!isTransitionalMode()) {
|
||||||
|
// clear this flag when a non-transitional Mode is reached to be safe
|
||||||
|
continueToNormal = false;
|
||||||
modeHelper.modeChanged(newMode, newSubmode);
|
modeHelper.modeChanged(newMode, newSubmode);
|
||||||
announceMode(false);
|
announceMode(false);
|
||||||
}
|
}
|
||||||
@ -1055,8 +1067,7 @@ Mode_t DeviceHandlerBase::getBaseMode(Mode_t transitionMode) {
|
|||||||
return transitionMode & ~(TRANSITION_MODE_BASE_ACTION_MASK | TRANSITION_MODE_CHILD_ACTION_MASK);
|
return transitionMode & ~(TRANSITION_MODE_BASE_ACTION_MASK | TRANSITION_MODE_CHILD_ACTION_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SHOULDDO: Allow transition from OFF to NORMAL to reduce complexity in assemblies. And, by the
|
// SHOULDDO: throw away DHB and write a new one:
|
||||||
// way, throw away DHB and write a new one:
|
|
||||||
// - Include power and thermal completely, but more modular :-)
|
// - Include power and thermal completely, but more modular :-)
|
||||||
// - Don't use modes for state transitions, reduce FSM (Finte State Machine) complexity.
|
// - Don't use modes for state transitions, reduce FSM (Finte State Machine) complexity.
|
||||||
// - Modularization?
|
// - Modularization?
|
||||||
@ -1068,11 +1079,10 @@ ReturnValue_t DeviceHandlerBase::checkModeCommand(Mode_t commandedMode, Submode_
|
|||||||
if ((mode == MODE_ERROR_ON) && (commandedMode != MODE_OFF)) {
|
if ((mode == MODE_ERROR_ON) && (commandedMode != MODE_OFF)) {
|
||||||
return TRANS_NOT_ALLOWED;
|
return TRANS_NOT_ALLOWED;
|
||||||
}
|
}
|
||||||
if ((commandedMode == MODE_NORMAL) && (mode == MODE_OFF)) {
|
|
||||||
return TRANS_NOT_ALLOWED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((commandedMode == MODE_ON) && (mode == MODE_OFF) and (thermalSet != nullptr)) {
|
// Do not check thermal state for MODE_RAW
|
||||||
|
if ((mode == MODE_OFF) and ((commandedMode == MODE_ON) or (commandedMode == MODE_NORMAL)) and
|
||||||
|
(thermalSet != nullptr)) {
|
||||||
ReturnValue_t result = thermalSet->read();
|
ReturnValue_t result = thermalSet->read();
|
||||||
if (result == returnvalue::OK) {
|
if (result == returnvalue::OK) {
|
||||||
if ((thermalSet->heaterRequest.value != ThermalComponentIF::STATE_REQUEST_IGNORE) and
|
if ((thermalSet->heaterRequest.value != ThermalComponentIF::STATE_REQUEST_IGNORE) and
|
||||||
@ -1087,6 +1097,7 @@ ReturnValue_t DeviceHandlerBase::checkModeCommand(Mode_t commandedMode, Submode_
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DeviceHandlerBase::startTransition(Mode_t commandedMode, Submode_t commandedSubmode) {
|
void DeviceHandlerBase::startTransition(Mode_t commandedMode, Submode_t commandedSubmode) {
|
||||||
|
continueToNormal = false;
|
||||||
switch (commandedMode) {
|
switch (commandedMode) {
|
||||||
case MODE_ON:
|
case MODE_ON:
|
||||||
handleTransitionToOnMode(commandedMode, commandedSubmode);
|
handleTransitionToOnMode(commandedMode, commandedSubmode);
|
||||||
@ -1116,8 +1127,9 @@ void DeviceHandlerBase::startTransition(Mode_t commandedMode, Submode_t commande
|
|||||||
case MODE_NORMAL:
|
case MODE_NORMAL:
|
||||||
if (mode != MODE_OFF) {
|
if (mode != MODE_OFF) {
|
||||||
setTransition(MODE_NORMAL, commandedSubmode);
|
setTransition(MODE_NORMAL, commandedSubmode);
|
||||||
} else {
|
} else { // mode is off
|
||||||
replyReturnvalueToCommand(HasModesIF::TRANS_NOT_ALLOWED);
|
continueToNormal = true;
|
||||||
|
handleTransitionToOnMode(MODE_NORMAL, commandedSubmode);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1257,28 +1269,30 @@ ReturnValue_t DeviceHandlerBase::letChildHandleMessage(CommandMessage* message)
|
|||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceHandlerBase::handleDeviceTM(SerializeIF* dataSet, DeviceCommandId_t replyId,
|
void DeviceHandlerBase::handleDeviceTm(const uint8_t* rawData, size_t rawDataLen,
|
||||||
bool forceDirectTm) {
|
DeviceCommandId_t replyId, bool forceDirectTm) {
|
||||||
if (dataSet == nullptr) {
|
SerialBufferAdapter bufferWrapper(rawData, rawDataLen);
|
||||||
return;
|
handleDeviceTm(bufferWrapper, replyId, forceDirectTm);
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceReplyMap::iterator iter = deviceReplyMap.find(replyId);
|
void DeviceHandlerBase::handleDeviceTm(const SerializeIF& dataSet, DeviceCommandId_t replyId,
|
||||||
|
bool forceDirectTm) {
|
||||||
|
auto iter = deviceReplyMap.find(replyId);
|
||||||
if (iter == deviceReplyMap.end()) {
|
if (iter == deviceReplyMap.end()) {
|
||||||
triggerEvent(DEVICE_UNKNOWN_REPLY, replyId);
|
triggerEvent(DEVICE_UNKNOWN_REPLY, replyId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Regular replies to a command */
|
// Regular replies to a command
|
||||||
if (iter->second.command != deviceCommandMap.end()) {
|
if (iter->second.command != deviceCommandMap.end()) {
|
||||||
MessageQueueId_t queueId = iter->second.command->second.sendReplyTo;
|
MessageQueueId_t queueId = iter->second.command->second.sendReplyTo;
|
||||||
|
|
||||||
if (queueId != NO_COMMANDER) {
|
if (queueId != NO_COMMANDER) {
|
||||||
/* This may fail, but we'll ignore the fault. */
|
// This may fail, but we'll ignore the fault.
|
||||||
actionHelper.reportData(queueId, replyId, dataSet);
|
actionHelper.reportData(queueId, replyId, const_cast<SerializeIF*>(&dataSet));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This check should make sure we get any TM but don't get anything doubled. */
|
// This check should make sure we get any TM but don't get anything doubled.
|
||||||
if (wiretappingMode == TM && (requestedRawTraffic != queueId)) {
|
if (wiretappingMode == TM && (requestedRawTraffic != queueId)) {
|
||||||
DeviceTmReportingWrapper wrapper(getObjectId(), replyId, dataSet);
|
DeviceTmReportingWrapper wrapper(getObjectId(), replyId, dataSet);
|
||||||
actionHelper.reportData(requestedRawTraffic, replyId, &wrapper);
|
actionHelper.reportData(requestedRawTraffic, replyId, &wrapper);
|
||||||
@ -1289,22 +1303,17 @@ void DeviceHandlerBase::handleDeviceTM(SerializeIF* dataSet, DeviceCommandId_t r
|
|||||||
// hiding of sender needed so the service will handle it as
|
// hiding of sender needed so the service will handle it as
|
||||||
// unexpected Data, no matter what state (progress or completed)
|
// unexpected Data, no matter what state (progress or completed)
|
||||||
// it is in
|
// it is in
|
||||||
actionHelper.reportData(defaultRawReceiver, replyId, dataSet, true);
|
actionHelper.reportData(defaultRawReceiver, replyId, const_cast<SerializeIF*>(&dataSet),
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Unrequested or aperiodic replies */
|
// Unrequested or aperiodic replies
|
||||||
else {
|
else {
|
||||||
DeviceTmReportingWrapper wrapper(getObjectId(), replyId, dataSet);
|
DeviceTmReportingWrapper wrapper(getObjectId(), replyId, dataSet);
|
||||||
if (wiretappingMode == TM) {
|
if (wiretappingMode == TM) {
|
||||||
actionHelper.reportData(requestedRawTraffic, replyId, &wrapper);
|
actionHelper.reportData(requestedRawTraffic, replyId, &wrapper);
|
||||||
}
|
}
|
||||||
if (forceDirectTm and defaultRawReceiver != MessageQueueIF::NO_QUEUE) {
|
if (forceDirectTm and defaultRawReceiver != MessageQueueIF::NO_QUEUE) {
|
||||||
// sid_t setSid = sid_t(this->getObjectId(), replyId);
|
|
||||||
// LocalPoolDataSetBase* dataset = getDataSetHandle(setSid);
|
|
||||||
// if(dataset != nullptr) {
|
|
||||||
// poolManager.generateHousekeepingPacket(setSid, dataset, true);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// hiding of sender needed so the service will handle it as
|
// hiding of sender needed so the service will handle it as
|
||||||
// unexpected Data, no matter what state (progress or completed)
|
// unexpected Data, no matter what state (progress or completed)
|
||||||
// it is in
|
// it is in
|
||||||
@ -1325,10 +1334,10 @@ ReturnValue_t DeviceHandlerBase::executeAction(ActionId_t actionId, MessageQueue
|
|||||||
} else if (iter->second.isExecuting) {
|
} else if (iter->second.isExecuting) {
|
||||||
result = COMMAND_ALREADY_SENT;
|
result = COMMAND_ALREADY_SENT;
|
||||||
} else {
|
} else {
|
||||||
|
iter->second.sendReplyTo = commandedBy;
|
||||||
result = buildCommandFromCommand(actionId, data, size);
|
result = buildCommandFromCommand(actionId, data, size);
|
||||||
}
|
}
|
||||||
if (result == returnvalue::OK) {
|
if (result == returnvalue::OK) {
|
||||||
iter->second.sendReplyTo = commandedBy;
|
|
||||||
iter->second.isExecuting = true;
|
iter->second.isExecuting = true;
|
||||||
cookieInfo.pendingCommand = iter;
|
cookieInfo.pendingCommand = iter;
|
||||||
cookieInfo.state = COOKIE_WRITE_READY;
|
cookieInfo.state = COOKIE_WRITE_READY;
|
||||||
|
@ -102,6 +102,53 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF *comCookie,
|
DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF *comCookie,
|
||||||
FailureIsolationBase *fdirInstance = nullptr, size_t cmdQueueSize = 20);
|
FailureIsolationBase *fdirInstance = nullptr, size_t cmdQueueSize = 20);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* extending the modes of DeviceHandler IF for internal state machine
|
||||||
|
*/
|
||||||
|
static constexpr uint8_t TRANSITION_MODE_CHILD_ACTION_MASK = 0x20;
|
||||||
|
static constexpr uint8_t TRANSITION_MODE_BASE_ACTION_MASK = 0x10;
|
||||||
|
//! This is a transitional state which can not be commanded. The device
|
||||||
|
//! handler performs all commands to get the device in a state ready to
|
||||||
|
//! perform commands. When this is completed, the mode changes to @c MODE_ON.
|
||||||
|
static const Mode_t _MODE_START_UP = TRANSITION_MODE_CHILD_ACTION_MASK | 5;
|
||||||
|
//! This is a transitional state which can not be commanded.
|
||||||
|
//! The device handler performs all actions and commands to get the device
|
||||||
|
//! shut down. When the device is off, the mode changes to @c MODE_OFF.
|
||||||
|
//! It is possible to set the mode to _MODE_SHUT_DOWN to use the to off
|
||||||
|
//! transition if available.
|
||||||
|
static const Mode_t _MODE_SHUT_DOWN = TRANSITION_MODE_CHILD_ACTION_MASK | 6;
|
||||||
|
//! It is possible to set the mode to _MODE_TO_ON to use the to on
|
||||||
|
//! transition if available.
|
||||||
|
static const Mode_t _MODE_TO_ON = TRANSITION_MODE_CHILD_ACTION_MASK | HasModesIF::MODE_ON;
|
||||||
|
//! It is possible to set the mode to _MODE_TO_RAW to use the to raw
|
||||||
|
//! transition if available.
|
||||||
|
static const Mode_t _MODE_TO_RAW = TRANSITION_MODE_CHILD_ACTION_MASK | MODE_RAW;
|
||||||
|
//! It is possible to set the mode to _MODE_TO_NORMAL to use the to normal
|
||||||
|
//! transition if available.
|
||||||
|
static const Mode_t _MODE_TO_NORMAL = TRANSITION_MODE_CHILD_ACTION_MASK | MODE_NORMAL;
|
||||||
|
//! This is a transitional state which can not be commanded.
|
||||||
|
//! The device is shut down and ready to be switched off.
|
||||||
|
//! After the command to set the switch off has been sent,
|
||||||
|
//! the mode changes to @c _MODE_WAIT_OFF
|
||||||
|
static const Mode_t _MODE_POWER_DOWN = TRANSITION_MODE_BASE_ACTION_MASK | 1;
|
||||||
|
//! This is a transitional state which can not be commanded. The device
|
||||||
|
//! will be switched on in this state. After the command to set the switch
|
||||||
|
//! on has been sent, the mode changes to @c _MODE_WAIT_ON.
|
||||||
|
static const Mode_t _MODE_POWER_ON = TRANSITION_MODE_BASE_ACTION_MASK | 2;
|
||||||
|
//! This is a transitional state which can not be commanded. The switch has
|
||||||
|
//! been commanded off and the handler waits for it to be off.
|
||||||
|
//! When the switch is off, the mode changes to @c MODE_OFF.
|
||||||
|
static const Mode_t _MODE_WAIT_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 3;
|
||||||
|
//! This is a transitional state which can not be commanded. The switch
|
||||||
|
//! has been commanded on and the handler waits for it to be on.
|
||||||
|
//! When the switch is on, the mode changes to @c _MODE_TO_ON.
|
||||||
|
static const Mode_t _MODE_WAIT_ON = TRANSITION_MODE_BASE_ACTION_MASK | 4;
|
||||||
|
//! This is a transitional state which can not be commanded. The switch has
|
||||||
|
//! been commanded off and is off now. This state is only to do an RMAP
|
||||||
|
//! cycle once more where the doSendRead() function will set the mode to
|
||||||
|
//! MODE_OFF. The reason to do this is to get rid of stuck packets in the IO Board.
|
||||||
|
static const Mode_t _MODE_SWITCH_IS_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 5;
|
||||||
|
|
||||||
void setHkDestination(object_id_t hkDestination);
|
void setHkDestination(object_id_t hkDestination);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -684,15 +731,18 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
size_t rawPacketLen = 0;
|
size_t rawPacketLen = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The mode the device handler is currently in.
|
* Get the current mode
|
||||||
* This should never be changed directly but only with setMode()
|
*
|
||||||
|
* set via setMode()
|
||||||
*/
|
*/
|
||||||
Mode_t mode;
|
Mode_t getMode();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The submode the device handler is currently in.
|
* Get the current Submode
|
||||||
* This should never be changed directly but only with setMode()
|
*
|
||||||
|
* set via setMode()
|
||||||
*/
|
*/
|
||||||
Submode_t submode;
|
Submode_t getSubmode;
|
||||||
|
|
||||||
/** This is the counter value from performOperation(). */
|
/** This is the counter value from performOperation(). */
|
||||||
uint8_t pstStep = 0;
|
uint8_t pstStep = 0;
|
||||||
@ -873,8 +923,8 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
* Do the transition to the main modes (MODE_ON, MODE_NORMAL and MODE_RAW).
|
* Do the transition to the main modes (MODE_ON, MODE_NORMAL and MODE_RAW).
|
||||||
*
|
*
|
||||||
* If the transition is complete, the mode should be set to the target mode,
|
* If the transition is complete, the mode should be set to the target mode,
|
||||||
* which can be deduced from the current mode which is
|
* which can be deduced from the current mode (which is
|
||||||
* [_MODE_TO_ON, _MODE_TO_NORMAL, _MODE_TO_RAW]
|
* [_MODE_TO_ON, _MODE_TO_NORMAL, _MODE_TO_RAW]) using getBaseMode()
|
||||||
*
|
*
|
||||||
* The intended target submode is already set.
|
* The intended target submode is already set.
|
||||||
* The origin submode can be read in subModeFrom.
|
* The origin submode can be read in subModeFrom.
|
||||||
@ -1052,9 +1102,25 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
|
|
||||||
bool isAwaitingReply();
|
bool isAwaitingReply();
|
||||||
|
|
||||||
void handleDeviceTM(SerializeIF *dataSet, DeviceCommandId_t replyId, bool forceDirectTm = false);
|
/**
|
||||||
// void handleDeviceTM(uint8_t* data, size_t dataSize, DeviceCommandId_t replyId,
|
* Wrapper function for @handleDeviceTm which wraps the raw buffer with @SerialBufferAdapter.
|
||||||
// bool forceDirectTm);
|
* For interpreted data, prefer the other function.
|
||||||
|
* @param rawData
|
||||||
|
* @param rawDataLen
|
||||||
|
* @param replyId
|
||||||
|
* @param forceDirectTm
|
||||||
|
*/
|
||||||
|
void handleDeviceTm(const uint8_t *rawData, size_t rawDataLen, DeviceCommandId_t replyId,
|
||||||
|
bool forceDirectTm = false);
|
||||||
|
/**
|
||||||
|
* Can be used to handle Service 8 data replies. This will also generate the TM wiretapping
|
||||||
|
* packets accordingly.
|
||||||
|
* @param dataSet
|
||||||
|
* @param replyId
|
||||||
|
* @param forceDirectTm
|
||||||
|
*/
|
||||||
|
void handleDeviceTm(const SerializeIF &dataSet, DeviceCommandId_t replyId,
|
||||||
|
bool forceDirectTm = false);
|
||||||
|
|
||||||
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||||
uint32_t *msToReachTheMode);
|
uint32_t *msToReachTheMode);
|
||||||
@ -1154,6 +1220,18 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
*/
|
*/
|
||||||
uint32_t childTransitionDelay;
|
uint32_t childTransitionDelay;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mode the device handler is currently in.
|
||||||
|
* This should not be changed directly but only with setMode()
|
||||||
|
*/
|
||||||
|
Mode_t mode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The submode the device handler is currently in.
|
||||||
|
* This should not be changed directly but only with setMode()
|
||||||
|
*/
|
||||||
|
Submode_t submode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The mode the current transition originated from
|
* @brief The mode the current transition originated from
|
||||||
*
|
*
|
||||||
@ -1171,6 +1249,15 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
*/
|
*/
|
||||||
Submode_t transitionSourceSubMode;
|
Submode_t transitionSourceSubMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* used to make the state machine continue from ON to NOMAL when
|
||||||
|
* a Device is commanded to NORMAL in OFF mode
|
||||||
|
*
|
||||||
|
* set in startTransition()
|
||||||
|
* evaluated in setMode() to continue to NORMAL when ON is reached
|
||||||
|
*/
|
||||||
|
bool continueToNormal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* read the command queue
|
* read the command queue
|
||||||
*/
|
*/
|
||||||
|
@ -24,9 +24,6 @@ class DeviceHandlerIF {
|
|||||||
static const DeviceCommandId_t RAW_COMMAND_ID = -1;
|
static const DeviceCommandId_t RAW_COMMAND_ID = -1;
|
||||||
static const DeviceCommandId_t NO_COMMAND_ID = -2;
|
static const DeviceCommandId_t NO_COMMAND_ID = -2;
|
||||||
|
|
||||||
static constexpr uint8_t TRANSITION_MODE_CHILD_ACTION_MASK = 0x20;
|
|
||||||
static constexpr uint8_t TRANSITION_MODE_BASE_ACTION_MASK = 0x10;
|
|
||||||
|
|
||||||
using dh_heater_request_t = uint8_t;
|
using dh_heater_request_t = uint8_t;
|
||||||
using dh_thermal_state_t = int8_t;
|
using dh_thermal_state_t = int8_t;
|
||||||
|
|
||||||
@ -54,47 +51,6 @@ class DeviceHandlerIF {
|
|||||||
//! device still is powered. In this mode, only a mode change to @c MODE_OFF
|
//! device still is powered. In this mode, only a mode change to @c MODE_OFF
|
||||||
//! can be commanded, which tries to switch off the device again.
|
//! can be commanded, which tries to switch off the device again.
|
||||||
static const Mode_t MODE_ERROR_ON = 4;
|
static const Mode_t MODE_ERROR_ON = 4;
|
||||||
//! This is a transitional state which can not be commanded. The device
|
|
||||||
//! handler performs all commands to get the device in a state ready to
|
|
||||||
//! perform commands. When this is completed, the mode changes to @c MODE_ON.
|
|
||||||
static const Mode_t _MODE_START_UP = TRANSITION_MODE_CHILD_ACTION_MASK | 5;
|
|
||||||
//! This is a transitional state which can not be commanded.
|
|
||||||
//! The device handler performs all actions and commands to get the device
|
|
||||||
//! shut down. When the device is off, the mode changes to @c MODE_OFF.
|
|
||||||
//! It is possible to set the mode to _MODE_SHUT_DOWN to use the to off
|
|
||||||
//! transition if available.
|
|
||||||
static const Mode_t _MODE_SHUT_DOWN = TRANSITION_MODE_CHILD_ACTION_MASK | 6;
|
|
||||||
//! It is possible to set the mode to _MODE_TO_ON to use the to on
|
|
||||||
//! transition if available.
|
|
||||||
static const Mode_t _MODE_TO_ON = TRANSITION_MODE_CHILD_ACTION_MASK | HasModesIF::MODE_ON;
|
|
||||||
//! It is possible to set the mode to _MODE_TO_RAW to use the to raw
|
|
||||||
//! transition if available.
|
|
||||||
static const Mode_t _MODE_TO_RAW = TRANSITION_MODE_CHILD_ACTION_MASK | MODE_RAW;
|
|
||||||
//! It is possible to set the mode to _MODE_TO_NORMAL to use the to normal
|
|
||||||
//! transition if available.
|
|
||||||
static const Mode_t _MODE_TO_NORMAL = TRANSITION_MODE_CHILD_ACTION_MASK | MODE_NORMAL;
|
|
||||||
//! This is a transitional state which can not be commanded.
|
|
||||||
//! The device is shut down and ready to be switched off.
|
|
||||||
//! After the command to set the switch off has been sent,
|
|
||||||
//! the mode changes to @c MODE_WAIT_OFF
|
|
||||||
static const Mode_t _MODE_POWER_DOWN = TRANSITION_MODE_BASE_ACTION_MASK | 1;
|
|
||||||
//! This is a transitional state which can not be commanded. The device
|
|
||||||
//! will be switched on in this state. After the command to set the switch
|
|
||||||
//! on has been sent, the mode changes to @c MODE_WAIT_ON.
|
|
||||||
static const Mode_t _MODE_POWER_ON = TRANSITION_MODE_BASE_ACTION_MASK | 2;
|
|
||||||
//! This is a transitional state which can not be commanded. The switch has
|
|
||||||
//! been commanded off and the handler waits for it to be off.
|
|
||||||
//! When the switch is off, the mode changes to @c MODE_OFF.
|
|
||||||
static const Mode_t _MODE_WAIT_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 3;
|
|
||||||
//! This is a transitional state which can not be commanded. The switch
|
|
||||||
//! has been commanded on and the handler waits for it to be on.
|
|
||||||
//! When the switch is on, the mode changes to @c MODE_TO_ON.
|
|
||||||
static const Mode_t _MODE_WAIT_ON = TRANSITION_MODE_BASE_ACTION_MASK | 4;
|
|
||||||
//! This is a transitional state which can not be commanded. The switch has
|
|
||||||
//! been commanded off and is off now. This state is only to do an RMAP
|
|
||||||
//! cycle once more where the doSendRead() function will set the mode to
|
|
||||||
//! MODE_OFF. The reason to do this is to get rid of stuck packets in the IO Board.
|
|
||||||
static const Mode_t _MODE_SWITCH_IS_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 5;
|
|
||||||
|
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CDH;
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CDH;
|
||||||
static const Event DEVICE_BUILDING_COMMAND_FAILED = MAKE_EVENT(0, severity::LOW);
|
static const Event DEVICE_BUILDING_COMMAND_FAILED = MAKE_EVENT(0, severity::LOW);
|
||||||
|
@ -3,10 +3,10 @@
|
|||||||
#include "fsfw/serialize/SerializeAdapter.h"
|
#include "fsfw/serialize/SerializeAdapter.h"
|
||||||
|
|
||||||
DeviceTmReportingWrapper::DeviceTmReportingWrapper(object_id_t objectId, ActionId_t actionId,
|
DeviceTmReportingWrapper::DeviceTmReportingWrapper(object_id_t objectId, ActionId_t actionId,
|
||||||
SerializeIF* data)
|
const SerializeIF& data)
|
||||||
: objectId(objectId), actionId(actionId), data(data) {}
|
: objectId(objectId), actionId(actionId), data(data) {}
|
||||||
|
|
||||||
DeviceTmReportingWrapper::~DeviceTmReportingWrapper() {}
|
DeviceTmReportingWrapper::~DeviceTmReportingWrapper() = default;
|
||||||
|
|
||||||
ReturnValue_t DeviceTmReportingWrapper::serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
ReturnValue_t DeviceTmReportingWrapper::serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||||
Endianness streamEndianness) const {
|
Endianness streamEndianness) const {
|
||||||
@ -19,22 +19,14 @@ ReturnValue_t DeviceTmReportingWrapper::serialize(uint8_t** buffer, size_t* size
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return data->serialize(buffer, size, maxSize, streamEndianness);
|
return data.serialize(buffer, size, maxSize, streamEndianness);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t DeviceTmReportingWrapper::getSerializedSize() const {
|
size_t DeviceTmReportingWrapper::getSerializedSize() const {
|
||||||
return sizeof(objectId) + sizeof(ActionId_t) + data->getSerializedSize();
|
return sizeof(objectId) + sizeof(ActionId_t) + data.getSerializedSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t DeviceTmReportingWrapper::deSerialize(const uint8_t** buffer, size_t* size,
|
ReturnValue_t DeviceTmReportingWrapper::deSerialize(const uint8_t** buffer, size_t* size,
|
||||||
Endianness streamEndianness) {
|
Endianness streamEndianness) {
|
||||||
ReturnValue_t result = SerializeAdapter::deSerialize(&objectId, buffer, size, streamEndianness);
|
return returnvalue::FAILED;
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = SerializeAdapter::deSerialize(&actionId, buffer, size, streamEndianness);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return data->deSerialize(buffer, size, streamEndianness);
|
|
||||||
}
|
}
|
||||||
|
@ -7,21 +7,22 @@
|
|||||||
|
|
||||||
class DeviceTmReportingWrapper : public SerializeIF {
|
class DeviceTmReportingWrapper : public SerializeIF {
|
||||||
public:
|
public:
|
||||||
DeviceTmReportingWrapper(object_id_t objectId, ActionId_t actionId, SerializeIF* data);
|
DeviceTmReportingWrapper(object_id_t objectId, ActionId_t actionId, const SerializeIF& data);
|
||||||
virtual ~DeviceTmReportingWrapper();
|
~DeviceTmReportingWrapper() override;
|
||||||
|
|
||||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||||
Endianness streamEndianness) const override;
|
Endianness streamEndianness) const override;
|
||||||
|
|
||||||
virtual size_t getSerializedSize() const override;
|
[[nodiscard]] size_t getSerializedSize() const override;
|
||||||
|
|
||||||
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
|
||||||
Endianness streamEndianness) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
object_id_t objectId;
|
object_id_t objectId;
|
||||||
ActionId_t actionId;
|
ActionId_t actionId;
|
||||||
SerializeIF* data;
|
const SerializeIF& data;
|
||||||
|
|
||||||
|
// Deserialization forbidden
|
||||||
|
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||||
|
Endianness streamEndianness) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_DEVICEHANDLERS_DEVICETMREPORTINGWRAPPER_H_ */
|
#endif /* FSFW_DEVICEHANDLERS_DEVICETMREPORTINGWRAPPER_H_ */
|
||||||
|
@ -4,8 +4,6 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "fwSubsystemIdRanges.h"
|
#include "fwSubsystemIdRanges.h"
|
||||||
// could be moved to more suitable location
|
|
||||||
#include <events/subsystemIdRanges.h>
|
|
||||||
|
|
||||||
using EventId_t = uint16_t;
|
using EventId_t = uint16_t;
|
||||||
using EventSeverity_t = uint8_t;
|
using EventSeverity_t = uint8_t;
|
||||||
|
@ -12,7 +12,7 @@ MessageQueueMessage::MessageQueueMessage() : messageSize(getMinimumMessageSize()
|
|||||||
MessageQueueMessage::MessageQueueMessage(uint8_t* data, size_t size)
|
MessageQueueMessage::MessageQueueMessage(uint8_t* data, size_t size)
|
||||||
: messageSize(MessageQueueMessage::HEADER_SIZE + size) {
|
: messageSize(MessageQueueMessage::HEADER_SIZE + size) {
|
||||||
if (size <= MessageQueueMessage::MAX_DATA_SIZE) {
|
if (size <= MessageQueueMessage::MAX_DATA_SIZE) {
|
||||||
std::memcpy(internalBuffer + MessageQueueMessage::HEADER_SIZE, data, size);
|
std::memcpy(MessageQueueMessage::getData(), data, size);
|
||||||
this->messageSize = MessageQueueMessage::HEADER_SIZE + size;
|
this->messageSize = MessageQueueMessage::HEADER_SIZE + size;
|
||||||
} else {
|
} else {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "../serialize/SerialLinkedListAdapter.h"
|
#include "../serialize/SerialLinkedListAdapter.h"
|
||||||
#include "../serialize/SerializeElement.h"
|
#include "../serialize/SerializeElement.h"
|
||||||
#include "../serviceinterface/ServiceInterface.h"
|
#include "../serviceinterface/ServiceInterface.h"
|
||||||
#include "../timemanager/TimeStamperIF.h"
|
#include "../timemanager/TimeWriterIF.h"
|
||||||
#include "HasMonitorsIF.h"
|
#include "HasMonitorsIF.h"
|
||||||
#include "MonitoringIF.h"
|
#include "MonitoringIF.h"
|
||||||
#include "monitoringConf.h"
|
#include "monitoringConf.h"
|
||||||
@ -34,9 +34,9 @@ class MonitoringReportContent : public SerialLinkedListAdapter<SerializeIF> {
|
|||||||
SerializeElement<T> limitValue;
|
SerializeElement<T> limitValue;
|
||||||
SerializeElement<ReturnValue_t> oldState;
|
SerializeElement<ReturnValue_t> oldState;
|
||||||
SerializeElement<ReturnValue_t> newState;
|
SerializeElement<ReturnValue_t> newState;
|
||||||
uint8_t rawTimestamp[TimeStamperIF::MAXIMUM_TIMESTAMP_LEN] = {};
|
uint8_t rawTimestamp[TimeWriterIF::MAXIMUM_TIMESTAMP_LEN] = {};
|
||||||
SerializeElement<SerialBufferAdapter<uint8_t>> timestampSerializer;
|
SerializeElement<SerialBufferAdapter<uint8_t>> timestampSerializer;
|
||||||
TimeStamperIF* timeStamper;
|
TimeWriterIF* timeStamper;
|
||||||
MonitoringReportContent()
|
MonitoringReportContent()
|
||||||
: SerialLinkedListAdapter<SerializeIF>(¶meterObjectId),
|
: SerialLinkedListAdapter<SerializeIF>(¶meterObjectId),
|
||||||
monitorId(0),
|
monitorId(0),
|
||||||
@ -79,7 +79,7 @@ class MonitoringReportContent : public SerialLinkedListAdapter<SerializeIF> {
|
|||||||
}
|
}
|
||||||
bool checkAndSetStamper() {
|
bool checkAndSetStamper() {
|
||||||
if (timeStamper == nullptr) {
|
if (timeStamper == nullptr) {
|
||||||
timeStamper = ObjectManager::instance()->get<TimeStamperIF>(timeStamperId);
|
timeStamper = ObjectManager::instance()->get<TimeWriterIF>(timeStamperId);
|
||||||
if (timeStamper == nullptr) {
|
if (timeStamper == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "MonitoringReportContent::checkAndSetStamper: "
|
sif::error << "MonitoringReportContent::checkAndSetStamper: "
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
TcpTmTcBridge::TcpTmTcBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId,
|
TcpTmTcBridge::TcpTmTcBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId,
|
||||||
object_id_t tcStoreId)
|
object_id_t tcStoreId)
|
||||||
: TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) {
|
: TmTcBridge("TCP TMTC Bridge", objectId, tcDestination, tmStoreId, tcStoreId) {
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
// Connection is always up, TM is requested by connecting to server and receiving packets
|
// Connection is always up, TM is requested by connecting to server and receiving packets
|
||||||
registerCommConnect();
|
registerCommConnect();
|
||||||
|
@ -161,7 +161,7 @@ void TcpTmTcServer::handleServerOperation(socket_t& connSocket) {
|
|||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
ssize_t retval = recv(connSocket, reinterpret_cast<char*>(receptionBuffer.data()),
|
ssize_t retval = recv(connSocket, reinterpret_cast<char*>(receptionBuffer.data()),
|
||||||
receptionBuffer.capacity(), tcpConfig.tcpFlags);
|
receptionBuffer.size(), tcpConfig.tcpFlags);
|
||||||
if (retval == 0) {
|
if (retval == 0) {
|
||||||
size_t availableReadData = ringBuffer.getAvailableReadData();
|
size_t availableReadData = ringBuffer.getAvailableReadData();
|
||||||
if (availableReadData > lastRingBufferSize) {
|
if (availableReadData > lastRingBufferSize) {
|
||||||
@ -335,31 +335,27 @@ ReturnValue_t TcpTmTcServer::handleTcRingBufferData(size_t availableReadData) {
|
|||||||
}
|
}
|
||||||
ringBuffer.readData(receptionBuffer.data(), readAmount, true);
|
ringBuffer.readData(receptionBuffer.data(), readAmount, true);
|
||||||
const uint8_t* bufPtr = receptionBuffer.data();
|
const uint8_t* bufPtr = receptionBuffer.data();
|
||||||
const uint8_t** bufPtrPtr = &bufPtr;
|
SpacePacketParser::FoundPacketInfo info;
|
||||||
size_t startIdx = 0;
|
if (spacePacketParser == nullptr) {
|
||||||
size_t foundSize = 0;
|
return returnvalue::FAILED;
|
||||||
size_t readLen = 0;
|
}
|
||||||
while (readLen < readAmount) {
|
spacePacketParser->reset();
|
||||||
if (spacePacketParser == nullptr) {
|
while (spacePacketParser->getAmountRead() < readAmount) {
|
||||||
return returnvalue::FAILED;
|
result = spacePacketParser->parseSpacePackets(&bufPtr, readAmount, info);
|
||||||
}
|
|
||||||
result =
|
|
||||||
spacePacketParser->parseSpacePackets(bufPtrPtr, readAmount, startIdx, foundSize, readLen);
|
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case (SpacePacketParser::NO_PACKET_FOUND):
|
case (SpacePacketParser::NO_PACKET_FOUND):
|
||||||
case (SpacePacketParser::SPLIT_PACKET): {
|
case (SpacePacketParser::SPLIT_PACKET): {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (returnvalue::OK): {
|
case (returnvalue::OK): {
|
||||||
result = handleTcReception(receptionBuffer.data() + startIdx, foundSize);
|
result = handleTcReception(receptionBuffer.data() + info.startIdx, info.sizeFound);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
status = result;
|
status = result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ringBuffer.deleteData(foundSize);
|
ringBuffer.deleteData(info.sizeFound);
|
||||||
lastRingBufferSize = ringBuffer.getAvailableReadData();
|
lastRingBufferSize = ringBuffer.getAvailableReadData();
|
||||||
std::memset(receptionBuffer.data() + startIdx, 0, foundSize);
|
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ const std::string UdpTmTcBridge::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_POR
|
|||||||
UdpTmTcBridge::UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination,
|
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)
|
object_id_t tcStoreId)
|
||||||
: TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) {
|
: TmTcBridge("UDP TMTC Bridge", objectId, tcDestination, tmStoreId, tcStoreId) {
|
||||||
if (udpServerPort_.empty()) {
|
if (udpServerPort_.empty()) {
|
||||||
udpServerPort = DEFAULT_SERVER_PORT;
|
udpServerPort = DEFAULT_SERVER_PORT;
|
||||||
} else {
|
} else {
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
CService200ModeCommanding::CService200ModeCommanding(object_id_t objectId, uint16_t apid,
|
CService200ModeCommanding::CService200ModeCommanding(object_id_t objectId, uint16_t apid,
|
||||||
uint8_t serviceId, uint8_t numParallelCommands,
|
uint8_t serviceId, uint8_t numParallelCommands,
|
||||||
uint16_t commandTimeoutSeconds)
|
uint16_t commandTimeoutSeconds)
|
||||||
: CommandingServiceBase(objectId, apid, serviceId, numParallelCommands, commandTimeoutSeconds) {
|
: CommandingServiceBase(objectId, apid, "PUS 200 Mode MGMT", serviceId, numParallelCommands,
|
||||||
}
|
commandTimeoutSeconds) {}
|
||||||
|
|
||||||
CService200ModeCommanding::~CService200ModeCommanding() {}
|
CService200ModeCommanding::~CService200ModeCommanding() {}
|
||||||
|
|
||||||
|
@ -10,8 +10,8 @@ CService201HealthCommanding::CService201HealthCommanding(object_id_t objectId, u
|
|||||||
uint8_t serviceId,
|
uint8_t serviceId,
|
||||||
uint8_t numParallelCommands,
|
uint8_t numParallelCommands,
|
||||||
uint16_t commandTimeoutSeconds)
|
uint16_t commandTimeoutSeconds)
|
||||||
: CommandingServiceBase(objectId, apid, serviceId, numParallelCommands, commandTimeoutSeconds) {
|
: CommandingServiceBase(objectId, apid, "PUS 201 Health MGMT", serviceId, numParallelCommands,
|
||||||
}
|
commandTimeoutSeconds) {}
|
||||||
|
|
||||||
ReturnValue_t CService201HealthCommanding::isValidSubservice(uint8_t subservice) {
|
ReturnValue_t CService201HealthCommanding::isValidSubservice(uint8_t subservice) {
|
||||||
switch (subservice) {
|
switch (subservice) {
|
||||||
|
@ -38,8 +38,9 @@ class Service11TelecommandScheduling final : public PusServiceBase {
|
|||||||
static constexpr uint8_t CLASS_ID = CLASS_ID::PUS_SERVICE_11;
|
static constexpr uint8_t CLASS_ID = CLASS_ID::PUS_SERVICE_11;
|
||||||
|
|
||||||
static constexpr ReturnValue_t INVALID_TYPE_TIME_WINDOW = returnvalue::makeCode(CLASS_ID, 1);
|
static constexpr ReturnValue_t INVALID_TYPE_TIME_WINDOW = returnvalue::makeCode(CLASS_ID, 1);
|
||||||
static constexpr ReturnValue_t TIMESHIFTING_NOT_POSSIBLE = returnvalue::makeCode(CLASS_ID, 2);
|
static constexpr ReturnValue_t INVALID_TIME_WINDOW = returnvalue::makeCode(CLASS_ID, 2);
|
||||||
static constexpr ReturnValue_t INVALID_RELATIVE_TIME = returnvalue::makeCode(CLASS_ID, 3);
|
static constexpr ReturnValue_t TIMESHIFTING_NOT_POSSIBLE = returnvalue::makeCode(CLASS_ID, 3);
|
||||||
|
static constexpr ReturnValue_t INVALID_RELATIVE_TIME = returnvalue::makeCode(CLASS_ID, 4);
|
||||||
|
|
||||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_11;
|
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_11;
|
||||||
|
|
||||||
|
@ -16,7 +16,9 @@ inline Service11TelecommandScheduling<MAX_NUM_TCS>::Service11TelecommandScheduli
|
|||||||
: PusServiceBase(params),
|
: PusServiceBase(params),
|
||||||
RELEASE_TIME_MARGIN_SECONDS(releaseTimeMarginSeconds),
|
RELEASE_TIME_MARGIN_SECONDS(releaseTimeMarginSeconds),
|
||||||
debugMode(debugMode),
|
debugMode(debugMode),
|
||||||
tcRecipient(tcRecipient) {}
|
tcRecipient(tcRecipient) {
|
||||||
|
params.name = "PUS 11 TC Scheduling";
|
||||||
|
}
|
||||||
|
|
||||||
template <size_t MAX_NUM_TCS>
|
template <size_t MAX_NUM_TCS>
|
||||||
inline Service11TelecommandScheduling<MAX_NUM_TCS>::~Service11TelecommandScheduling() = default;
|
inline Service11TelecommandScheduling<MAX_NUM_TCS>::~Service11TelecommandScheduling() = default;
|
||||||
@ -564,12 +566,17 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::getMapFilterFr
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
if (fromTimestamp > toTimestamp) {
|
||||||
|
return INVALID_TIME_WINDOW;
|
||||||
|
}
|
||||||
itBegin = telecommandMap.begin();
|
itBegin = telecommandMap.begin();
|
||||||
itEnd = telecommandMap.begin();
|
|
||||||
|
|
||||||
while (itBegin->first < fromTimestamp && itBegin != telecommandMap.end()) {
|
while (itBegin->first < fromTimestamp && itBegin != telecommandMap.end()) {
|
||||||
itBegin++;
|
itBegin++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// start looking for end beginning at begin
|
||||||
|
itEnd = itBegin;
|
||||||
while (itEnd->first <= toTimestamp && itEnd != telecommandMap.end()) {
|
while (itEnd->first <= toTimestamp && itEnd != telecommandMap.end()) {
|
||||||
itEnd++;
|
itEnd++;
|
||||||
}
|
}
|
||||||
@ -579,16 +586,6 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::getMapFilterFr
|
|||||||
default:
|
default:
|
||||||
return returnvalue::FAILED;
|
return returnvalue::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 returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// the map range should now be set according to the sent filter.
|
// the map range should now be set according to the sent filter.
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,9 @@
|
|||||||
Service17Test::Service17Test(PsbParams params)
|
Service17Test::Service17Test(PsbParams params)
|
||||||
: PusServiceBase(params),
|
: PusServiceBase(params),
|
||||||
storeHelper(params.apid),
|
storeHelper(params.apid),
|
||||||
tmHelper(params.serviceId, storeHelper, sendHelper) {}
|
tmHelper(params.serviceId, storeHelper, sendHelper) {
|
||||||
|
params.name = "PUS 17 Test";
|
||||||
|
}
|
||||||
|
|
||||||
Service17Test::~Service17Test() = default;
|
Service17Test::~Service17Test() = default;
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ Service1TelecommandVerification::Service1TelecommandVerification(object_id_t obj
|
|||||||
uint16_t apid, uint8_t serviceId,
|
uint16_t apid, uint8_t serviceId,
|
||||||
object_id_t targetDestination,
|
object_id_t targetDestination,
|
||||||
uint16_t messageQueueDepth,
|
uint16_t messageQueueDepth,
|
||||||
TimeStamperIF* timeStamper)
|
TimeWriterIF* timeStamper)
|
||||||
: SystemObject(objectId),
|
: SystemObject(objectId),
|
||||||
apid(apid),
|
apid(apid),
|
||||||
serviceId(serviceId),
|
serviceId(serviceId),
|
||||||
@ -134,7 +134,7 @@ ReturnValue_t Service1TelecommandVerification::initialize() {
|
|||||||
storeHelper.setTmStore(*tmStore);
|
storeHelper.setTmStore(*tmStore);
|
||||||
}
|
}
|
||||||
if (timeStamper == nullptr) {
|
if (timeStamper == nullptr) {
|
||||||
timeStamper = ObjectManager::instance()->get<TimeStamperIF>(objects::TIME_STAMPER);
|
timeStamper = ObjectManager::instance()->get<TimeWriterIF>(objects::TIME_STAMPER);
|
||||||
if (timeStamper == nullptr) {
|
if (timeStamper == nullptr) {
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ class Service1TelecommandVerification : public AcceptsVerifyMessageIF,
|
|||||||
|
|
||||||
Service1TelecommandVerification(object_id_t objectId, uint16_t apid, uint8_t serviceId,
|
Service1TelecommandVerification(object_id_t objectId, uint16_t apid, uint8_t serviceId,
|
||||||
object_id_t targetDestination, uint16_t messageQueueDepth,
|
object_id_t targetDestination, uint16_t messageQueueDepth,
|
||||||
TimeStamperIF* timeStamper = nullptr);
|
TimeWriterIF* timeStamper = nullptr);
|
||||||
~Service1TelecommandVerification() override;
|
~Service1TelecommandVerification() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -87,7 +87,7 @@ class Service1TelecommandVerification : public AcceptsVerifyMessageIF,
|
|||||||
TmStoreHelper storeHelper;
|
TmStoreHelper storeHelper;
|
||||||
TmStoreAndSendWrapper tmHelper;
|
TmStoreAndSendWrapper tmHelper;
|
||||||
InternalErrorReporterIF* errReporter = nullptr;
|
InternalErrorReporterIF* errReporter = nullptr;
|
||||||
TimeStamperIF* timeStamper = nullptr;
|
TimeWriterIF* timeStamper = nullptr;
|
||||||
StorageManagerIF* tmStore = nullptr;
|
StorageManagerIF* tmStore = nullptr;
|
||||||
MessageQueueIF* tmQueue = nullptr;
|
MessageQueueIF* tmQueue = nullptr;
|
||||||
|
|
||||||
|
@ -11,8 +11,8 @@ Service20ParameterManagement::Service20ParameterManagement(object_id_t objectId,
|
|||||||
uint8_t serviceId,
|
uint8_t serviceId,
|
||||||
uint8_t numberOfParallelCommands,
|
uint8_t numberOfParallelCommands,
|
||||||
uint16_t commandTimeoutSeconds)
|
uint16_t commandTimeoutSeconds)
|
||||||
: CommandingServiceBase(objectId, apid, serviceId, numberOfParallelCommands,
|
: CommandingServiceBase(objectId, apid, "PUS 20 Parameter MGMT", serviceId,
|
||||||
commandTimeoutSeconds) {}
|
numberOfParallelCommands, commandTimeoutSeconds) {}
|
||||||
|
|
||||||
Service20ParameterManagement::~Service20ParameterManagement() = default;
|
Service20ParameterManagement::~Service20ParameterManagement() = default;
|
||||||
|
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
Service2DeviceAccess::Service2DeviceAccess(object_id_t objectId, uint16_t apid, uint8_t serviceId,
|
Service2DeviceAccess::Service2DeviceAccess(object_id_t objectId, uint16_t apid, uint8_t serviceId,
|
||||||
uint8_t numberOfParallelCommands,
|
uint8_t numberOfParallelCommands,
|
||||||
uint16_t commandTimeoutSeconds)
|
uint16_t commandTimeoutSeconds)
|
||||||
: CommandingServiceBase(objectId, apid, serviceId, numberOfParallelCommands,
|
: CommandingServiceBase(objectId, apid, "PUS 2 Raw Commanding", serviceId,
|
||||||
commandTimeoutSeconds) {}
|
numberOfParallelCommands, commandTimeoutSeconds) {}
|
||||||
|
|
||||||
Service2DeviceAccess::~Service2DeviceAccess() {}
|
Service2DeviceAccess::~Service2DeviceAccess() {}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include "fsfw/pus/servicepackets/Service3Packets.h"
|
#include "fsfw/pus/servicepackets/Service3Packets.h"
|
||||||
|
|
||||||
Service3Housekeeping::Service3Housekeeping(object_id_t objectId, uint16_t apid, uint8_t serviceId)
|
Service3Housekeeping::Service3Housekeeping(object_id_t objectId, uint16_t apid, uint8_t serviceId)
|
||||||
: CommandingServiceBase(objectId, apid, serviceId, NUM_OF_PARALLEL_COMMANDS,
|
: CommandingServiceBase(objectId, apid, "PUS 3 HK", serviceId, NUM_OF_PARALLEL_COMMANDS,
|
||||||
COMMAND_TIMEOUT_SECONDS) {}
|
COMMAND_TIMEOUT_SECONDS) {}
|
||||||
|
|
||||||
Service3Housekeeping::~Service3Housekeeping() {}
|
Service3Housekeeping::~Service3Housekeeping() {}
|
||||||
|
@ -13,6 +13,7 @@ Service5EventReporting::Service5EventReporting(PsbParams params, size_t maxNumbe
|
|||||||
storeHelper(params.apid),
|
storeHelper(params.apid),
|
||||||
tmHelper(params.serviceId, storeHelper, sendHelper),
|
tmHelper(params.serviceId, storeHelper, sendHelper),
|
||||||
maxNumberReportsPerCycle(maxNumberReportsPerCycle) {
|
maxNumberReportsPerCycle(maxNumberReportsPerCycle) {
|
||||||
|
psbParams.name = "PUS 5 Event Reporting";
|
||||||
eventQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth);
|
eventQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,8 +12,8 @@ Service8FunctionManagement::Service8FunctionManagement(object_id_t objectId, uin
|
|||||||
uint8_t serviceId,
|
uint8_t serviceId,
|
||||||
uint8_t numParallelCommands,
|
uint8_t numParallelCommands,
|
||||||
uint16_t commandTimeoutSeconds)
|
uint16_t commandTimeoutSeconds)
|
||||||
: CommandingServiceBase(objectId, apid, serviceId, numParallelCommands, commandTimeoutSeconds) {
|
: CommandingServiceBase(objectId, apid, "PUS 8 Functional Commanding", serviceId,
|
||||||
}
|
numParallelCommands, commandTimeoutSeconds) {}
|
||||||
|
|
||||||
Service8FunctionManagement::~Service8FunctionManagement() {}
|
Service8FunctionManagement::~Service8FunctionManagement() {}
|
||||||
|
|
||||||
|
@ -5,7 +5,9 @@
|
|||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
#include "fsfw/timemanager/CCSDSTime.h"
|
#include "fsfw/timemanager/CCSDSTime.h"
|
||||||
|
|
||||||
Service9TimeManagement::Service9TimeManagement(PsbParams params) : PusServiceBase(params) {}
|
Service9TimeManagement::Service9TimeManagement(PsbParams params) : PusServiceBase(params) {
|
||||||
|
params.name = "PUS 9 Time MGMT";
|
||||||
|
}
|
||||||
|
|
||||||
Service9TimeManagement::~Service9TimeManagement() = default;
|
Service9TimeManagement::~Service9TimeManagement() = default;
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
#ifndef FSFW_RETURNVALUES_RETURNVALUE_H_
|
#ifndef FSFW_RETURNVALUES_RETURNVALUE_H_
|
||||||
#define FSFW_RETURNVALUES_RETURNVALUE_H_
|
#define FSFW_RETURNVALUES_RETURNVALUE_H_
|
||||||
|
|
||||||
#include <returnvalues/classIds.h>
|
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#include "FwClassIds.h"
|
#include "FwClassIds.h"
|
||||||
|
@ -21,7 +21,7 @@ SerialBufferAdapter<count_t>::SerialBufferAdapter(uint8_t* buffer, count_t buffe
|
|||||||
bufferLength(bufferLength) {}
|
bufferLength(bufferLength) {}
|
||||||
|
|
||||||
template <typename count_t>
|
template <typename count_t>
|
||||||
SerialBufferAdapter<count_t>::~SerialBufferAdapter() {}
|
SerialBufferAdapter<count_t>::~SerialBufferAdapter() = default;
|
||||||
|
|
||||||
template <typename count_t>
|
template <typename count_t>
|
||||||
ReturnValue_t SerialBufferAdapter<count_t>::serialize(uint8_t** buffer, size_t* size,
|
ReturnValue_t SerialBufferAdapter<count_t>::serialize(uint8_t** buffer, size_t* size,
|
||||||
@ -119,10 +119,10 @@ const uint8_t* SerialBufferAdapter<count_t>::getConstBuffer() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename count_t>
|
template <typename count_t>
|
||||||
void SerialBufferAdapter<count_t>::setBuffer(uint8_t* buffer, count_t bufferLength) {
|
void SerialBufferAdapter<count_t>::setConstBuffer(const uint8_t* buf, count_t bufLen) {
|
||||||
this->buffer = buffer;
|
this->buffer = nullptr;
|
||||||
this->constBuffer = buffer;
|
this->bufferLength = bufLen;
|
||||||
this->bufferLength = bufferLength;
|
this->constBuffer = buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
// forward Template declaration for linker
|
// forward Template declaration for linker
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
template <typename count_t>
|
template <typename count_t>
|
||||||
class SerialBufferAdapter : public SerializeIF {
|
class SerialBufferAdapter : public SerializeIF {
|
||||||
public:
|
public:
|
||||||
|
SerialBufferAdapter() = default;
|
||||||
/**
|
/**
|
||||||
* Constructor for constant uint8_t buffer. Length field can be serialized optionally.
|
* Constructor for constant uint8_t buffer. Length field can be serialized optionally.
|
||||||
* Type of length can be supplied as template type.
|
* Type of length can be supplied as template type.
|
||||||
@ -40,12 +41,12 @@ class SerialBufferAdapter : public SerializeIF {
|
|||||||
*/
|
*/
|
||||||
SerialBufferAdapter(uint8_t* buffer, count_t bufferLength, bool serializeLength = false);
|
SerialBufferAdapter(uint8_t* buffer, count_t bufferLength, bool serializeLength = false);
|
||||||
|
|
||||||
virtual ~SerialBufferAdapter();
|
~SerialBufferAdapter() override;
|
||||||
|
|
||||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||||
Endianness streamEndianness) const override;
|
Endianness streamEndianness) const override;
|
||||||
|
|
||||||
virtual size_t getSerializedSize() const override;
|
[[nodiscard]] size_t getSerializedSize() const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function deserializes a buffer into the member buffer.
|
* @brief This function deserializes a buffer into the member buffer.
|
||||||
@ -59,12 +60,12 @@ class SerialBufferAdapter : public SerializeIF {
|
|||||||
* @param bigEndian
|
* @param bigEndian
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||||
Endianness streamEndianness) override;
|
Endianness streamEndianness) override;
|
||||||
|
|
||||||
uint8_t* getBuffer();
|
uint8_t* getBuffer();
|
||||||
const uint8_t* getConstBuffer() const;
|
[[nodiscard]] const uint8_t* getConstBuffer() const;
|
||||||
void setBuffer(uint8_t* buffer, count_t bufferLength);
|
void setConstBuffer(const uint8_t* buf, count_t bufLen);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool serializeLength = false;
|
bool serializeLength = false;
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
#include "fsfw/serviceinterface/ServiceInterfaceBuffer.h"
|
#include "ServiceInterfaceBuffer.h"
|
||||||
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <cinttypes>
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "fsfw/serviceinterface/serviceInterfaceDefintions.h"
|
#include "fsfw/serviceinterface/serviceInterfaceDefintions.h"
|
||||||
@ -16,8 +15,6 @@
|
|||||||
// to be implemented by bsp
|
// to be implemented by bsp
|
||||||
extern "C" void printChar(const char*, bool errStream);
|
extern "C" void printChar(const char*, bool errStream);
|
||||||
|
|
||||||
#ifndef UT699
|
|
||||||
|
|
||||||
ServiceInterfaceBuffer::ServiceInterfaceBuffer(std::string setMessage, bool addCrToPreamble,
|
ServiceInterfaceBuffer::ServiceInterfaceBuffer(std::string setMessage, bool addCrToPreamble,
|
||||||
bool buffered, bool errStream, uint16_t port)
|
bool buffered, bool errStream, uint16_t port)
|
||||||
: isActive(true),
|
: isActive(true),
|
||||||
@ -58,6 +55,9 @@ ServiceInterfaceBuffer::ServiceInterfaceBuffer(std::string setMessage, bool addC
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ServiceInterfaceBuffer::putChars(char const* begin, char const* end) {
|
void ServiceInterfaceBuffer::putChars(char const* begin, char const* end) {
|
||||||
|
if (not isActive) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
char array[BUF_SIZE];
|
char array[BUF_SIZE];
|
||||||
uint32_t length = end - begin;
|
uint32_t length = end - begin;
|
||||||
if (length > sizeof(array)) {
|
if (length > sizeof(array)) {
|
||||||
@ -74,8 +74,6 @@ void ServiceInterfaceBuffer::putChars(char const* begin, char const* end) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int ServiceInterfaceBuffer::overflow(int c) {
|
int ServiceInterfaceBuffer::overflow(int c) {
|
||||||
if (not buffered and this->isActive) {
|
if (not buffered and this->isActive) {
|
||||||
if (c != Traits::eof()) {
|
if (c != Traits::eof()) {
|
||||||
@ -169,89 +167,4 @@ void ServiceInterfaceBuffer::setAsciiColorPrefix(std::string colorPrefix) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef UT699
|
#endif
|
||||||
#include "../osal/rtems/Interrupt.h"
|
|
||||||
|
|
||||||
ServiceInterfaceBuffer::ServiceInterfaceBuffer(std::string set_message, uint16_t port) {
|
|
||||||
this->log_message = set_message;
|
|
||||||
this->isActive = true;
|
|
||||||
setp(buf, buf + BUF_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServiceInterfaceBuffer::putChars(char const* begin, char const* end) {
|
|
||||||
char array[BUF_SIZE];
|
|
||||||
uint32_t length = end - begin;
|
|
||||||
if (length > sizeof(array)) {
|
|
||||||
length = sizeof(array);
|
|
||||||
}
|
|
||||||
memcpy(array, begin, length);
|
|
||||||
|
|
||||||
if (!Interrupt::isInterruptInProgress()) {
|
|
||||||
std::cout << array;
|
|
||||||
} else {
|
|
||||||
// Uncomment the following line if you need ISR debug output.
|
|
||||||
// printk(array);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // UT699
|
|
||||||
|
|
||||||
#ifdef ML505
|
|
||||||
#include <bsp_flp/network/networkconfig.h>
|
|
||||||
ServiceInterfaceBuffer::ServiceInterfaceBuffer(std::string set_message, uint16_t port)
|
|
||||||
: isActive(true),
|
|
||||||
log_message(set_message),
|
|
||||||
udpSocket(0),
|
|
||||||
remoteAddressLength(sizeof(remoteAddress)) {
|
|
||||||
setp(buf, buf + BUF_SIZE);
|
|
||||||
memset((uint8_t*)&remoteAddress, 0, sizeof(remoteAddress));
|
|
||||||
remoteAddress.sin_family = AF_INET;
|
|
||||||
remoteAddress.sin_port = htons(port);
|
|
||||||
remoteAddress.sin_addr.s_addr = htonl(inet_addr("192.168.250.100"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServiceInterfaceBuffer::putChars(char const* begin, char const* end) {
|
|
||||||
char array[BUF_SIZE];
|
|
||||||
uint32_t length = end - begin;
|
|
||||||
if (length > sizeof(array)) {
|
|
||||||
length = sizeof(array);
|
|
||||||
}
|
|
||||||
memcpy(array, begin, length);
|
|
||||||
|
|
||||||
if (udpSocket <= 0) {
|
|
||||||
initSocket();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (udpSocket > 0) {
|
|
||||||
sendto(udpSocket, array, length, 0, (sockaddr*)&remoteAddress, sizeof(remoteAddress));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServiceInterfaceBuffer::initSocket() {
|
|
||||||
sockaddr_in address;
|
|
||||||
memset((uint8_t*)&address, 0, sizeof(address));
|
|
||||||
address.sin_family = AF_INET;
|
|
||||||
address.sin_port = htons(0);
|
|
||||||
address.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
||||||
|
|
||||||
udpSocket = socket(PF_INET, SOCK_DGRAM, 0);
|
|
||||||
if (socket < 0) {
|
|
||||||
printf("Error opening socket!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
timeval timeout = {0, 20};
|
|
||||||
if (setsockopt(udpSocket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0) {
|
|
||||||
printf("Error setting SO_RCVTIMEO socket options!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (setsockopt(udpSocket, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) < 0) {
|
|
||||||
printf("Error setting SO_SNDTIMEO socket options!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (bind(udpSocket, (sockaddr*)&address, sizeof(address)) < 0) {
|
|
||||||
printf("Error binding socket!\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // ML505
|
|
||||||
|
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
#ifndef FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACEBUFFER_H_
|
#ifndef FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACEBUFFER_H_
|
||||||
#define FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACEBUFFER_H_
|
#define FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACEBUFFER_H_
|
||||||
|
|
||||||
#include <FSFWConfig.h>
|
#include "fsfw/FSFW.h"
|
||||||
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
#include "../returnvalues/returnvalue.h"
|
|
||||||
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
|
||||||
@ -11,8 +10,6 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#ifndef UT699
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This is the underlying stream buffer which implements the
|
* @brief This is the underlying stream buffer which implements the
|
||||||
* streambuf class and overloads the overflow() and sync() methods
|
* streambuf class and overloads the overflow() and sync() methods
|
||||||
@ -77,85 +74,6 @@ class ServiceInterfaceBuffer : public std::streambuf {
|
|||||||
bool crAdditionEnabled() const;
|
bool crAdditionEnabled() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UT699
|
|
||||||
class ServiceInterfaceBuffer : public std::basic_streambuf<char, std::char_traits<char> > {
|
|
||||||
friend class ServiceInterfaceStream;
|
|
||||||
|
|
||||||
public:
|
|
||||||
ServiceInterfaceBuffer(std::string set_message, uint16_t port);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool isActive;
|
|
||||||
// This is called when buffer becomes full. If
|
|
||||||
// buffer is not used, then this is called every
|
|
||||||
// time when characters are put to stream.
|
|
||||||
virtual int overflow(int c = Traits::eof());
|
|
||||||
|
|
||||||
// This function is called when stream is flushed,
|
|
||||||
// for example when std::endl is put to stream.
|
|
||||||
virtual int sync(void);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// For additional message information
|
|
||||||
std::string log_message;
|
|
||||||
// For EOF detection
|
|
||||||
typedef std::char_traits<char> Traits;
|
|
||||||
|
|
||||||
// Work in buffer mode. It is also possible to work without buffer.
|
|
||||||
static size_t const BUF_SIZE = 128;
|
|
||||||
char buf[BUF_SIZE];
|
|
||||||
|
|
||||||
// In this function, the characters are parsed.
|
|
||||||
void putChars(char const* begin, char const* end);
|
|
||||||
};
|
|
||||||
#endif // UT699
|
|
||||||
|
|
||||||
#ifdef ML505
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <netinet/udp.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
class ServiceInterfaceBuffer : public std::basic_streambuf<char, std::char_traits<char> > {
|
|
||||||
friend class ServiceInterfaceStream;
|
|
||||||
|
|
||||||
public:
|
|
||||||
ServiceInterfaceBuffer(std::string set_message, uint16_t port);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool isActive;
|
|
||||||
// This is called when buffer becomes full. If
|
|
||||||
// buffer is not used, then this is called every
|
|
||||||
// time when characters are put to stream.
|
|
||||||
virtual int overflow(int c = Traits::eof());
|
|
||||||
|
|
||||||
// This function is called when stream is flushed,
|
|
||||||
// for example when std::endl is put to stream.
|
|
||||||
virtual int sync(void);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// For additional message information
|
|
||||||
std::string log_message;
|
|
||||||
// For EOF detection
|
|
||||||
typedef std::char_traits<char> Traits;
|
|
||||||
|
|
||||||
// Work in buffer mode. It is also possible to work without buffer.
|
|
||||||
static size_t const BUF_SIZE = 128;
|
|
||||||
char buf[BUF_SIZE];
|
|
||||||
|
|
||||||
// In this function, the characters are parsed.
|
|
||||||
void putChars(char const* begin, char const* end);
|
|
||||||
|
|
||||||
int udpSocket;
|
|
||||||
sockaddr_in remoteAddress;
|
|
||||||
socklen_t remoteAddressLength;
|
|
||||||
void initSocket();
|
|
||||||
};
|
|
||||||
#endif // ML505
|
|
||||||
|
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||||
|
|
||||||
#endif /* FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACEBUFFER_H_ */
|
#endif /* FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACEBUFFER_H_ */
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
#ifndef FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACESTREAM_H_
|
#ifndef FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACESTREAM_H_
|
||||||
#define FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACESTREAM_H_
|
#define FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACESTREAM_H_
|
||||||
|
|
||||||
#include <FSFWConfig.h>
|
|
||||||
|
|
||||||
#include "ServiceInterfaceBuffer.h"
|
#include "ServiceInterfaceBuffer.h"
|
||||||
|
#include "fsfw/FSFW.h"
|
||||||
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ TcDistributor::TcMqMapIter CCSDSDistributor::selectDestination() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t CCSDSDistributor::getRequestQueue() { return tcQueue->getId(); }
|
MessageQueueId_t CCSDSDistributor::getRequestQueue() const { return tcQueue->getId(); }
|
||||||
|
|
||||||
ReturnValue_t CCSDSDistributor::registerApplication(AcceptsTelecommandsIF* application) {
|
ReturnValue_t CCSDSDistributor::registerApplication(AcceptsTelecommandsIF* application) {
|
||||||
ReturnValue_t returnValue = returnvalue::OK;
|
ReturnValue_t returnValue = returnvalue::OK;
|
||||||
@ -80,7 +80,7 @@ ReturnValue_t CCSDSDistributor::registerApplication(uint16_t apid, MessageQueueI
|
|||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t CCSDSDistributor::getIdentifier() { return 0; }
|
uint32_t CCSDSDistributor::getIdentifier() const { return 0; }
|
||||||
|
|
||||||
ReturnValue_t CCSDSDistributor::initialize() {
|
ReturnValue_t CCSDSDistributor::initialize() {
|
||||||
if (packetChecker == nullptr) {
|
if (packetChecker == nullptr) {
|
||||||
|
@ -35,10 +35,10 @@ class CCSDSDistributor : public TcDistributor,
|
|||||||
*/
|
*/
|
||||||
~CCSDSDistributor() override;
|
~CCSDSDistributor() override;
|
||||||
|
|
||||||
MessageQueueId_t getRequestQueue() override;
|
MessageQueueId_t getRequestQueue() const override;
|
||||||
ReturnValue_t registerApplication(uint16_t apid, MessageQueueId_t id) override;
|
ReturnValue_t registerApplication(uint16_t apid, MessageQueueId_t id) override;
|
||||||
ReturnValue_t registerApplication(AcceptsTelecommandsIF* application) override;
|
ReturnValue_t registerApplication(AcceptsTelecommandsIF* application) override;
|
||||||
uint16_t getIdentifier() override;
|
uint32_t getIdentifier() const override;
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
#include "../returnvalues/returnvalue.h"
|
#include "../returnvalues/returnvalue.h"
|
||||||
#include "../tmtcpacket/cfdp/CfdpPacketStored.h"
|
#include "../tmtcpacket/cfdp/CfdpPacketStored.h"
|
||||||
|
|
||||||
#include "../tmtcservices/AcceptsTelecommandsIF.h"
|
#include "../tmtcservices/AcceptsTelecommandsIF.h"
|
||||||
#include "../tmtcservices/VerificationReporter.h"
|
#include "../tmtcservices/VerificationReporter.h"
|
||||||
#include "CFDPDistributorIF.h"
|
#include "CFDPDistributorIF.h"
|
||||||
@ -34,9 +33,9 @@ class CFDPDistributor : public TcDistributor,
|
|||||||
*/
|
*/
|
||||||
~CFDPDistributor() override;
|
~CFDPDistributor() override;
|
||||||
ReturnValue_t registerHandler(AcceptsTelecommandsIF* handler) override;
|
ReturnValue_t registerHandler(AcceptsTelecommandsIF* handler) override;
|
||||||
MessageQueueId_t getRequestQueue() override;
|
MessageQueueId_t getRequestQueue() const override;
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
uint16_t getIdentifier() override;
|
uint32_t getIdentifier() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint16_t apid;
|
uint16_t apid;
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
target_sources(
|
target_sources(
|
||||||
${LIB_FSFW_NAME}
|
${LIB_FSFW_NAME}
|
||||||
PRIVATE CCSDSDistributor.cpp
|
PRIVATE CCSDSDistributor.cpp PusDistributor.cpp TcDistributor.cpp
|
||||||
PusDistributor.cpp
|
TcPacketCheckCFDP.cpp CcsdsPacketChecker.cpp)
|
||||||
TcDistributor.cpp
|
|
||||||
PusPacketChecker.cpp
|
|
||||||
TcPacketCheckCFDP.cpp
|
|
||||||
CFDPDistributor.cpp
|
|
||||||
CcsdsPacketChecker.cpp)
|
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
#ifndef FSFW_TCDISTRIBUTION_TCPACKETCHECKIF_H_
|
#ifndef FSFW_TCDISTRIBUTION_TCPACKETCHECKIF_H_
|
||||||
#define FSFW_TCDISTRIBUTION_TCPACKETCHECKIF_H_
|
#define FSFW_TCDISTRIBUTION_TCPACKETCHECKIF_H_
|
||||||
|
|
||||||
<<<<<<< HEAD:src/fsfw/tcdistribution/CcsdsPacketCheckIF.h
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
=======
|
|
||||||
#include "../returnvalues/returnvalue.h"
|
|
||||||
>>>>>>> origin/development:src/fsfw/tcdistribution/TcPacketCheckIF.h
|
|
||||||
|
|
||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
|
|
||||||
class SpacePacketReader;
|
class SpacePacketReader;
|
||||||
|
|
||||||
|
@ -97,13 +97,13 @@ ReturnValue_t PusDistributor::registerService(AcceptsTelecommandsIF* service) {
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t PusDistributor::getRequestQueue() { return tcQueue->getId(); }
|
MessageQueueId_t PusDistributor::getRequestQueue() const { return tcQueue->getId(); }
|
||||||
|
|
||||||
ReturnValue_t PusDistributor::callbackAfterSending(ReturnValue_t queueStatus) {
|
ReturnValue_t PusDistributor::callbackAfterSending(ReturnValue_t queueStatus) {
|
||||||
if (queueStatus != returnvalue::OK) {
|
if (queueStatus != returnvalue::OK) {
|
||||||
tcStatus = queueStatus;
|
tcStatus = queueStatus;
|
||||||
}
|
}
|
||||||
if (tcStatus != RETURN_OK) {
|
if (tcStatus != returnvalue::OK) {
|
||||||
verifyChannel->sendFailureReport({tcverif::ACCEPTANCE_FAILURE, reader, tcStatus});
|
verifyChannel->sendFailureReport({tcverif::ACCEPTANCE_FAILURE, reader, tcStatus});
|
||||||
// A failed packet is deleted immediately after reporting,
|
// A failed packet is deleted immediately after reporting,
|
||||||
// otherwise it will block memory.
|
// otherwise it will block memory.
|
||||||
@ -111,11 +111,11 @@ ReturnValue_t PusDistributor::callbackAfterSending(ReturnValue_t queueStatus) {
|
|||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
} else {
|
} else {
|
||||||
verifyChannel->sendSuccessReport({tcverif::ACCEPTANCE_SUCCESS, reader});
|
verifyChannel->sendSuccessReport({tcverif::ACCEPTANCE_SUCCESS, reader});
|
||||||
return RETURN_OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t PusDistributor::getIdentifier() { return checker.getApid(); }
|
uint32_t PusDistributor::getIdentifier() const { return checker.getApid(); }
|
||||||
|
|
||||||
ReturnValue_t PusDistributor::initialize() {
|
ReturnValue_t PusDistributor::initialize() {
|
||||||
if (store == nullptr) {
|
if (store == nullptr) {
|
||||||
|
@ -34,9 +34,9 @@ class PusDistributor : public TcDistributor, public PUSDistributorIF, public Acc
|
|||||||
*/
|
*/
|
||||||
~PusDistributor() override;
|
~PusDistributor() override;
|
||||||
ReturnValue_t registerService(AcceptsTelecommandsIF* service) override;
|
ReturnValue_t registerService(AcceptsTelecommandsIF* service) override;
|
||||||
MessageQueueId_t getRequestQueue() override;
|
MessageQueueId_t getRequestQueue() const override;
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
uint16_t getIdentifier() override;
|
uint32_t getIdentifier() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
StorageManagerIF* store;
|
StorageManagerIF* store;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define FSFW_TCDISTRIBUTION_TCPACKETCHECKPUS_H_
|
#define FSFW_TCDISTRIBUTION_TCPACKETCHECKPUS_H_
|
||||||
|
|
||||||
#include "fsfw/FSFW.h"
|
#include "fsfw/FSFW.h"
|
||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
#include "fsfw/tmtcpacket/pus/defs.h"
|
#include "fsfw/tmtcpacket/pus/defs.h"
|
||||||
#include "fsfw/tmtcservices/PusVerificationReport.h"
|
#include "fsfw/tmtcservices/PusVerificationReport.h"
|
||||||
|
|
||||||
|
@ -9,4 +9,3 @@ ReturnValue_t CfdpPacketChecker::checkPacket(const SpacePacketReader& currentPac
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint16_t CfdpPacketChecker::getApid() const { return apid; }
|
uint16_t CfdpPacketChecker::getApid() const { return apid; }
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#include "fsfw/returnvalues/FwClassIds.h"
|
#include "fsfw/returnvalues/FwClassIds.h"
|
||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
|
|
||||||
namespace tcdistrib {
|
namespace tcdistrib {
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::PACKET_CHECK;
|
static const uint8_t INTERFACE_ID = CLASS_ID::PACKET_CHECK;
|
||||||
@ -14,11 +14,11 @@ static constexpr ReturnValue_t INVALID_PACKET_TYPE = MAKE_RETURN_CODE(2);
|
|||||||
static constexpr ReturnValue_t INVALID_SEC_HEADER_FIELD = MAKE_RETURN_CODE(3);
|
static constexpr ReturnValue_t INVALID_SEC_HEADER_FIELD = MAKE_RETURN_CODE(3);
|
||||||
static constexpr ReturnValue_t INCORRECT_PRIMARY_HEADER = MAKE_RETURN_CODE(4);
|
static constexpr ReturnValue_t INCORRECT_PRIMARY_HEADER = MAKE_RETURN_CODE(4);
|
||||||
|
|
||||||
static constexpr ReturnValue_t INCOMPLETE_PACKET = MAKE_RETURN_CODE(5);
|
static constexpr ReturnValue_t INCOMPLETE_PACKET = MAKE_RETURN_CODE(7);
|
||||||
static constexpr ReturnValue_t INVALID_PUS_VERSION = MAKE_RETURN_CODE(6);
|
static constexpr ReturnValue_t INVALID_PUS_VERSION = MAKE_RETURN_CODE(8);
|
||||||
static constexpr ReturnValue_t INCORRECT_CHECKSUM = MAKE_RETURN_CODE(7);
|
static constexpr ReturnValue_t INCORRECT_CHECKSUM = MAKE_RETURN_CODE(9);
|
||||||
static constexpr ReturnValue_t ILLEGAL_PACKET_SUBTYPE = MAKE_RETURN_CODE(8);
|
static constexpr ReturnValue_t ILLEGAL_PACKET_SUBTYPE = MAKE_RETURN_CODE(10);
|
||||||
static constexpr ReturnValue_t INCORRECT_SECONDARY_HEADER = MAKE_RETURN_CODE(9);
|
static constexpr ReturnValue_t INCORRECT_SECONDARY_HEADER = MAKE_RETURN_CODE(11);
|
||||||
|
|
||||||
}; // namespace tcdistrib
|
}; // namespace tcdistrib
|
||||||
#endif // FSFW_TMTCPACKET_DEFINITIONS_H
|
#endif // FSFW_TMTCPACKET_DEFINITIONS_H
|
||||||
|
@ -39,13 +39,13 @@ class CCSDSTime {
|
|||||||
* Struct for CDS day-segmented format.
|
* Struct for CDS day-segmented format.
|
||||||
*/
|
*/
|
||||||
struct CDS_short {
|
struct CDS_short {
|
||||||
uint8_t pField;
|
uint8_t pField = P_FIELD_CDS_SHORT;
|
||||||
uint8_t dayMSB;
|
uint8_t dayMSB = 0;
|
||||||
uint8_t dayLSB;
|
uint8_t dayLSB = 0;
|
||||||
uint8_t msDay_hh;
|
uint8_t msDay_hh = 0;
|
||||||
uint8_t msDay_h;
|
uint8_t msDay_h = 0;
|
||||||
uint8_t msDay_l;
|
uint8_t msDay_l = 0;
|
||||||
uint8_t msDay_ll;
|
uint8_t msDay_ll = 0;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Struct for the CCS fromat in day of month variation with max resolution
|
* Struct for the CCS fromat in day of month variation with max resolution
|
||||||
|
@ -6,11 +6,6 @@
|
|||||||
|
|
||||||
CdsShortTimeStamper::CdsShortTimeStamper(object_id_t objectId) : SystemObject(objectId) {}
|
CdsShortTimeStamper::CdsShortTimeStamper(object_id_t objectId) : SystemObject(objectId) {}
|
||||||
|
|
||||||
ReturnValue_t CdsShortTimeStamper::addTimeStamp(uint8_t *buffer, const uint8_t maxSize) {
|
|
||||||
size_t serLen = 0;
|
|
||||||
return serialize(&buffer, &serLen, maxSize, SerializeIF::Endianness::NETWORK);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t CdsShortTimeStamper::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
ReturnValue_t CdsShortTimeStamper::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||||
SerializeIF::Endianness streamEndianness) const {
|
SerializeIF::Endianness streamEndianness) const {
|
||||||
if (*size + getSerializedSize() > maxSize) {
|
if (*size + getSerializedSize() > maxSize) {
|
||||||
@ -33,15 +28,22 @@ size_t CdsShortTimeStamper::getSerializedSize() const { return getTimestampSize(
|
|||||||
|
|
||||||
ReturnValue_t CdsShortTimeStamper::deSerialize(const uint8_t **buffer, size_t *size,
|
ReturnValue_t CdsShortTimeStamper::deSerialize(const uint8_t **buffer, size_t *size,
|
||||||
SerializeIF::Endianness streamEndianness) {
|
SerializeIF::Endianness streamEndianness) {
|
||||||
return returnvalue::FAILED;
|
if (size == nullptr or buffer == nullptr) {
|
||||||
}
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
ReturnValue_t CdsShortTimeStamper::readTimeStamp(const uint8_t *buffer, size_t maxSize) {
|
if (*size < getTimestampSize()) {
|
||||||
if (maxSize < getTimestampSize()) {
|
|
||||||
return SerializeIF::STREAM_TOO_SHORT;
|
return SerializeIF::STREAM_TOO_SHORT;
|
||||||
}
|
}
|
||||||
size_t foundLen = 0;
|
size_t foundLen = 0;
|
||||||
return CCSDSTime::convertFromCcsds(&readTime, buffer, &foundLen, maxSize);
|
if (((**buffer >> 4) & 0b111) != CCSDSTime::TimeCodeIdentification::CDS) {
|
||||||
|
return BAD_TIMESTAMP;
|
||||||
|
}
|
||||||
|
auto res = CCSDSTime::convertFromCcsds(&readTime, *buffer, &foundLen, *size);
|
||||||
|
if (res == returnvalue::OK) {
|
||||||
|
*size -= getSerializedSize();
|
||||||
|
*buffer += getSerializedSize();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
timeval &CdsShortTimeStamper::getTime() { return readTime; }
|
timeval &CdsShortTimeStamper::getTime() { return readTime; }
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "CCSDSTime.h"
|
#include "CCSDSTime.h"
|
||||||
#include "TimeReaderIF.h"
|
#include "TimeReaderIF.h"
|
||||||
#include "TimeStamperIF.h"
|
#include "TimeWriterIF.h"
|
||||||
#include "fsfw/objectmanager/SystemObject.h"
|
#include "fsfw/objectmanager/SystemObject.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -15,7 +15,7 @@
|
|||||||
* overriding the #addTimeStamp function.
|
* overriding the #addTimeStamp function.
|
||||||
* @ingroup utility
|
* @ingroup utility
|
||||||
*/
|
*/
|
||||||
class CdsShortTimeStamper : public TimeStamperIF, public TimeReaderIF, public SystemObject {
|
class CdsShortTimeStamper : public TimeWriterIF, public TimeReaderIF, public SystemObject {
|
||||||
public:
|
public:
|
||||||
static constexpr size_t TIMESTAMP_LEN = 7;
|
static constexpr size_t TIMESTAMP_LEN = 7;
|
||||||
/**
|
/**
|
||||||
@ -25,20 +25,11 @@ class CdsShortTimeStamper : public TimeStamperIF, public TimeReaderIF, public Sy
|
|||||||
*/
|
*/
|
||||||
explicit CdsShortTimeStamper(object_id_t objectId);
|
explicit CdsShortTimeStamper(object_id_t objectId);
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a CCSDS CDC short 8 byte timestamp to the given buffer.
|
|
||||||
* This function can be overriden to use a custom timestamp.
|
|
||||||
* @param buffer
|
|
||||||
* @param maxSize
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
ReturnValue_t addTimeStamp(uint8_t *buffer, uint8_t maxSize) override;
|
|
||||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||||
Endianness streamEndianness) const override;
|
Endianness streamEndianness) const override;
|
||||||
[[nodiscard]] size_t getSerializedSize() const override;
|
[[nodiscard]] size_t getSerializedSize() const override;
|
||||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||||
Endianness streamEndianness) override;
|
Endianness streamEndianness) override;
|
||||||
ReturnValue_t readTimeStamp(const uint8_t *buffer, size_t maxSize) override;
|
|
||||||
timeval &getTime() override;
|
timeval &getTime() override;
|
||||||
[[nodiscard]] size_t getTimestampSize() const override;
|
[[nodiscard]] size_t getTimestampSize() const override;
|
||||||
|
|
||||||
|
@ -4,13 +4,29 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "TimeStampIF.h"
|
#include "TimeStampIF.h"
|
||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
|
#include "fsfw/serialize/SerializeIF.h"
|
||||||
|
|
||||||
class TimeReaderIF : public TimeStampIF {
|
class TimeReaderIF : public SerializeIF, public TimeStampIF {
|
||||||
public:
|
public:
|
||||||
~TimeReaderIF() override = default;
|
~TimeReaderIF() override = default;
|
||||||
virtual ReturnValue_t readTimeStamp(const uint8_t* buffer, size_t maxSize) = 0;
|
|
||||||
virtual timeval& getTime() = 0;
|
virtual timeval& getTime() = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] size_t getSerializedSize() const override { return getTimestampSize(); }
|
||||||
|
|
||||||
|
ReturnValue_t readTimeStamp(const uint8_t* buf, size_t maxSize) {
|
||||||
|
size_t dummy = 0;
|
||||||
|
return deSerialize(buf, dummy, maxSize, SerializeIF::Endianness::NETWORK);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Forbidden, use dedicated IF @TimeWriterIF
|
||||||
|
*/
|
||||||
|
[[nodiscard]] ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||||
|
Endianness streamEndianness) const override {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FSFW_TIMEMANAGER_TIMEREADERIF_H
|
#endif // FSFW_TIMEMANAGER_TIMEREADERIF_H
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
#ifndef FSFW_TIMEMANAGER_TIMESTAMPERIF_H_
|
|
||||||
#define FSFW_TIMEMANAGER_TIMESTAMPERIF_H_
|
|
||||||
|
|
||||||
#include "TimeStampIF.h"
|
|
||||||
#include "fsfw/returnvalues/returnvalue.h"
|
|
||||||
#include "fsfw/serialize/SerializeIF.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A class implementing this IF provides facilities to add a time stamp to the
|
|
||||||
* buffer provided.
|
|
||||||
* Implementors need to ensure that calling the method is thread-safe, i.e.
|
|
||||||
* addTimeStamp may be called in parallel from a different context.
|
|
||||||
*/
|
|
||||||
class TimeStamperIF : public SerializeIF, public TimeStampIF {
|
|
||||||
public:
|
|
||||||
virtual ReturnValue_t addTimeStamp(uint8_t* buffer, uint8_t maxSize) = 0;
|
|
||||||
~TimeStamperIF() override = default;
|
|
||||||
size_t getTimestampSize() const override { return getSerializedSize(); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* FSFW_TIMEMANAGER_TIMESTAMPERIF_H_ */
|
|
34
src/fsfw/timemanager/TimeWriterIF.h
Normal file
34
src/fsfw/timemanager/TimeWriterIF.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#ifndef FSFW_TIMEMANAGER_TIMESTAMPERIF_H_
|
||||||
|
#define FSFW_TIMEMANAGER_TIMESTAMPERIF_H_
|
||||||
|
|
||||||
|
#include "TimeStampIF.h"
|
||||||
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
|
#include "fsfw/serialize/SerializeIF.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class implementing this IF provides facilities to add a time stamp to the
|
||||||
|
* buffer provided.
|
||||||
|
* Implementors need to ensure that calling the method is thread-safe, i.e.
|
||||||
|
* addTimeStamp may be called in parallel from a different context.
|
||||||
|
*/
|
||||||
|
class TimeWriterIF : public SerializeIF, public TimeStampIF {
|
||||||
|
public:
|
||||||
|
~TimeWriterIF() override = default;
|
||||||
|
[[nodiscard]] size_t getTimestampSize() const override { return getSerializedSize(); }
|
||||||
|
|
||||||
|
ReturnValue_t addTimeStamp(uint8_t *buf, size_t maxSize) {
|
||||||
|
size_t dummy = 0;
|
||||||
|
return serialize(buf, dummy, maxSize, SerializeIF::Endianness::NETWORK);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Forbidden, use dedicated IF @TimeReaderIF
|
||||||
|
*/
|
||||||
|
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||||
|
Endianness streamEndianness) override {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* FSFW_TIMEMANAGER_TIMESTAMPERIF_H_ */
|
@ -7,7 +7,7 @@
|
|||||||
#include "fsfw/serialize/SerialLinkedListAdapter.h"
|
#include "fsfw/serialize/SerialLinkedListAdapter.h"
|
||||||
#include "fsfw/serialize/SerializeElement.h"
|
#include "fsfw/serialize/SerializeElement.h"
|
||||||
#include "fsfw/timemanager/CCSDSTime.h"
|
#include "fsfw/timemanager/CCSDSTime.h"
|
||||||
#include "fsfw/timemanager/TimeStamperIF.h"
|
#include "fsfw/timemanager/TimeWriterIF.h"
|
||||||
#include "fsfw/tmtcpacket/pus/tm/PusTmMinimal.h"
|
#include "fsfw/tmtcpacket/pus/tm/PusTmMinimal.h"
|
||||||
#include "tmStorageConf.h"
|
#include "tmStorageConf.h"
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
#include "fsfw/tmtcpacket/ReadablePacketIF.h"
|
#include "fsfw/tmtcpacket/ReadablePacketIF.h"
|
||||||
#include "fsfw/tmtcpacket/RedirectableDataPointerIF.h"
|
#include "fsfw/tmtcpacket/RedirectableDataPointerIF.h"
|
||||||
#include "fsfw/tmtcpacket/ccsds/defs.h"
|
#include "fsfw/tmtcpacket/ccsds/defs.h"
|
||||||
|
@ -23,11 +23,11 @@ constexpr uint16_t getSpacePacketIdFromApid(bool isTc, uint16_t apid,
|
|||||||
return ((isTc << 4) | (secondaryHeaderFlag << 3) | ((apid >> 8) & 0x07)) << 8 | (apid & 0x00ff);
|
return ((isTc << 4) | (secondaryHeaderFlag << 3) | ((apid >> 8) & 0x07)) << 8 | (apid & 0x00ff);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr uint16_t getTcSpacePacketIdFromApid(uint16_t apid, bool secondaryHeaderFlag = true) {
|
constexpr uint16_t getTcSpacePacketIdFromApid(uint16_t apid, bool secondaryHeaderFlag) {
|
||||||
return getSpacePacketIdFromApid(true, apid, secondaryHeaderFlag);
|
return getSpacePacketIdFromApid(true, apid, secondaryHeaderFlag);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr uint16_t getTmSpacePacketIdFromApid(uint16_t apid, bool secondaryHeaderFlag = true) {
|
constexpr uint16_t getTmSpacePacketIdFromApid(uint16_t apid, bool secondaryHeaderFlag) {
|
||||||
return getSpacePacketIdFromApid(false, apid, secondaryHeaderFlag);
|
return getSpacePacketIdFromApid(false, apid, secondaryHeaderFlag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,11 +7,7 @@
|
|||||||
#include "fsfw/tmtcpacket/pus/tm/PusTmIF.h"
|
#include "fsfw/tmtcpacket/pus/tm/PusTmIF.h"
|
||||||
#include "fsfw/tmtcpacket/pus/tm/PusTmMinimal.h"
|
#include "fsfw/tmtcpacket/pus/tm/PusTmMinimal.h"
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
class PacketMatchTree : public MatchTree<PusTmIF*> {
|
class PacketMatchTree : public MatchTree<PusTmIF*> {
|
||||||
=======
|
|
||||||
class PacketMatchTree : public MatchTree<TmPacketMinimal*> {
|
|
||||||
>>>>>>> origin/development
|
|
||||||
public:
|
public:
|
||||||
explicit PacketMatchTree(Node* root);
|
explicit PacketMatchTree(Node* root);
|
||||||
explicit PacketMatchTree(iterator root);
|
explicit PacketMatchTree(iterator root);
|
||||||
|
@ -7,6 +7,6 @@ class CustomUserDataIF {
|
|||||||
public:
|
public:
|
||||||
virtual ~CustomUserDataIF() = default;
|
virtual ~CustomUserDataIF() = default;
|
||||||
virtual ReturnValue_t setRawUserData(const uint8_t* data, size_t len) = 0;
|
virtual ReturnValue_t setRawUserData(const uint8_t* data, size_t len) = 0;
|
||||||
virtual ReturnValue_t setSerializableUserData(SerializeIF& serializable) = 0;
|
virtual ReturnValue_t setSerializableUserData(const SerializeIF& serializable) = 0;
|
||||||
};
|
};
|
||||||
#endif // FSFW_TMTCPACKET_CREATORDATAIF_H
|
#endif // FSFW_TMTCPACKET_CREATORDATAIF_H
|
||||||
|
@ -13,44 +13,6 @@ using PusChecksumT = uint16_t;
|
|||||||
//! Version numbers according to ECSS-E-ST-70-41C p.439
|
//! Version numbers according to ECSS-E-ST-70-41C p.439
|
||||||
enum PusVersion : uint8_t { PUS_A = 1, PUS_C = 2 };
|
enum PusVersion : uint8_t { PUS_A = 1, PUS_C = 2 };
|
||||||
|
|
||||||
struct RawData {
|
|
||||||
const uint8_t* data;
|
|
||||||
size_t len;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum DataTypes { RAW, SERIALIZABLE };
|
|
||||||
|
|
||||||
union DataUnion {
|
|
||||||
RawData raw;
|
|
||||||
SerializeIF* serializable;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DataWrapper {
|
|
||||||
DataTypes type;
|
|
||||||
DataUnion dataUnion;
|
|
||||||
using BufPairT = std::pair<const uint8_t*, size_t>;
|
|
||||||
|
|
||||||
[[nodiscard]] size_t getLength() const {
|
|
||||||
if (type == DataTypes::RAW) {
|
|
||||||
return dataUnion.raw.len;
|
|
||||||
} else if (type == DataTypes::SERIALIZABLE and dataUnion.serializable != nullptr) {
|
|
||||||
return dataUnion.serializable->getSerializedSize();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setRawData(BufPairT bufPair) {
|
|
||||||
type = DataTypes::RAW;
|
|
||||||
dataUnion.raw.data = bufPair.first;
|
|
||||||
dataUnion.raw.len = bufPair.second;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setSerializable(SerializeIF& serializable) {
|
|
||||||
type = DataTypes::SERIALIZABLE;
|
|
||||||
dataUnion.serializable = &serializable;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This struct defines the data structure of a Space Packet when accessed
|
* This struct defines the data structure of a Space Packet when accessed
|
||||||
* via a pointer.
|
* via a pointer.
|
||||||
|
@ -14,7 +14,6 @@ PusTcCreator::PusTcCreator(SpacePacketParams spParams, PusTcParams pusParams)
|
|||||||
ReturnValue_t PusTcCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
ReturnValue_t PusTcCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||||
SerializeIF::Endianness streamEndianness) const {
|
SerializeIF::Endianness streamEndianness) const {
|
||||||
const uint8_t *start = *buffer;
|
const uint8_t *start = *buffer;
|
||||||
size_t userDataLen = pusParams.dataWrapper.getLength();
|
|
||||||
if (*size + getSerializedSize() > maxSize) {
|
if (*size + getSerializedSize() > maxSize) {
|
||||||
return SerializeIF::BUFFER_TOO_SHORT;
|
return SerializeIF::BUFFER_TOO_SHORT;
|
||||||
}
|
}
|
||||||
@ -37,17 +36,8 @@ ReturnValue_t PusTcCreator::serialize(uint8_t **buffer, size_t *size, size_t max
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (pusParams.dataWrapper.type == ecss::DataTypes::RAW) {
|
if (pusParams.appData != nullptr) {
|
||||||
const uint8_t *data = pusParams.dataWrapper.dataUnion.raw.data;
|
result = pusParams.appData->serialize(buffer, size, maxSize, streamEndianness);
|
||||||
if (data != nullptr and userDataLen > 0) {
|
|
||||||
std::memcpy(*buffer, data, userDataLen);
|
|
||||||
*buffer += userDataLen;
|
|
||||||
*size += userDataLen;
|
|
||||||
}
|
|
||||||
} else if (pusParams.dataWrapper.type == ecss::DataTypes::SERIALIZABLE and
|
|
||||||
pusParams.dataWrapper.dataUnion.serializable != nullptr) {
|
|
||||||
result = pusParams.dataWrapper.dataUnion.serializable->serialize(buffer, size, maxSize,
|
|
||||||
streamEndianness);
|
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -58,8 +48,11 @@ ReturnValue_t PusTcCreator::serialize(uint8_t **buffer, size_t *size, size_t max
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PusTcCreator::updateSpLengthField() {
|
void PusTcCreator::updateSpLengthField() {
|
||||||
spCreator.setDataLen(ecss::PusTcDataFieldHeader::MIN_SIZE + pusParams.dataWrapper.getLength() +
|
size_t len = ecss::PusTcDataFieldHeader::MIN_SIZE + 1;
|
||||||
1);
|
if (pusParams.appData != nullptr) {
|
||||||
|
len += pusParams.appData->getSerializedSize();
|
||||||
|
}
|
||||||
|
spCreator.setDataLen(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t PusTcCreator::getSerializedSize() const { return spCreator.getFullPacketLen(); }
|
size_t PusTcCreator::getSerializedSize() const { return spCreator.getFullPacketLen(); }
|
||||||
@ -91,14 +84,15 @@ SpacePacketParams &PusTcCreator::getSpParams() { return spCreator.getParams(); }
|
|||||||
|
|
||||||
ReturnValue_t PusTcCreator::setRawUserData(const uint8_t *data, size_t len) {
|
ReturnValue_t PusTcCreator::setRawUserData(const uint8_t *data, size_t len) {
|
||||||
// TODO: Check length field?
|
// TODO: Check length field?
|
||||||
pusParams.dataWrapper.setRawData({data, len});
|
pusParams.bufAdapter.setConstBuffer(data, len);
|
||||||
|
pusParams.appData = &pusParams.bufAdapter;
|
||||||
updateSpLengthField();
|
updateSpLengthField();
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PusTcCreator::setSerializableUserData(SerializeIF &serializable) {
|
ReturnValue_t PusTcCreator::setSerializableUserData(const SerializeIF &serializable) {
|
||||||
// TODO: Check length field?
|
// TODO: Check length field?
|
||||||
pusParams.dataWrapper.setSerializable(serializable);
|
pusParams.appData = &serializable;
|
||||||
updateSpLengthField();
|
updateSpLengthField();
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef FSFW_TMTCPACKET_TCPACKETDESERIALIZER_H
|
#ifndef FSFW_TMTCPACKET_TCPACKETDESERIALIZER_H
|
||||||
#define FSFW_TMTCPACKET_TCPACKETDESERIALIZER_H
|
#define FSFW_TMTCPACKET_TCPACKETDESERIALIZER_H
|
||||||
|
|
||||||
|
#include "fsfw/serialize/SerialBufferAdapter.h"
|
||||||
#include "fsfw/tmtcpacket/RedirectableDataPointerIF.h"
|
#include "fsfw/tmtcpacket/RedirectableDataPointerIF.h"
|
||||||
#include "fsfw/tmtcpacket/ccsds/SpacePacketCreator.h"
|
#include "fsfw/tmtcpacket/ccsds/SpacePacketCreator.h"
|
||||||
#include "fsfw/tmtcpacket/ccsds/SpacePacketIF.h"
|
#include "fsfw/tmtcpacket/ccsds/SpacePacketIF.h"
|
||||||
@ -11,11 +12,19 @@
|
|||||||
struct PusTcParams {
|
struct PusTcParams {
|
||||||
PusTcParams(uint8_t service_, uint8_t subservice_) : service(service_), subservice(subservice_) {}
|
PusTcParams(uint8_t service_, uint8_t subservice_) : service(service_), subservice(subservice_) {}
|
||||||
|
|
||||||
|
void setRawAppData(const uint8_t *data, size_t len) {
|
||||||
|
bufAdapter.setConstBuffer(data, len);
|
||||||
|
appData = &bufAdapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSerializableAppData(const SerializeIF &serializable) { appData = &serializable; }
|
||||||
|
|
||||||
uint8_t service;
|
uint8_t service;
|
||||||
uint8_t subservice;
|
uint8_t subservice;
|
||||||
uint8_t ackFlags = ecss::ACK_ALL;
|
uint8_t ackFlags = ecss::ACK_ALL;
|
||||||
uint16_t sourceId = 0;
|
uint16_t sourceId = 0;
|
||||||
ecss::DataWrapper dataWrapper{};
|
SerialBufferAdapter<uint8_t> bufAdapter;
|
||||||
|
const SerializeIF *appData = nullptr;
|
||||||
uint8_t pusVersion = ecss::PusVersion::PUS_C;
|
uint8_t pusVersion = ecss::PusVersion::PUS_C;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -51,7 +60,7 @@ class PusTcCreator : public PusTcIF, public SerializeIF, public CustomUserDataIF
|
|||||||
[[nodiscard]] uint8_t getSubService() const override;
|
[[nodiscard]] uint8_t getSubService() const override;
|
||||||
[[nodiscard]] uint16_t getSourceId() const override;
|
[[nodiscard]] uint16_t getSourceId() const override;
|
||||||
ReturnValue_t setRawUserData(const uint8_t *data, size_t len) override;
|
ReturnValue_t setRawUserData(const uint8_t *data, size_t len) override;
|
||||||
ReturnValue_t setSerializableUserData(SerializeIF &serializable) override;
|
ReturnValue_t setSerializableUserData(const SerializeIF &serializable) override;
|
||||||
|
|
||||||
// Load all big endian helpers into the class namespace
|
// Load all big endian helpers into the class namespace
|
||||||
using SerializeIF::serializeBe;
|
using SerializeIF::serializeBe;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "fsfw/globalfunctions/CRC.h"
|
#include "fsfw/globalfunctions/CRC.h"
|
||||||
#include "fsfw/timemanager/TimeStamperIF.h"
|
#include "fsfw/timemanager/TimeWriterIF.h"
|
||||||
|
|
||||||
PusTmCreator::PusTmCreator(SpacePacketParams initSpParams, PusTmParams initPusParams)
|
PusTmCreator::PusTmCreator(SpacePacketParams initSpParams, PusTmParams initPusParams)
|
||||||
: pusParams(initPusParams), spCreator(std::move(initSpParams)) {
|
: pusParams(initPusParams), spCreator(std::move(initSpParams)) {
|
||||||
@ -30,7 +30,7 @@ uint8_t PusTmCreator::getSubService() const { return pusParams.secHeader.subserv
|
|||||||
|
|
||||||
PusTmParams& PusTmCreator::getParams() { return pusParams; }
|
PusTmParams& PusTmCreator::getParams() { return pusParams; }
|
||||||
|
|
||||||
void PusTmCreator::setTimeStamper(TimeStamperIF& timeStamper_) {
|
void PusTmCreator::setTimeStamper(TimeWriterIF& timeStamper_) {
|
||||||
pusParams.secHeader.timeStamper = &timeStamper_;
|
pusParams.secHeader.timeStamper = &timeStamper_;
|
||||||
updateSpLengthField();
|
updateSpLengthField();
|
||||||
}
|
}
|
||||||
@ -51,7 +51,6 @@ ReturnValue_t PusTmCreator::serialize(uint8_t** buffer, size_t* size, size_t max
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
size_t userDataLen = pusParams.dataWrapper.getLength();
|
|
||||||
**buffer =
|
**buffer =
|
||||||
((pusParams.secHeader.pusVersion << 4) & 0xF0) | (pusParams.secHeader.scTimeRefStatus & 0x0F);
|
((pusParams.secHeader.pusVersion << 4) & 0xF0) | (pusParams.secHeader.scTimeRefStatus & 0x0F);
|
||||||
*buffer += 1;
|
*buffer += 1;
|
||||||
@ -77,15 +76,8 @@ ReturnValue_t PusTmCreator::serialize(uint8_t** buffer, size_t* size, size_t max
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pusParams.dataWrapper.type == ecss::DataTypes::RAW and
|
if (pusParams.sourceData != nullptr) {
|
||||||
pusParams.dataWrapper.dataUnion.raw.data != nullptr) {
|
result = pusParams.sourceData->serialize(buffer, size, maxSize, streamEndianness);
|
||||||
std::memcpy(*buffer, pusParams.dataWrapper.dataUnion.raw.data, userDataLen);
|
|
||||||
*buffer += userDataLen;
|
|
||||||
*size += userDataLen;
|
|
||||||
} else if (pusParams.dataWrapper.type == ecss::DataTypes::SERIALIZABLE and
|
|
||||||
pusParams.dataWrapper.dataUnion.serializable != nullptr) {
|
|
||||||
result = pusParams.dataWrapper.dataUnion.serializable->serialize(buffer, size, maxSize,
|
|
||||||
streamEndianness);
|
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -106,13 +98,15 @@ ReturnValue_t PusTmCreator::deSerialize(const uint8_t** buffer, size_t* size,
|
|||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeStamperIF* PusTmCreator::getTimestamper() const { return pusParams.secHeader.timeStamper; }
|
TimeWriterIF* PusTmCreator::getTimestamper() const { return pusParams.secHeader.timeStamper; }
|
||||||
|
|
||||||
SpacePacketParams& PusTmCreator::getSpParams() { return spCreator.getParams(); }
|
SpacePacketParams& PusTmCreator::getSpParams() { return spCreator.getParams(); }
|
||||||
|
|
||||||
void PusTmCreator::updateSpLengthField() {
|
void PusTmCreator::updateSpLengthField() {
|
||||||
size_t headerLen = PusTmIF::MIN_SEC_HEADER_LEN + pusParams.dataWrapper.getLength() +
|
size_t headerLen = PusTmIF::MIN_SEC_HEADER_LEN + sizeof(ecss::PusChecksumT) - 1;
|
||||||
sizeof(ecss::PusChecksumT) - 1;
|
if (pusParams.sourceData != nullptr) {
|
||||||
|
headerLen += pusParams.sourceData->getSerializedSize();
|
||||||
|
}
|
||||||
if (pusParams.secHeader.timeStamper != nullptr) {
|
if (pusParams.secHeader.timeStamper != nullptr) {
|
||||||
headerLen += pusParams.secHeader.timeStamper->getSerializedSize();
|
headerLen += pusParams.secHeader.timeStamper->getSerializedSize();
|
||||||
}
|
}
|
||||||
@ -134,12 +128,17 @@ void PusTmCreator::setMessageTypeCounter(uint16_t messageTypeCounter) {
|
|||||||
void PusTmCreator::setDestId(uint16_t destId) { pusParams.secHeader.destId = destId; }
|
void PusTmCreator::setDestId(uint16_t destId) { pusParams.secHeader.destId = destId; }
|
||||||
|
|
||||||
ReturnValue_t PusTmCreator::setRawUserData(const uint8_t* data, size_t len) {
|
ReturnValue_t PusTmCreator::setRawUserData(const uint8_t* data, size_t len) {
|
||||||
pusParams.dataWrapper.setRawData({data, len});
|
if (data == nullptr or len == 0) {
|
||||||
|
pusParams.sourceData = nullptr;
|
||||||
|
} else {
|
||||||
|
pusParams.adapter.setConstBuffer(data, len);
|
||||||
|
pusParams.sourceData = &pusParams.adapter;
|
||||||
|
}
|
||||||
updateSpLengthField();
|
updateSpLengthField();
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
ReturnValue_t PusTmCreator::setSerializableUserData(SerializeIF& serializable) {
|
ReturnValue_t PusTmCreator::setSerializableUserData(const SerializeIF& serializable) {
|
||||||
pusParams.dataWrapper.setSerializable(serializable);
|
pusParams.sourceData = &serializable;
|
||||||
updateSpLengthField();
|
updateSpLengthField();
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
@ -2,17 +2,18 @@
|
|||||||
#define FSFW_TMTCPACKET_TMPACKETCREATOR_H
|
#define FSFW_TMTCPACKET_TMPACKETCREATOR_H
|
||||||
|
|
||||||
#include "PusTmIF.h"
|
#include "PusTmIF.h"
|
||||||
|
#include "fsfw/serialize/SerialBufferAdapter.h"
|
||||||
#include "fsfw/tmtcpacket/ccsds/SpacePacketCreator.h"
|
#include "fsfw/tmtcpacket/ccsds/SpacePacketCreator.h"
|
||||||
#include "fsfw/tmtcpacket/pus/CustomUserDataIF.h"
|
#include "fsfw/tmtcpacket/pus/CustomUserDataIF.h"
|
||||||
|
|
||||||
struct PusTmSecHeader {
|
struct PusTmSecHeader {
|
||||||
PusTmSecHeader() = default;
|
PusTmSecHeader() = default;
|
||||||
PusTmSecHeader(uint8_t service, uint8_t subservice, TimeStamperIF* timeStamper)
|
PusTmSecHeader(uint8_t service, uint8_t subservice, TimeWriterIF* timeStamper)
|
||||||
: service(service), subservice(subservice), timeStamper(timeStamper) {}
|
: service(service), subservice(subservice), timeStamper(timeStamper) {}
|
||||||
|
|
||||||
uint8_t service = 0;
|
uint8_t service = 0;
|
||||||
uint8_t subservice = 0;
|
uint8_t subservice = 0;
|
||||||
TimeStamperIF* timeStamper = nullptr;
|
TimeWriterIF* timeStamper = nullptr;
|
||||||
uint8_t pusVersion = ecss::PusVersion::PUS_C;
|
uint8_t pusVersion = ecss::PusVersion::PUS_C;
|
||||||
uint8_t scTimeRefStatus = 0;
|
uint8_t scTimeRefStatus = 0;
|
||||||
uint16_t messageTypeCounter = 0;
|
uint16_t messageTypeCounter = 0;
|
||||||
@ -22,22 +23,28 @@ struct PusTmSecHeader {
|
|||||||
struct PusTmParams {
|
struct PusTmParams {
|
||||||
PusTmParams() = default;
|
PusTmParams() = default;
|
||||||
explicit PusTmParams(PusTmSecHeader secHeader) : secHeader(secHeader){};
|
explicit PusTmParams(PusTmSecHeader secHeader) : secHeader(secHeader){};
|
||||||
PusTmParams(PusTmSecHeader secHeader, ecss::DataWrapper dataWrapper)
|
PusTmParams(PusTmSecHeader secHeader, const SerializeIF& data)
|
||||||
: secHeader(secHeader), dataWrapper(dataWrapper) {}
|
: secHeader(secHeader), sourceData(&data) {}
|
||||||
|
PusTmParams(PusTmSecHeader secHeader, const uint8_t* data, size_t dataLen)
|
||||||
PusTmParams(uint8_t service, uint8_t subservice, TimeStamperIF* timeStamper)
|
: secHeader(secHeader), adapter(data, dataLen), sourceData(&adapter) {}
|
||||||
|
PusTmParams(uint8_t service, uint8_t subservice, TimeWriterIF* timeStamper)
|
||||||
: secHeader(service, subservice, timeStamper) {}
|
: secHeader(service, subservice, timeStamper) {}
|
||||||
|
|
||||||
PusTmParams(uint8_t service, uint8_t subservice, TimeStamperIF* timeStamper,
|
PusTmParams(uint8_t service, uint8_t subservice, TimeWriterIF* timeStamper,
|
||||||
ecss::DataWrapper dataWrapper_)
|
const SerializeIF& data_)
|
||||||
: PusTmParams(service, subservice, timeStamper) {
|
: PusTmParams(service, subservice, timeStamper) {
|
||||||
dataWrapper = dataWrapper_;
|
sourceData = &data_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PusTmParams(uint8_t service, uint8_t subservice, TimeWriterIF* timeStamper, const uint8_t* data,
|
||||||
|
size_t dataLen)
|
||||||
|
: secHeader(service, subservice, timeStamper), adapter(data, dataLen), sourceData(&adapter) {}
|
||||||
PusTmSecHeader secHeader;
|
PusTmSecHeader secHeader;
|
||||||
ecss::DataWrapper dataWrapper{};
|
SerialBufferAdapter<uint8_t> adapter;
|
||||||
|
const SerializeIF* sourceData = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TimeStamperIF;
|
class TimeWriterIF;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides a high-level interface to create PUS TM packets and then @serialize
|
* This class provides a high-level interface to create PUS TM packets and then @serialize
|
||||||
@ -55,7 +62,7 @@ class PusTmCreator : public SerializeIF, public PusTmIF, public CustomUserDataIF
|
|||||||
PusTmCreator(SpacePacketParams initSpParams, PusTmParams initPusParams);
|
PusTmCreator(SpacePacketParams initSpParams, PusTmParams initPusParams);
|
||||||
~PusTmCreator() override = default;
|
~PusTmCreator() override = default;
|
||||||
|
|
||||||
void setTimeStamper(TimeStamperIF& timeStamper);
|
void setTimeStamper(TimeWriterIF& timeStamper);
|
||||||
/**
|
/**
|
||||||
* This function disables the CRC16 calculation on serialization. This is useful to avoid
|
* This function disables the CRC16 calculation on serialization. This is useful to avoid
|
||||||
* duplicate calculation if some lower level component needs to update fields like the sequence
|
* duplicate calculation if some lower level component needs to update fields like the sequence
|
||||||
@ -85,9 +92,9 @@ class PusTmCreator : public SerializeIF, public PusTmIF, public CustomUserDataIF
|
|||||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||||
Endianness streamEndianness) const override;
|
Endianness streamEndianness) const override;
|
||||||
[[nodiscard]] size_t getSerializedSize() const override;
|
[[nodiscard]] size_t getSerializedSize() const override;
|
||||||
[[nodiscard]] TimeStamperIF* getTimestamper() const;
|
[[nodiscard]] TimeWriterIF* getTimestamper() const;
|
||||||
ReturnValue_t setRawUserData(const uint8_t* data, size_t len) override;
|
ReturnValue_t setRawUserData(const uint8_t* data, size_t len) override;
|
||||||
ReturnValue_t setSerializableUserData(SerializeIF& serializable) override;
|
ReturnValue_t setSerializableUserData(const SerializeIF& serializable) override;
|
||||||
|
|
||||||
// Load all big endian (network endian) helpers into scope
|
// Load all big endian (network endian) helpers into scope
|
||||||
using SerializeIF::serializeBe;
|
using SerializeIF::serializeBe;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#include "fsfw/timemanager/TimeStamperIF.h"
|
#include "fsfw/timemanager/TimeWriterIF.h"
|
||||||
#include "fsfw/tmtcpacket/pus/PusIF.h"
|
#include "fsfw/tmtcpacket/pus/PusIF.h"
|
||||||
#include "fsfw/tmtcpacket/pus/defs.h"
|
#include "fsfw/tmtcpacket/pus/defs.h"
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define FRAMEWORK_TMTCPACKET_PUS_TMPACKETMINIMAL_H_
|
#define FRAMEWORK_TMTCPACKET_PUS_TMPACKETMINIMAL_H_
|
||||||
|
|
||||||
#include "PusTmIF.h"
|
#include "PusTmIF.h"
|
||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
#include "fsfw/tmtcpacket/ccsds/SpacePacketReader.h"
|
#include "fsfw/tmtcpacket/ccsds/SpacePacketReader.h"
|
||||||
#include "fsfw/tmtcpacket/pus/RawUserDataReaderIF.h"
|
#include "fsfw/tmtcpacket/pus/RawUserDataReaderIF.h"
|
||||||
|
|
||||||
|
@ -21,20 +21,22 @@ class AcceptsTelecommandsIF {
|
|||||||
* @brief The virtual destructor as it is mandatory for C++ interfaces.
|
* @brief The virtual destructor as it is mandatory for C++ interfaces.
|
||||||
*/
|
*/
|
||||||
virtual ~AcceptsTelecommandsIF() = default;
|
virtual ~AcceptsTelecommandsIF() = default;
|
||||||
|
[[nodiscard]] virtual const char* getName() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Getter for the service id.
|
* @brief Getter for a generic identifier ID.
|
||||||
* @details Any receiving service (at least any PUS service) shall have a
|
* @details Any receiving service (at least any PUS service) shall have an identifier. For
|
||||||
* service ID. If the receiver can handle Telecommands, but for
|
* example, this could be the APID for a receiver expecting generic PUS packets, or a PUS
|
||||||
* some reason has no service id, it shall return 0.
|
* service for a component expecting specific PUS service packets.
|
||||||
* @return The service ID or 0.
|
* @return The identifier.
|
||||||
*/
|
*/
|
||||||
virtual uint16_t getIdentifier() = 0;
|
[[nodiscard]] virtual uint32_t getIdentifier() const = 0;
|
||||||
/**
|
/**
|
||||||
* @brief This method returns the message queue id of the telecommand
|
* @brief This method returns the message queue id of the telecommand
|
||||||
* receiving message queue.
|
* receiving message queue.
|
||||||
* @return The telecommand reception message queue id.
|
* @return The telecommand reception message queue id.
|
||||||
*/
|
*/
|
||||||
virtual MessageQueueId_t getRequestQueue() = 0;
|
[[nodiscard]] virtual MessageQueueId_t getRequestQueue() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FRAMEWORK_TMTCSERVICES_ACCEPTSTELECOMMANDSIF_H_ */
|
#endif /* FRAMEWORK_TMTCSERVICES_ACCEPTSTELECOMMANDSIF_H_ */
|
||||||
|
@ -14,6 +14,8 @@ class AcceptsTelemetryIF {
|
|||||||
* @brief The virtual destructor as it is mandatory for C++ interfaces.
|
* @brief The virtual destructor as it is mandatory for C++ interfaces.
|
||||||
*/
|
*/
|
||||||
virtual ~AcceptsTelemetryIF() = default;
|
virtual ~AcceptsTelemetryIF() = default;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual const char* getName() const = 0;
|
||||||
/**
|
/**
|
||||||
* @brief This method returns the message queue id of the telemetry
|
* @brief This method returns the message queue id of the telemetry
|
||||||
* receiving message queue.
|
* receiving message queue.
|
||||||
|
@ -14,7 +14,8 @@ object_id_t CommandingServiceBase::defaultPacketSource = objects::NO_OBJECT;
|
|||||||
object_id_t CommandingServiceBase::defaultPacketDestination = objects::NO_OBJECT;
|
object_id_t CommandingServiceBase::defaultPacketDestination = objects::NO_OBJECT;
|
||||||
|
|
||||||
CommandingServiceBase::CommandingServiceBase(object_id_t setObjectId, uint16_t apid,
|
CommandingServiceBase::CommandingServiceBase(object_id_t setObjectId, uint16_t apid,
|
||||||
uint8_t service, uint8_t numberOfParallelCommands,
|
const char* name, uint8_t service,
|
||||||
|
uint8_t numberOfParallelCommands,
|
||||||
uint16_t commandTimeoutSeconds, size_t queueDepth,
|
uint16_t commandTimeoutSeconds, size_t queueDepth,
|
||||||
VerificationReporterIF* verificationReporter)
|
VerificationReporterIF* verificationReporter)
|
||||||
: SystemObject(setObjectId),
|
: SystemObject(setObjectId),
|
||||||
@ -24,7 +25,8 @@ CommandingServiceBase::CommandingServiceBase(object_id_t setObjectId, uint16_t a
|
|||||||
tmStoreHelper(apid),
|
tmStoreHelper(apid),
|
||||||
tmHelper(service, tmStoreHelper, tmSendHelper),
|
tmHelper(service, tmStoreHelper, tmSendHelper),
|
||||||
verificationReporter(verificationReporter),
|
verificationReporter(verificationReporter),
|
||||||
commandMap(numberOfParallelCommands) {
|
commandMap(numberOfParallelCommands),
|
||||||
|
name(name) {
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(queueDepth);
|
commandQueue = QueueFactory::instance()->createMessageQueue(queueDepth);
|
||||||
requestQueue = QueueFactory::instance()->createMessageQueue(queueDepth);
|
requestQueue = QueueFactory::instance()->createMessageQueue(queueDepth);
|
||||||
}
|
}
|
||||||
@ -50,9 +52,9 @@ ReturnValue_t CommandingServiceBase::performOperation(uint8_t opCode) {
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t CommandingServiceBase::getIdentifier() { return service; }
|
uint32_t CommandingServiceBase::getIdentifier() const { return service; }
|
||||||
|
|
||||||
MessageQueueId_t CommandingServiceBase::getRequestQueue() { return requestQueue->getId(); }
|
MessageQueueId_t CommandingServiceBase::getRequestQueue() const { return requestQueue->getId(); }
|
||||||
|
|
||||||
ReturnValue_t CommandingServiceBase::initialize() {
|
ReturnValue_t CommandingServiceBase::initialize() {
|
||||||
ReturnValue_t result = SystemObject::initialize();
|
ReturnValue_t result = SystemObject::initialize();
|
||||||
@ -104,7 +106,7 @@ ReturnValue_t CommandingServiceBase::initialize() {
|
|||||||
// This avoids duplicate calculation of the CRC16
|
// This avoids duplicate calculation of the CRC16
|
||||||
tmStoreHelper.disableCrcCalculation();
|
tmStoreHelper.disableCrcCalculation();
|
||||||
if (tmTimeStamper == nullptr) {
|
if (tmTimeStamper == nullptr) {
|
||||||
tmTimeStamper = ObjectManager::instance()->get<TimeStamperIF>(objects::TIME_STAMPER);
|
tmTimeStamper = ObjectManager::instance()->get<TimeWriterIF>(objects::TIME_STAMPER);
|
||||||
if (tmTimeStamper == nullptr) {
|
if (tmTimeStamper == nullptr) {
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
@ -489,3 +491,5 @@ void CommandingServiceBase::prepareVerificationSuccessWithFullInfo(
|
|||||||
successParams.tcPsc = tcInfo.tcSequenceControl;
|
successParams.tcPsc = tcInfo.tcSequenceControl;
|
||||||
successParams.ackFlags = tcInfo.ackFlags;
|
successParams.ackFlags = tcInfo.ackFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* CommandingServiceBase::getName() const { return name; }
|
||||||
|
@ -75,7 +75,7 @@ class CommandingServiceBase : public SystemObject,
|
|||||||
* @param setPacketDestination
|
* @param setPacketDestination
|
||||||
* @param queueDepth
|
* @param queueDepth
|
||||||
*/
|
*/
|
||||||
CommandingServiceBase(object_id_t setObjectId, uint16_t apid, uint8_t service,
|
CommandingServiceBase(object_id_t setObjectId, uint16_t apid, const char* name, uint8_t service,
|
||||||
uint8_t numberOfParallelCommands, uint16_t commandTimeoutSeconds,
|
uint8_t numberOfParallelCommands, uint16_t commandTimeoutSeconds,
|
||||||
size_t queueDepth = 20, VerificationReporterIF* reporter = nullptr);
|
size_t queueDepth = 20, VerificationReporterIF* reporter = nullptr);
|
||||||
~CommandingServiceBase() override;
|
~CommandingServiceBase() override;
|
||||||
@ -105,7 +105,7 @@ class CommandingServiceBase : public SystemObject,
|
|||||||
*/
|
*/
|
||||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||||
|
|
||||||
uint16_t getIdentifier() override;
|
uint32_t getIdentifier() const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the requestQueue MessageQueueId_t
|
* Returns the requestQueue MessageQueueId_t
|
||||||
@ -114,7 +114,7 @@ class CommandingServiceBase : public SystemObject,
|
|||||||
*
|
*
|
||||||
* @return requestQueue messageQueueId_t
|
* @return requestQueue messageQueueId_t
|
||||||
*/
|
*/
|
||||||
MessageQueueId_t getRequestQueue() override;
|
MessageQueueId_t getRequestQueue() const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the commandQueue MessageQueueId_t
|
* Returns the commandQueue MessageQueueId_t
|
||||||
@ -133,6 +133,7 @@ class CommandingServiceBase : public SystemObject,
|
|||||||
* @param task Pointer to the taskIF of this task
|
* @param task Pointer to the taskIF of this task
|
||||||
*/
|
*/
|
||||||
void setTaskIF(PeriodicTaskIF* task) override;
|
void setTaskIF(PeriodicTaskIF* task) override;
|
||||||
|
const char* getName() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
@ -272,7 +273,7 @@ class CommandingServiceBase : public SystemObject,
|
|||||||
MessageQueueIF* commandQueue = nullptr;
|
MessageQueueIF* commandQueue = nullptr;
|
||||||
MessageQueueIF* requestQueue = nullptr;
|
MessageQueueIF* requestQueue = nullptr;
|
||||||
|
|
||||||
TimeStamperIF* tmTimeStamper = nullptr;
|
TimeWriterIF* tmTimeStamper = nullptr;
|
||||||
VerificationReporterIF* verificationReporter;
|
VerificationReporterIF* verificationReporter;
|
||||||
|
|
||||||
InternalErrorReporterIF* errReporter = nullptr;
|
InternalErrorReporterIF* errReporter = nullptr;
|
||||||
@ -283,6 +284,8 @@ class CommandingServiceBase : public SystemObject,
|
|||||||
uint32_t failureParameter1 = 0;
|
uint32_t failureParameter1 = 0;
|
||||||
uint32_t failureParameter2 = 0;
|
uint32_t failureParameter2 = 0;
|
||||||
|
|
||||||
|
const char* name = "";
|
||||||
|
|
||||||
static object_id_t defaultPacketSource;
|
static object_id_t defaultPacketSource;
|
||||||
object_id_t packetSource = objects::NO_OBJECT;
|
object_id_t packetSource = objects::NO_OBJECT;
|
||||||
static object_id_t defaultPacketDestination;
|
static object_id_t defaultPacketDestination;
|
||||||
|
@ -82,9 +82,9 @@ void PusServiceBase::handleRequestQueue() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t PusServiceBase::getIdentifier() { return psbParams.serviceId; }
|
uint32_t PusServiceBase::getIdentifier() const { return psbParams.serviceId; }
|
||||||
|
|
||||||
MessageQueueId_t PusServiceBase::getRequestQueue() {
|
MessageQueueId_t PusServiceBase::getRequestQueue() const {
|
||||||
if (psbParams.reqQueue == nullptr) {
|
if (psbParams.reqQueue == nullptr) {
|
||||||
return MessageQueueIF::NO_QUEUE;
|
return MessageQueueIF::NO_QUEUE;
|
||||||
}
|
}
|
||||||
@ -178,7 +178,7 @@ ReturnValue_t PusServiceBase::initializeTmStoreHelper(TmStoreHelper& tmStoreHelp
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (psbParams.timeStamper == nullptr) {
|
if (psbParams.timeStamper == nullptr) {
|
||||||
auto timerStamper = ObjectManager::instance()->get<TimeStamperIF>(objects::TIME_STAMPER);
|
auto timerStamper = ObjectManager::instance()->get<TimeWriterIF>(objects::TIME_STAMPER);
|
||||||
if (timerStamper != nullptr) {
|
if (timerStamper != nullptr) {
|
||||||
tmStoreHelper.setTimeStamper(*timerStamper);
|
tmStoreHelper.setTimeStamper(*timerStamper);
|
||||||
}
|
}
|
||||||
@ -202,3 +202,5 @@ void PusServiceBase::setTmReceiver(AcceptsTelemetryIF& tmReceiver_) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PusServiceBase::setRequestQueue(MessageQueueIF& reqQueue) { psbParams.reqQueue = &reqQueue; }
|
void PusServiceBase::setRequestQueue(MessageQueueIF& reqQueue) { psbParams.reqQueue = &reqQueue; }
|
||||||
|
|
||||||
|
const char* PusServiceBase::getName() const { return psbParams.name; }
|
||||||
|
@ -22,9 +22,13 @@ class StorageManagerIF;
|
|||||||
struct PsbParams {
|
struct PsbParams {
|
||||||
PsbParams() = default;
|
PsbParams() = default;
|
||||||
PsbParams(uint16_t apid, AcceptsTelemetryIF* tmReceiver) : apid(apid), tmReceiver(tmReceiver) {}
|
PsbParams(uint16_t apid, AcceptsTelemetryIF* tmReceiver) : apid(apid), tmReceiver(tmReceiver) {}
|
||||||
|
PsbParams(const char* name, uint16_t apid, AcceptsTelemetryIF* tmReceiver)
|
||||||
|
: name(name), apid(apid), tmReceiver(tmReceiver) {}
|
||||||
PsbParams(object_id_t objectId, uint16_t apid, uint8_t serviceId)
|
PsbParams(object_id_t objectId, uint16_t apid, uint8_t serviceId)
|
||||||
: objectId(objectId), apid(apid), serviceId(serviceId) {}
|
: objectId(objectId), apid(apid), serviceId(serviceId) {}
|
||||||
|
PsbParams(const char* name, object_id_t objectId, uint16_t apid, uint8_t serviceId)
|
||||||
|
: name(name), objectId(objectId), apid(apid), serviceId(serviceId) {}
|
||||||
|
const char* name = "";
|
||||||
object_id_t objectId = objects::NO_OBJECT;
|
object_id_t objectId = objects::NO_OBJECT;
|
||||||
uint16_t apid = 0;
|
uint16_t apid = 0;
|
||||||
uint8_t serviceId = 0;
|
uint8_t serviceId = 0;
|
||||||
@ -65,7 +69,7 @@ struct PsbParams {
|
|||||||
* register itself at that object.
|
* register itself at that object.
|
||||||
*/
|
*/
|
||||||
PUSDistributorIF* pusDistributor = nullptr;
|
PUSDistributorIF* pusDistributor = nullptr;
|
||||||
TimeStamperIF* timeStamper = nullptr;
|
TimeWriterIF* timeStamper = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Factory {
|
namespace Factory {
|
||||||
@ -187,11 +191,12 @@ class PusServiceBase : public ExecutableObjectIF,
|
|||||||
* @c returnvalue::FAILED else.
|
* @c returnvalue::FAILED else.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||||
uint16_t getIdentifier() override;
|
uint32_t getIdentifier() const override;
|
||||||
MessageQueueId_t getRequestQueue() override;
|
MessageQueueId_t getRequestQueue() const override;
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
void setTaskIF(PeriodicTaskIF* taskHandle) override;
|
void setTaskIF(PeriodicTaskIF* taskHandle) override;
|
||||||
|
[[nodiscard]] const char* getName() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
@ -200,6 +205,7 @@ class PusServiceBase : public ExecutableObjectIF,
|
|||||||
* Will be set by setTaskIF(), which is called on task creation.
|
* Will be set by setTaskIF(), which is called on task creation.
|
||||||
*/
|
*/
|
||||||
PeriodicTaskIF* taskHandle = nullptr;
|
PeriodicTaskIF* taskHandle = nullptr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* One of two error parameters for additional error information.
|
* One of two error parameters for additional error information.
|
||||||
*/
|
*/
|
||||||
|
@ -6,17 +6,9 @@
|
|||||||
SpacePacketParser::SpacePacketParser(std::vector<uint16_t> validPacketIds)
|
SpacePacketParser::SpacePacketParser(std::vector<uint16_t> validPacketIds)
|
||||||
: validPacketIds(validPacketIds) {}
|
: validPacketIds(validPacketIds) {}
|
||||||
|
|
||||||
ReturnValue_t SpacePacketParser::parseSpacePackets(const uint8_t* buffer, const size_t maxSize,
|
|
||||||
size_t& startIndex, size_t& foundSize) {
|
|
||||||
const uint8_t** tempPtr = &buffer;
|
|
||||||
size_t readLen = 0;
|
|
||||||
return parseSpacePackets(tempPtr, maxSize, startIndex, foundSize, readLen);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t SpacePacketParser::parseSpacePackets(const uint8_t** buffer, const size_t maxSize,
|
ReturnValue_t SpacePacketParser::parseSpacePackets(const uint8_t** buffer, const size_t maxSize,
|
||||||
size_t& startIndex, size_t& foundSize,
|
FoundPacketInfo& packetInfo) {
|
||||||
size_t& readLen) {
|
if (buffer == nullptr or nextStartIdx > maxSize) {
|
||||||
if (buffer == nullptr or maxSize < 5) {
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "SpacePacketParser::parseSpacePackets: Frame invalid" << std::endl;
|
sif::warning << "SpacePacketParser::parseSpacePackets: Frame invalid" << std::endl;
|
||||||
#else
|
#else
|
||||||
@ -26,35 +18,32 @@ ReturnValue_t SpacePacketParser::parseSpacePackets(const uint8_t** buffer, const
|
|||||||
}
|
}
|
||||||
const uint8_t* bufPtr = *buffer;
|
const uint8_t* bufPtr = *buffer;
|
||||||
|
|
||||||
auto verifyLengthField = [&](size_t idx) {
|
auto verifyLengthField = [&](size_t localIdx) {
|
||||||
uint16_t lengthField = bufPtr[idx + 4] << 8 | bufPtr[idx + 5];
|
uint16_t lengthField = (bufPtr[localIdx + 4] << 8) | bufPtr[localIdx + 5];
|
||||||
size_t packetSize = lengthField + 7;
|
size_t packetSize = lengthField + 7;
|
||||||
startIndex = idx;
|
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
if (lengthField == 0) {
|
if (packetSize + localIdx + amountRead > maxSize) {
|
||||||
// Skip whole header for now
|
|
||||||
foundSize = 6;
|
|
||||||
result = NO_PACKET_FOUND;
|
|
||||||
} else if (packetSize + idx > maxSize) {
|
|
||||||
// Don't increment buffer and read length here, user has to decide what to do
|
// Don't increment buffer and read length here, user has to decide what to do
|
||||||
foundSize = packetSize;
|
packetInfo.sizeFound = packetSize;
|
||||||
return SPLIT_PACKET;
|
return SPLIT_PACKET;
|
||||||
} else {
|
} else {
|
||||||
foundSize = packetSize;
|
packetInfo.sizeFound = packetSize;
|
||||||
}
|
}
|
||||||
*buffer += foundSize;
|
*buffer += packetInfo.sizeFound;
|
||||||
readLen += idx + foundSize;
|
packetInfo.startIdx = localIdx + amountRead;
|
||||||
|
nextStartIdx = localIdx + amountRead + packetInfo.sizeFound;
|
||||||
|
amountRead = nextStartIdx;
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
// Space packet ID as start marker
|
// Space packet ID as start marker
|
||||||
if (validPacketIds.size() > 0) {
|
if (validPacketIds.size() > 0) {
|
||||||
while (idx < maxSize - 5) {
|
while (idx + amountRead < maxSize - 5) {
|
||||||
uint16_t currentPacketId = bufPtr[idx] << 8 | bufPtr[idx + 1];
|
uint16_t currentPacketId = (bufPtr[idx] << 8) | bufPtr[idx + 1];
|
||||||
if (std::find(validPacketIds.begin(), validPacketIds.end(), currentPacketId) !=
|
if (std::find(validPacketIds.begin(), validPacketIds.end(), currentPacketId) !=
|
||||||
validPacketIds.end()) {
|
validPacketIds.end()) {
|
||||||
if (idx + 5 >= maxSize) {
|
if (idx + amountRead >= maxSize - 5) {
|
||||||
return SPLIT_PACKET;
|
return SPLIT_PACKET;
|
||||||
}
|
}
|
||||||
return verifyLengthField(idx);
|
return verifyLengthField(idx);
|
||||||
@ -62,10 +51,10 @@ ReturnValue_t SpacePacketParser::parseSpacePackets(const uint8_t** buffer, const
|
|||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
startIndex = 0;
|
nextStartIdx = maxSize;
|
||||||
foundSize = maxSize;
|
packetInfo.sizeFound = maxSize;
|
||||||
*buffer += foundSize;
|
amountRead = maxSize;
|
||||||
readLen += foundSize;
|
*buffer += maxSize;
|
||||||
return NO_PACKET_FOUND;
|
return NO_PACKET_FOUND;
|
||||||
}
|
}
|
||||||
// Assume that the user verified a valid start of a space packet
|
// Assume that the user verified a valid start of a space packet
|
||||||
|
@ -17,9 +17,10 @@
|
|||||||
*/
|
*/
|
||||||
class SpacePacketParser {
|
class SpacePacketParser {
|
||||||
public:
|
public:
|
||||||
//! The first entry is the index inside the buffer while the second index
|
struct FoundPacketInfo {
|
||||||
//! is the size of the PUS packet starting at that index.
|
size_t startIdx = 0;
|
||||||
using IndexSizePair = std::pair<size_t, size_t>;
|
size_t sizeFound = 0;
|
||||||
|
};
|
||||||
|
|
||||||
static constexpr uint8_t INTERFACE_ID = CLASS_ID::SPACE_PACKET_PARSER;
|
static constexpr uint8_t INTERFACE_ID = CLASS_ID::SPACE_PACKET_PARSER;
|
||||||
static constexpr ReturnValue_t NO_PACKET_FOUND = MAKE_RETURN_CODE(0x00);
|
static constexpr ReturnValue_t NO_PACKET_FOUND = MAKE_RETURN_CODE(0x00);
|
||||||
@ -36,44 +37,30 @@ class SpacePacketParser {
|
|||||||
SpacePacketParser(std::vector<uint16_t> validPacketIds);
|
SpacePacketParser(std::vector<uint16_t> validPacketIds);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a given frame for space packets but also increment the given buffer and assign the
|
* Parse a given frame for space packets but also increments the given buffer.
|
||||||
* total number of bytes read so far
|
|
||||||
* @param buffer Parser will look for space packets in this buffer
|
* @param buffer Parser will look for space packets in this buffer
|
||||||
* @param maxSize Maximum size of the buffer
|
* @param maxSize Maximum size of the buffer
|
||||||
* @param startIndex Start index of a found space packet
|
* @param packetInfo Information about packets found.
|
||||||
* @param foundSize Found size of the space packet
|
* -@c NO_PACKET_FOUND if no packet was found in the given buffer
|
||||||
* @param readLen Length read so far. This value is incremented by the number of parsed
|
* -@c SPLIT_PACKET if a packet was found but the detected size exceeds maxSize. packetInfo
|
||||||
* bytes which also includes the size of a found packet
|
* will contain the detected packet size and start index.
|
||||||
* -@c NO_PACKET_FOUND if no packet was found in the given buffer or the length field is
|
* -@c returnvalue::OK if a packet was found. Packet size and start index will be set in
|
||||||
* invalid. foundSize will be set to the size of the space packet header. buffer and
|
* packetInfo
|
||||||
* readLen will be incremented accordingly.
|
|
||||||
* -@c SPLIT_PACKET if a packet was found but the detected size exceeds maxSize. foundSize
|
|
||||||
* will be set to the detected packet size and startIndex will be set to the start of the
|
|
||||||
* detected packet. buffer and read length will not be incremented but the found length
|
|
||||||
* will be assigned.
|
|
||||||
* -@c returnvalue::OK if a packet was found
|
|
||||||
*/
|
*/
|
||||||
ReturnValue_t parseSpacePackets(const uint8_t** buffer, const size_t maxSize, size_t& startIndex,
|
ReturnValue_t parseSpacePackets(const uint8_t** buffer, const size_t maxSize,
|
||||||
size_t& foundSize, size_t& readLen);
|
FoundPacketInfo& packetInfo);
|
||||||
|
|
||||||
/**
|
size_t getAmountRead() { return amountRead; }
|
||||||
* Parse a given frame for space packets
|
|
||||||
* @param buffer Parser will look for space packets in this buffer
|
void reset() {
|
||||||
* @param maxSize Maximum size of the buffer
|
nextStartIdx = 0;
|
||||||
* @param startIndex Start index of a found space packet
|
amountRead = 0;
|
||||||
* @param foundSize Found size of the space packet
|
}
|
||||||
* -@c NO_PACKET_FOUND if no packet was found in the given buffer or the length field is
|
|
||||||
* invalid. foundSize will be set to the size of the space packet header
|
|
||||||
* -@c SPLIT_PACKET if a packet was found but the detected size exceeds maxSize. foundSize
|
|
||||||
* will be set to the detected packet size and startIndex will be set to the start of the
|
|
||||||
* detected packet
|
|
||||||
* -@c returnvalue::OK if a packet was found
|
|
||||||
*/
|
|
||||||
ReturnValue_t parseSpacePackets(const uint8_t* buffer, const size_t maxSize, size_t& startIndex,
|
|
||||||
size_t& foundSize);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<uint16_t> validPacketIds;
|
std::vector<uint16_t> validPacketIds;
|
||||||
|
size_t nextStartIdx = 0;
|
||||||
|
size_t amountRead = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FRAMEWORK_TMTCSERVICES_PUSPARSER_H_ */
|
#endif /* FRAMEWORK_TMTCSERVICES_PUSPARSER_H_ */
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include "fsfw/internalerror/InternalErrorReporterIF.h"
|
#include "fsfw/internalerror/InternalErrorReporterIF.h"
|
||||||
#include "fsfw/ipc/MessageQueueIF.h"
|
#include "fsfw/ipc/MessageQueueIF.h"
|
||||||
#include "fsfw/ipc/messageQueueDefinitions.h"
|
#include "fsfw/ipc/messageQueueDefinitions.h"
|
||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
|
|
||||||
class TmSendHelper {
|
class TmSendHelper {
|
||||||
public:
|
public:
|
||||||
|
@ -11,7 +11,7 @@ TmStoreHelper::TmStoreHelper(uint16_t defaultApid, StorageManagerIF& tmStore) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
TmStoreHelper::TmStoreHelper(uint16_t defaultApid, StorageManagerIF& tmStore,
|
TmStoreHelper::TmStoreHelper(uint16_t defaultApid, StorageManagerIF& tmStore,
|
||||||
TimeStamperIF& timeStamper)
|
TimeWriterIF& timeStamper)
|
||||||
: tmStore(&tmStore) {
|
: tmStore(&tmStore) {
|
||||||
creator.setApid(defaultApid);
|
creator.setApid(defaultApid);
|
||||||
creator.setTimeStamper(timeStamper);
|
creator.setTimeStamper(timeStamper);
|
||||||
@ -59,7 +59,7 @@ ReturnValue_t TmStoreHelper::addPacketToStore() {
|
|||||||
SerializeIF::Endianness::NETWORK);
|
SerializeIF::Endianness::NETWORK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TmStoreHelper::setTimeStamper(TimeStamperIF& timeStamper_) {
|
void TmStoreHelper::setTimeStamper(TimeWriterIF& timeStamper_) {
|
||||||
creator.setTimeStamper(timeStamper_);
|
creator.setTimeStamper(timeStamper_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ void TmStoreHelper::setApid(uint16_t apid) { creator.setApid(apid); }
|
|||||||
|
|
||||||
PusTmCreator& TmStoreHelper::getCreatorRef() { return creator; }
|
PusTmCreator& TmStoreHelper::getCreatorRef() { return creator; }
|
||||||
|
|
||||||
TimeStamperIF* TmStoreHelper::getTimeStamper() const { return creator.getTimestamper(); }
|
TimeWriterIF* TmStoreHelper::getTimeStamper() const { return creator.getTimestamper(); }
|
||||||
|
|
||||||
uint16_t TmStoreHelper::getApid() const { return creator.getApid(); }
|
uint16_t TmStoreHelper::getApid() const { return creator.getApid(); }
|
||||||
|
|
||||||
|
@ -4,14 +4,14 @@
|
|||||||
#include "fsfw/internalerror/InternalErrorReporterIF.h"
|
#include "fsfw/internalerror/InternalErrorReporterIF.h"
|
||||||
#include "fsfw/ipc/MessageQueueMessageIF.h"
|
#include "fsfw/ipc/MessageQueueMessageIF.h"
|
||||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||||
#include "fsfw/timemanager/TimeStamperIF.h"
|
#include "fsfw/timemanager/TimeWriterIF.h"
|
||||||
#include "fsfw/tmtcpacket/pus/tm/PusTmCreator.h"
|
#include "fsfw/tmtcpacket/pus/tm/PusTmCreator.h"
|
||||||
|
|
||||||
class TmStoreHelper {
|
class TmStoreHelper {
|
||||||
public:
|
public:
|
||||||
explicit TmStoreHelper(uint16_t defaultApid);
|
explicit TmStoreHelper(uint16_t defaultApid);
|
||||||
TmStoreHelper(uint16_t defaultApid, StorageManagerIF& tmStore);
|
TmStoreHelper(uint16_t defaultApid, StorageManagerIF& tmStore);
|
||||||
TmStoreHelper(uint16_t defaultApid, StorageManagerIF& tmStore, TimeStamperIF& timeStamper);
|
TmStoreHelper(uint16_t defaultApid, StorageManagerIF& tmStore, TimeWriterIF& timeStamper);
|
||||||
|
|
||||||
void disableCrcCalculation();
|
void disableCrcCalculation();
|
||||||
[[nodiscard]] bool crcCalculationEnabled() const;
|
[[nodiscard]] bool crcCalculationEnabled() const;
|
||||||
@ -20,8 +20,8 @@ class TmStoreHelper {
|
|||||||
|
|
||||||
PusTmCreator& getCreatorRef();
|
PusTmCreator& getCreatorRef();
|
||||||
|
|
||||||
void setTimeStamper(TimeStamperIF& timeStamper);
|
void setTimeStamper(TimeWriterIF& timeStamper);
|
||||||
[[nodiscard]] TimeStamperIF* getTimeStamper() const;
|
[[nodiscard]] TimeWriterIF* getTimeStamper() const;
|
||||||
|
|
||||||
[[nodiscard]] StorageManagerIF* getTmStore() const;
|
[[nodiscard]] StorageManagerIF* getTmStore() const;
|
||||||
void setTmStore(StorageManagerIF& store);
|
void setTmStore(StorageManagerIF& store);
|
||||||
|
@ -7,9 +7,10 @@
|
|||||||
|
|
||||||
#define TMTCBRIDGE_WIRETAPPING 0
|
#define TMTCBRIDGE_WIRETAPPING 0
|
||||||
|
|
||||||
TmTcBridge::TmTcBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId,
|
TmTcBridge::TmTcBridge(const char* name, object_id_t objectId, object_id_t tcDestination,
|
||||||
object_id_t tcStoreId)
|
object_id_t tmStoreId, object_id_t tcStoreId)
|
||||||
: SystemObject(objectId),
|
: SystemObject(objectId),
|
||||||
|
name(name),
|
||||||
tmStoreId(tmStoreId),
|
tmStoreId(tmStoreId),
|
||||||
tcStoreId(tcStoreId),
|
tcStoreId(tcStoreId),
|
||||||
tcDestination(tcDestination)
|
tcDestination(tcDestination)
|
||||||
@ -67,8 +68,7 @@ ReturnValue_t TmTcBridge::initialize() {
|
|||||||
#endif
|
#endif
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
AcceptsTelecommandsIF* tcDistributor =
|
auto* tcDistributor = ObjectManager::instance()->get<AcceptsTelecommandsIF>(tcDestination);
|
||||||
ObjectManager::instance()->get<AcceptsTelecommandsIF>(tcDestination);
|
|
||||||
if (tcDistributor == nullptr) {
|
if (tcDistributor == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "TmTcBridge::initialize: TC Distributor invalid" << std::endl;
|
sif::error << "TmTcBridge::initialize: TC Distributor invalid" << std::endl;
|
||||||
@ -246,14 +246,16 @@ MessageQueueId_t TmTcBridge::getReportReceptionQueue(uint8_t virtualChannel) {
|
|||||||
|
|
||||||
void TmTcBridge::printData(uint8_t* data, size_t dataLen) { arrayprinter::print(data, dataLen); }
|
void TmTcBridge::printData(uint8_t* data, size_t dataLen) { arrayprinter::print(data, dataLen); }
|
||||||
|
|
||||||
uint16_t TmTcBridge::getIdentifier() {
|
uint32_t TmTcBridge::getIdentifier() const {
|
||||||
// This is no PUS service, so we just return 0
|
// This is no PUS service, so we just return 0
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t TmTcBridge::getRequestQueue() {
|
MessageQueueId_t TmTcBridge::getRequestQueue() const {
|
||||||
// Default implementation: Relay TC messages to TC distributor directly.
|
// Default implementation: Relay TC messages to TC distributor directly.
|
||||||
return tmTcReceptionQueue->getDefaultDestination();
|
return tmTcReceptionQueue->getDefaultDestination();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TmTcBridge::setFifoToOverwriteOldData(bool overwriteOld) { this->overwriteOld = overwriteOld; }
|
void TmTcBridge::setFifoToOverwriteOldData(bool overwriteOld) { this->overwriteOld = overwriteOld; }
|
||||||
|
|
||||||
|
const char* TmTcBridge::getName() const { return name; }
|
||||||
|
@ -22,9 +22,9 @@ class TmTcBridge : public AcceptsTelemetryIF,
|
|||||||
static constexpr uint8_t DEFAULT_STORED_DATA_SENT_PER_CYCLE = 5;
|
static constexpr uint8_t DEFAULT_STORED_DATA_SENT_PER_CYCLE = 5;
|
||||||
static constexpr uint8_t DEFAULT_DOWNLINK_PACKETS_STORED = 10;
|
static constexpr uint8_t DEFAULT_DOWNLINK_PACKETS_STORED = 10;
|
||||||
|
|
||||||
TmTcBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId,
|
TmTcBridge(const char* name, object_id_t objectId, object_id_t tcDestination,
|
||||||
object_id_t tcStoreId);
|
object_id_t tmStoreId, object_id_t tcStoreId);
|
||||||
virtual ~TmTcBridge();
|
~TmTcBridge() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set number of packets sent per performOperation().Please note that this
|
* Set number of packets sent per performOperation().Please note that this
|
||||||
@ -57,21 +57,24 @@ class TmTcBridge : public AcceptsTelemetryIF,
|
|||||||
* Initializes necessary FSFW components for the TMTC Bridge
|
* Initializes necessary FSFW components for the TMTC Bridge
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Handles TMTC reception
|
* @brief Handles TMTC reception
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
||||||
|
|
||||||
/** AcceptsTelemetryIF override */
|
/** AcceptsTelemetryIF override */
|
||||||
virtual MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0) override;
|
MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0) override;
|
||||||
|
|
||||||
/** AcceptsTelecommandsIF override */
|
/** AcceptsTelecommandsIF override */
|
||||||
virtual uint16_t getIdentifier() override;
|
uint32_t getIdentifier() const override;
|
||||||
virtual MessageQueueId_t getRequestQueue() override;
|
MessageQueueId_t getRequestQueue() const override;
|
||||||
|
const char* getName() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
const char* name = "";
|
||||||
|
|
||||||
//! Cached for initialize function.
|
//! Cached for initialize function.
|
||||||
object_id_t tmStoreId = objects::NO_OBJECT;
|
object_id_t tmStoreId = objects::NO_OBJECT;
|
||||||
object_id_t tcStoreId = objects::NO_OBJECT;
|
object_id_t tcStoreId = objects::NO_OBJECT;
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
namespace tcverif {
|
namespace tcverif {
|
||||||
|
|
||||||
enum VerifFlags : uint8_t {
|
enum VerificationFlags : uint8_t {
|
||||||
NONE = 0b0000,
|
NONE = 0b0000,
|
||||||
ACCEPTANCE = 0b0001,
|
ACCEPTANCE = 0b0001,
|
||||||
START = 0b0010,
|
START = 0b0010,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef FSFW_TMTCSERVICES_TCHELPERS_H
|
#ifndef FSFW_TMTCSERVICES_TCHELPERS_H
|
||||||
#define FSFW_TMTCSERVICES_TCHELPERS_H
|
#define FSFW_TMTCSERVICES_TCHELPERS_H
|
||||||
|
|
||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||||
#include "fsfw/tmtcpacket/pus/tc.h"
|
#include "fsfw/tmtcpacket/pus/tc.h"
|
||||||
|
|
||||||
|
@ -10,48 +10,33 @@ namespace telemetry {
|
|||||||
class DataWithObjectIdPrefix : public SerializeIF {
|
class DataWithObjectIdPrefix : public SerializeIF {
|
||||||
public:
|
public:
|
||||||
DataWithObjectIdPrefix(object_id_t objectId, const uint8_t* srcData, size_t srcDataLen)
|
DataWithObjectIdPrefix(object_id_t objectId, const uint8_t* srcData, size_t srcDataLen)
|
||||||
: objectId(objectId) {
|
: objectId(objectId), bufAdapter(srcData, srcDataLen), userData(&bufAdapter) {}
|
||||||
dataWrapper.type = ecss::DataTypes::RAW;
|
|
||||||
dataWrapper.dataUnion.raw.data = srcData;
|
|
||||||
dataWrapper.dataUnion.raw.len = srcDataLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataWithObjectIdPrefix(object_id_t objectId, SerializeIF& serializable) : objectId(objectId) {
|
DataWithObjectIdPrefix(object_id_t objectId, const SerializeIF& serializable)
|
||||||
dataWrapper.type = ecss::DataTypes::SERIALIZABLE;
|
: objectId(objectId), userData(&serializable) {}
|
||||||
dataWrapper.dataUnion.serializable = &serializable;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||||
Endianness streamEndianness) const override {
|
Endianness streamEndianness) const override {
|
||||||
if (*size + getSerializedSize() > maxSize) {
|
if (*size + getSerializedSize() > maxSize) {
|
||||||
return SerializeIF::BUFFER_TOO_SHORT;
|
return SerializeIF::BUFFER_TOO_SHORT;
|
||||||
}
|
}
|
||||||
if (dataWrapper.type != ecss::DataTypes::RAW) {
|
|
||||||
if ((dataWrapper.dataUnion.raw.data == nullptr) and (dataWrapper.dataUnion.raw.len > 0)) {
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
} else if (dataWrapper.type == ecss::DataTypes::SERIALIZABLE) {
|
|
||||||
if (dataWrapper.dataUnion.serializable == nullptr) {
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ReturnValue_t result =
|
ReturnValue_t result =
|
||||||
SerializeAdapter::serialize(&objectId, buffer, size, maxSize, streamEndianness);
|
SerializeAdapter::serialize(&objectId, buffer, size, maxSize, streamEndianness);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (dataWrapper.type != ecss::DataTypes::RAW) {
|
if (userData != nullptr) {
|
||||||
std::memcpy(*buffer, dataWrapper.dataUnion.raw.data, dataWrapper.dataUnion.raw.len);
|
return userData->serialize(buffer, size, maxSize, streamEndianness);
|
||||||
*buffer += dataWrapper.dataUnion.raw.len;
|
|
||||||
*size += dataWrapper.dataUnion.raw.len;
|
|
||||||
} else {
|
|
||||||
return dataWrapper.dataUnion.serializable->serialize(buffer, size, maxSize, streamEndianness);
|
|
||||||
}
|
}
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] size_t getSerializedSize() const override {
|
[[nodiscard]] size_t getSerializedSize() const override {
|
||||||
return sizeof(objectId) + dataWrapper.getLength();
|
size_t len = 0;
|
||||||
|
if (userData != nullptr) {
|
||||||
|
len += userData->getSerializedSize();
|
||||||
|
}
|
||||||
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||||
@ -63,7 +48,8 @@ class DataWithObjectIdPrefix : public SerializeIF {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
object_id_t objectId;
|
object_id_t objectId;
|
||||||
ecss::DataWrapper dataWrapper{};
|
SerialBufferAdapter<uint8_t> bufAdapter;
|
||||||
|
const SerializeIF* userData = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace telemetry
|
} // namespace telemetry
|
||||||
|
@ -1 +1,3 @@
|
|||||||
add_subdirectory(gpio)
|
add_subdirectory(gpio)
|
||||||
|
|
||||||
|
target_sources(${LIB_FSFW_NAME} PRIVATE printChar.c)
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user