Compare commits
313 Commits
v5.0.0
...
108e7737e2
Author | SHA1 | Date | |
---|---|---|---|
108e7737e2 | |||
c90d1c8071 | |||
eae75b29e7 | |||
dc79b7ba00 | |||
db84dcd3ce | |||
935f35a40d | |||
348af0124b | |||
04bff7a522 | |||
5c20cc804e | |||
eb8e236cd4 | |||
7dec45ccf2 | |||
2b01e86f9c | |||
60fd3d43c0 | |||
67980cb592 | |||
3010f2f925 | |||
01651f0521 | |||
c7f300671f | |||
7d3223d766 | |||
7ae82a5cb4 | |||
28ecd0e5c6 | |||
7345c18b04 | |||
0de7b66218 | |||
158007fa7f | |||
ab719a3e59 | |||
64a7fde301 | |||
8e6cee7761 | |||
c756297e5c | |||
0f27c7e7e7 | |||
20d42add03 | |||
a9277622ce | |||
80e8511a43 | |||
4a06f11582 | |||
32c53b932d | |||
aea9db75cb | |||
9fedd03ed8 | |||
10fc4dd89d | |||
0cc8af5eb0 | |||
92d65aa3a5 | |||
342a56410c | |||
2cab73d972 | |||
9a9085b9e6 | |||
cb23911ccd | |||
b499dedd76 | |||
1bb487373d | |||
3bffb4f968 | |||
6bcb208968 | |||
6c2b5ab39e | |||
a7039bad41 | |||
6605ffb6b1 | |||
e2e0190cae | |||
fd278e410b | |||
ff4cbea571 | |||
81a7c21cd1 | |||
267466be9d | |||
2c730c8632 | |||
eb29b79467 | |||
26ea6606bf | |||
b1bd631322 | |||
9441b4a70e | |||
95457b1760 | |||
a46d8c34d9 | |||
d12c59c8ac | |||
9e5dddf79c | |||
ba5c6410d6 | |||
52f8c5038b | |||
10f34e5a48 | |||
dab1b1d067 | |||
8c8d1cfa84 | |||
2a4ab0af7b | |||
7c59df3f1c | |||
3b33b429e6 | |||
ff6de8e378 | |||
11a699c3ce | |||
6930656d4e | |||
0bb82e0da2 | |||
12c452e7ce | |||
23f514039a | |||
2e52d7a31d | |||
239d053562 | |||
875174c4ad | |||
8fd8a37f59 | |||
217276d50c | |||
d2ac3603a5 | |||
f63f3fa564 | |||
fc34d56239 | |||
1037102349 | |||
221361eb9c | |||
7f9269b387 | |||
4224c3d009 | |||
62fe75ee40 | |||
e76e109bdb | |||
9e064fe800 | |||
2339c48756 | |||
d7ec04bf4b | |||
adcc375f25 | |||
94a718ff19 | |||
4a10f76784 | |||
57ce5d1f34 | |||
90963b3940 | |||
71ed95b09a | |||
7ac4f1c64d | |||
9d64b96e9a | |||
5de2c6af66 | |||
ca2efb6021 | |||
3b000d924a | |||
deeeef553b | |||
0e7ec79af9 | |||
d3cabd8984 | |||
8efe85cb15 | |||
b28c26b288 | |||
8b4253bc46 | |||
c12492df03 | |||
8aaabc5d73 | |||
e796e025b6 | |||
20eee2c469 | |||
aca8b53a59 | |||
3df1161560 | |||
ea6e5d9971 | |||
46a4203d00 | |||
c86adf8e10 | |||
a2e0646ed4 | |||
28c8248f26 | |||
3e1fd15613 | |||
e45a99143c | |||
96dfe46e25 | |||
507c6ddff1 | |||
0cb15e901e | |||
d45108e3c2 | |||
8c059f8f32 | |||
5bea92d2a4 | |||
bba2d883b6 | |||
7a20412305 | |||
dce1ebcf65 | |||
4ee01e395b | |||
7f9401cf63 | |||
dba3f9960e | |||
eccb629ba8 | |||
7fb906a0ac | |||
9796abfc7d | |||
0d26a0f54b | |||
192956c2c7 | |||
22e1555f50 | |||
bddf5bded1 | |||
1c0b778848 | |||
c832bffdb0 | |||
2f8020baac | |||
06bea2f621 | |||
4f1fe39182 | |||
904abfba28 | |||
202d9341d8 | |||
37c60d1dd0 | |||
43fb6ef5cb | |||
65a47c7c57 | |||
fdb0cc0e44 | |||
e6957de166 | |||
cc56b00df3 | |||
269a3052ca | |||
c6a7a0fec8 | |||
acf5c2a56d | |||
7fb9e14555 | |||
b20e8a9679 | |||
29bcaee196 | |||
cc98512caf | |||
60ea9a9a7c | |||
df690b9628 | |||
b0c479cab9 | |||
a426aef7c7 | |||
43048c852a | |||
19817bd3a5 | |||
1db04cf20c | |||
902a4bfa9c | |||
52ee50ba8c | |||
bf540ebb49 | |||
aa978205d8 | |||
4334106ad1 | |||
458fe460eb | |||
83d71548ec | |||
f4beef8c9f | |||
c7b4dc349a | |||
96f092ef75 | |||
f75379fceb | |||
4a4d23573d | |||
cd4d92b12c | |||
47e148af8f | |||
c9bec03f00 | |||
6c5c59cad8 | |||
03e12a2388 | |||
6c5bbfa080 | |||
da106fd96f | |||
fc3412fa35 | |||
8f6f0e1d45 | |||
1b5fa2a8fa | |||
cb118176a0 | |||
30ba9ab916 | |||
fb4ba487b5 | |||
72bc5d4d60 | |||
5355e63711 | |||
b11cdf6184 | |||
dc31358d52 | |||
b485afea57 | |||
5bb7023ff3 | |||
85dbef20b0 | |||
93acac02f5 | |||
7e8afcc12f | |||
f03b7cd660 | |||
d641d63531 | |||
4e571e5082 | |||
356d778743 | |||
0a38d2e22d | |||
234ccdf764 | |||
f591b9793c | |||
c5ad9b5fa9 | |||
083d08ae2a | |||
740644f2c8 | |||
059fb10558 | |||
86692e202d | |||
064b195c75 | |||
18ee2ab903 | |||
9eb652e585 | |||
e7d9979078 | |||
681738dcc6 | |||
152c01b2ec | |||
8bf0fb9885 | |||
1954ce0ea4 | |||
d98b79cf5e | |||
f14c812aff | |||
146a0e3828 | |||
75c824ec80 | |||
332e9dbfd5 | |||
f1c37203a4 | |||
500a5602bd | |||
4ed028000d | |||
88ebb67c8d | |||
b827bd8370 | |||
bdf71d4e66 | |||
e48b6f1432 | |||
747243684d | |||
db33f9cc7e | |||
c12669fe50 | |||
6d00fc65c0 | |||
7d87274844 | |||
c83f75c515 | |||
586993c081 | |||
a88f767cca | |||
935e135f1c | |||
6d0fa36f8a | |||
8f07133e2c | |||
5fd5d488ff | |||
f80be9e9fa | |||
f3af88ae40 | |||
380f1d0206 | |||
9ee6da47e9 | |||
1a7d7b172b | |||
36e3956efb | |||
180210dc38 | |||
ca1e921b94 | |||
2a34c831b1 | |||
e2ad37e3e6 | |||
973d4ee8a5 | |||
899d021e00 | |||
4989bd0f02 | |||
832367fb30 | |||
63ee88af17 | |||
4921527022 | |||
f0c8fd2688 | |||
d474c4a7ee | |||
3708df2423 | |||
f629d60aaf | |||
b809f90e72 | |||
f2bf4b463e | |||
b66fd63cb4 | |||
fd55de9e95 | |||
8e05fc0417 | |||
55a238d553 | |||
9ccd9fd775 | |||
ddad97033d | |||
99aaf7068d | |||
c9d37e8d62 | |||
42a1d6cccd | |||
133894f4ba | |||
cb05329dd9 | |||
b350018cad | |||
2dfbce6174 | |||
cecaec6007 | |||
f28b9ea61b | |||
9275ccb79b | |||
67776241de | |||
bfee4fd90a | |||
0dfaba81f9 | |||
affde6bad5 | |||
0981ee6f7e | |||
61bc867bed | |||
5af3138e81 | |||
08e0b0f1a0 | |||
23f264096c | |||
e5ee96259d | |||
d8b6cb39ac | |||
be35bd53a6 | |||
9860061fc6 | |||
d80941514f | |||
6c636661b6 | |||
5fffbd4a90 | |||
95b476d4bd | |||
3d2af203f2 | |||
ddf38b65c3 | |||
490a80e49f | |||
e4d7182d93 | |||
7e2fdc06cd | |||
3c72a42ce1 | |||
0c5f623780 | |||
d7a2eada94 | |||
546e173cef | |||
0a7f2c6646 |
19
CHANGELOG.md
19
CHANGELOG.md
@@ -8,6 +8,23 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
# [unreleased]
|
||||
|
||||
# [v6.0.0]
|
||||
|
||||
## Added
|
||||
|
||||
- Add new `UnsignedByteField` class
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/660
|
||||
|
||||
## Changes
|
||||
|
||||
- Removed `HasReturnvaluesIF` class in favor of `returnvalue` namespace with `OK` and `FAILED`
|
||||
constants.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/659
|
||||
- Overhaul of the TMTC stack, including various changes and improvements
|
||||
for other modules
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/655
|
||||
which also includes a migration guide
|
||||
|
||||
# [v5.0.0] 25.07.2022
|
||||
|
||||
## Changes
|
||||
@@ -24,7 +41,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- HAL Devicehandlers: Periodic printout is run-time configurable now
|
||||
- `oneShotAction` flag in the `TestTask` class is not static anymore
|
||||
- `SimpleRingBuffer::writeData` now checks if the amount is larger than the total size of the
|
||||
Buffer and rejects such writeData calls with `HasReturnvaluesIF::RETURN_FAILED`
|
||||
Buffer and rejects such writeData calls with `returnvalue::FAILED`
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/586
|
||||
- Major update for version handling, using `git describe` to fetch version information with git.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/601
|
||||
|
@@ -104,7 +104,8 @@ if(FSFW_GENERATE_SECTIONS)
|
||||
option(FSFW_REMOVE_UNUSED_CODE "Remove unused code" ON)
|
||||
endif()
|
||||
|
||||
option(FSFW_BUILD_TESTS "Build unittest binary in addition to static library"
|
||||
option(FSFW_BUILD_TESTS
|
||||
"Build unittest binary in addition to static library. Requires Catch2"
|
||||
OFF)
|
||||
option(FSFW_CICD_BUILD "Build for CI/CD. This can disable problematic test" OFF)
|
||||
option(FSFW_BUILD_DOCS "Build documentation with Sphinx and Doxygen" OFF)
|
||||
@@ -115,9 +116,14 @@ endif()
|
||||
option(FSFW_WARNING_SHADOW_LOCAL_GCC "Enable -Wshadow=local warning in GCC" ON)
|
||||
# Options to exclude parts of the FSFW from compilation.
|
||||
option(FSFW_ADD_INTERNAL_TESTS "Add internal unit tests" ON)
|
||||
option(FSFW_ADD_UNITTESTS "Add regular unittests. Requires Catch2" OFF)
|
||||
option(FSFW_ADD_HAL "Add Hardware Abstraction Layer" ON)
|
||||
|
||||
if(UNIX)
|
||||
option(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS "Add Linux peripheral drivers"
|
||||
OFF)
|
||||
option(FSFW_HAL_LINUX_ADD_LIBGPIOD "Attempt to add Linux GPIOD drivers" OFF)
|
||||
endif()
|
||||
|
||||
# Optional sources
|
||||
option(FSFW_ADD_PUS "Compile with PUS sources" ON)
|
||||
option(FSFW_ADD_MONITORING "Compile with monitoring components" ON)
|
||||
@@ -183,7 +189,10 @@ if(FSFW_BUILD_TESTS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
message(STATUS "${MSG_PREFIX} Finding and/or providing ETL library")
|
||||
message(
|
||||
STATUS
|
||||
"${MSG_PREFIX} Finding and/or providing etl library with version ${FSFW_ETL_LIB_MAJOR_VERSION}"
|
||||
)
|
||||
|
||||
# Check whether the user has already installed ETL first
|
||||
find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET)
|
||||
@@ -191,7 +200,7 @@ find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET)
|
||||
if(NOT ${FSFW_ETL_LIB_NAME}_FOUND)
|
||||
message(
|
||||
STATUS
|
||||
"No ETL installation was found with find_package. Installing and providing "
|
||||
"${MSG_PREFIX} No ETL installation was found with find_package. Installing and providing "
|
||||
"etl with FindPackage")
|
||||
include(FetchContent)
|
||||
|
||||
|
@@ -132,7 +132,7 @@ You can use the following commands inside the `fsfw` folder to set up the build
|
||||
|
||||
```sh
|
||||
mkdir build-tests && cd build-tests
|
||||
cmake -DFSFW_BUILD_UNITTESTS=ON -DFSFW_OSAL=host -DCMAKE_BUILD_TYPE=Debug ..
|
||||
cmake -DFSFW_BUILD_TESTS=ON -DFSFW_OSAL=host -DCMAKE_BUILD_TYPE=Debug ..
|
||||
```
|
||||
|
||||
You can also use `-DFSFW_OSAL=linux` on Linux systems.
|
||||
|
2
automation/Jenkinsfile
vendored
2
automation/Jenkinsfile
vendored
@@ -1,6 +1,6 @@
|
||||
pipeline {
|
||||
environment {
|
||||
BUILDDIR = 'build-tests'
|
||||
BUILDDIR = 'cmake-build-tests'
|
||||
}
|
||||
agent {
|
||||
docker { image 'fsfw-ci:d3'}
|
||||
|
@@ -14,7 +14,7 @@ FSFW to achieve that. The fsfw uses run-time type information but exceptions are
|
||||
# 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 `HasReturnvaluesIF::makeReturnCode`
|
||||
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.
|
||||
|
@@ -144,7 +144,7 @@ ReturnValue_t GyroHandler::initializeLocalDataPool(localpool::DataPool &localDat
|
||||
new PoolEntry<uint8_t>({0}));
|
||||
|
||||
poolManager.subscribeForPeriodicPacket(gyroData.getSid(), false, 4.0, false);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
```
|
||||
|
||||
@@ -154,7 +154,7 @@ in any case:
|
||||
|
||||
```cpp
|
||||
PoolReadGuard readHelper(&gyroData);
|
||||
if(readHelper.getReadResult() == HasReturnvaluesIF::RETURN_OK) {
|
||||
if(readHelper.getReadResult() == returnvalue::OK) {
|
||||
if(not gyroData.isValid()) {
|
||||
gyroData.setValidity(true, true);
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@ API
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
|
||||
api/cfdp
|
||||
api/objectmanager
|
||||
api/task
|
||||
api/ipc
|
||||
|
8
docs/api/cfdp.rst
Normal file
8
docs/api/cfdp.rst
Normal file
@@ -0,0 +1,8 @@
|
||||
CFDP API
|
||||
=================
|
||||
|
||||
``UserBase``
|
||||
-----------------
|
||||
|
||||
.. doxygenclass:: cfdp::UserBase
|
||||
:members:
|
@@ -3,7 +3,7 @@
|
||||
Returnvalue API
|
||||
==================
|
||||
|
||||
.. doxygenfile:: HasReturnvaluesIF.h
|
||||
.. doxygenfile:: returnvalue.h
|
||||
|
||||
.. _fwclassids:
|
||||
|
||||
|
18
docs/conf.py
18
docs/conf.py
@@ -17,12 +17,12 @@
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = 'Flight Software Framework'
|
||||
copyright = '2021, Institute of Space Systems (IRS)'
|
||||
author = 'Institute of Space Systems (IRS)'
|
||||
project = "Flight Software Framework"
|
||||
copyright = "2021, Institute of Space Systems (IRS)"
|
||||
author = "Institute of Space Systems (IRS)"
|
||||
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = '2.0.1'
|
||||
release = "2.0.1"
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
@@ -30,17 +30,17 @@ release = '2.0.1'
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [ "breathe" ]
|
||||
extensions = ["breathe"]
|
||||
|
||||
breathe_default_project = "fsfw"
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
templates_path = ["_templates"]
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This pattern also affects html_static_path and html_extra_path.
|
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
@@ -48,9 +48,9 @@ exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
html_theme = 'alabaster'
|
||||
html_theme = "alabaster"
|
||||
|
||||
# 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,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = []
|
||||
html_static_path = []
|
||||
|
@@ -75,11 +75,11 @@ and the respective source file with sensible default return values:
|
||||
void TestDeviceHandler::doShutDown() {}
|
||||
|
||||
ReturnValue_t TestDeviceHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t TestDeviceHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
void TestDeviceHandler::fillCommandAndReplyMap() {}
|
||||
@@ -87,17 +87,17 @@ and the respective source file with sensible default return values:
|
||||
ReturnValue_t TestDeviceHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
|
||||
const uint8_t* commandData,
|
||||
size_t commandDataLen) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t TestDeviceHandler::scanForReply(const uint8_t* start, size_t remainingSize,
|
||||
DeviceCommandId_t* foundId, size_t* foundLen) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t TestDeviceHandler::interpretDeviceReply(DeviceCommandId_t id,
|
||||
const uint8_t* packet) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
uint32_t TestDeviceHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) {
|
||||
@@ -106,5 +106,5 @@ and the respective source file with sensible default return values:
|
||||
|
||||
ReturnValue_t TestDeviceHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
@@ -106,7 +106,7 @@ You can use the following commands inside the ``fsfw`` folder to set up the buil
|
||||
.. code-block:: console
|
||||
|
||||
mkdir build-tests && cd build-tests
|
||||
cmake -DFSFW_BUILD_UNITTESTS=ON -DFSFW_OSAL=host ..
|
||||
cmake -DFSFW_BUILD_TESTS=ON -DFSFW_OSAL=host ..
|
||||
|
||||
|
||||
You can also use ``-DFSFW_OSAL=linux`` on Linux systems.
|
||||
|
@@ -7,18 +7,20 @@ 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.
|
||||
The FSFW uses C++17 as baseline.
|
||||
It also 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 will not throw exceptions.
|
||||
|
||||
Failure Handling
|
||||
-----------------
|
||||
|
||||
Functions should return a defined :cpp:type:`ReturnValue_t` to signal to the caller that something has
|
||||
gone wrong. Returnvalues must be unique. For this the function :cpp:func:`HasReturnvaluesIF::makeReturnCode`
|
||||
gone wrong. Returnvalues must be unique. For this the function :cpp:func:`returnvalue::makeCode`
|
||||
or the :ref:`macro MAKE_RETURN_CODE <retvalapi>` can be used. The ``CLASS_ID`` is a unique ID for that type of object.
|
||||
See the :ref:`FSFW Class IDs file <fwclassids>`. The user can add custom ``CLASS_ID``\s via the
|
||||
``fsfwconfig`` folder.
|
||||
|
@@ -150,7 +150,7 @@ with a housekeeping service command.
|
||||
new PoolEntry<uint8_t>({0}));
|
||||
|
||||
poolManager.subscribeForPeriodicPacket(gyroData.getSid(), false, 4.0, false);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
Now, if we receive some sensor data and converted them into the right format,
|
||||
@@ -160,7 +160,7 @@ in any case:
|
||||
.. code-block:: cpp
|
||||
|
||||
PoolReadGuard readHelper(&gyroData);
|
||||
if(readHelper.getReadResult() == HasReturnvaluesIF::RETURN_OK) {
|
||||
if(readHelper.getReadResult() == returnvalue::OK) {
|
||||
if(not gyroData.isValid()) {
|
||||
gyroData.setValidity(true, true);
|
||||
}
|
||||
|
@@ -35,8 +35,8 @@ void Factory::produceFsfwObjects(void) {
|
||||
}
|
||||
|
||||
void Factory::setStaticFrameworkObjectIds() {
|
||||
PusServiceBase::packetSource = objects::NO_OBJECT;
|
||||
PusServiceBase::packetDestination = objects::NO_OBJECT;
|
||||
PusServiceBase::PUS_DISTRIBUTOR = objects::NO_OBJECT;
|
||||
PusServiceBase::PACKET_DESTINATION = objects::NO_OBJECT;
|
||||
|
||||
CommandingServiceBase::defaultPacketSource = objects::NO_OBJECT;
|
||||
CommandingServiceBase::defaultPacketDestination = objects::NO_OBJECT;
|
||||
|
@@ -11,15 +11,15 @@ ReturnValue_t pst::pollingSequenceInitDefault(
|
||||
|
||||
/* Add polling sequence table here */
|
||||
|
||||
if (thisSequence->checkSequence() == HasReturnvaluesIF::RETURN_OK) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
if (thisSequence->checkSequence() == returnvalue::OK) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
else {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "pst::pollingSequenceInitDefault: Sequence invalid!"
|
||||
<< std::endl;
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#ifndef POLLINGSEQUENCEFACTORY_H_
|
||||
#define POLLINGSEQUENCEFACTORY_H_
|
||||
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <fsfw/returnvalues/returnvalue.h>
|
||||
|
||||
class FixedTimeslotTaskIF;
|
||||
|
||||
|
@@ -3,11 +3,17 @@ if [[ ! -f README.md ]]; then
|
||||
cd ..
|
||||
fi
|
||||
|
||||
folder_list=(
|
||||
"./src"
|
||||
"./unittests"
|
||||
)
|
||||
|
||||
cmake_fmt="cmake-format"
|
||||
file_selectors="-iname CMakeLists.txt"
|
||||
if command -v ${cmake_fmt} &> /dev/null; then
|
||||
${cmake_fmt} -i CMakeLists.txt
|
||||
find ./src ${file_selectors} | xargs ${cmake_fmt} -i
|
||||
find ./src ${file_selectors} | xargs ${cmake_fmt} -i
|
||||
find ./unittests ${file_selectors} | xargs ${cmake_fmt} -i
|
||||
else
|
||||
echo "No ${cmake_fmt} tool found, not formatting CMake files"
|
||||
fi
|
||||
@@ -15,8 +21,10 @@ fi
|
||||
cpp_format="clang-format"
|
||||
file_selectors="-iname *.h -o -iname *.cpp -o -iname *.c -o -iname *.tpp"
|
||||
if command -v ${cpp_format} &> /dev/null; then
|
||||
find ./src ${file_selectors} | xargs ${cpp_format} --style=file -i
|
||||
find ./unittests ${file_selectors} | xargs ${cpp_format} --style=file -i
|
||||
for dir in ${folder_list[@]}; do
|
||||
echo "Auto-formatting ${dir} recursively"
|
||||
find ${dir} ${file_selectors} | xargs clang-format --style=file -i
|
||||
done
|
||||
else
|
||||
echo "No ${cpp_format} tool found, not formatting C++/C files"
|
||||
fi
|
||||
|
@@ -13,7 +13,7 @@ from shutil import which
|
||||
from typing import List
|
||||
|
||||
|
||||
UNITTEST_FOLDER_NAME = "build-tests"
|
||||
UNITTEST_FOLDER_NAME = "cmake-build-tests"
|
||||
DOCS_FOLDER_NAME = "build-docs"
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ def main():
|
||||
parser.add_argument(
|
||||
"-g",
|
||||
"--generators",
|
||||
default = "Ninja",
|
||||
default="Ninja",
|
||||
action="store",
|
||||
help="CMake generators",
|
||||
)
|
||||
@@ -165,10 +165,18 @@ def create_tests_build_cfg(args):
|
||||
os.mkdir(UNITTEST_FOLDER_NAME)
|
||||
os.chdir(UNITTEST_FOLDER_NAME)
|
||||
if args.windows:
|
||||
cmake_cmd = 'cmake -G "' + args.generators + '" -DFSFW_OSAL=host -DFSFW_BUILD_TESTS=ON \
|
||||
cmake_cmd = (
|
||||
'cmake -G "'
|
||||
+ args.generators
|
||||
+ '" -DFSFW_OSAL=host -DFSFW_BUILD_TESTS=ON \
|
||||
-DGCOVR_PATH="py -m gcovr" ..'
|
||||
)
|
||||
else:
|
||||
cmake_cmd = 'cmake -G "' + args.generators + '" -DFSFW_OSAL=host -DFSFW_BUILD_TESTS=ON ..'
|
||||
cmake_cmd = (
|
||||
'cmake -G "'
|
||||
+ args.generators
|
||||
+ '" -DFSFW_OSAL=host -DFSFW_BUILD_TESTS=ON ..'
|
||||
)
|
||||
cmd_runner(cmake_cmd)
|
||||
os.chdir("..")
|
||||
|
||||
|
@@ -31,6 +31,7 @@ add_subdirectory(thermal)
|
||||
add_subdirectory(timemanager)
|
||||
add_subdirectory(tmtcpacket)
|
||||
add_subdirectory(tmtcservices)
|
||||
add_subdirectory(filesystem)
|
||||
|
||||
# Optional
|
||||
|
||||
|
@@ -12,7 +12,7 @@ ReturnValue_t ActionHelper::handleActionMessage(CommandMessage* command) {
|
||||
if (command->getCommand() == ActionMessage::EXECUTE_ACTION) {
|
||||
ActionId_t currentAction = ActionMessage::getActionId(command);
|
||||
prepareExecution(command->getSender(), currentAction, ActionMessage::getStoreId(command));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
} else {
|
||||
return CommandMessage::UNKNOWN_COMMAND;
|
||||
}
|
||||
@@ -21,7 +21,7 @@ ReturnValue_t ActionHelper::handleActionMessage(CommandMessage* command) {
|
||||
ReturnValue_t ActionHelper::initialize(MessageQueueIF* queueToUse_) {
|
||||
ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
||||
if (ipcStore == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
if (queueToUse_ != nullptr) {
|
||||
setQueueToUse(queueToUse_);
|
||||
@@ -35,10 +35,10 @@ ReturnValue_t ActionHelper::initialize(MessageQueueIF* queueToUse_) {
|
||||
sif::printWarning("ActionHelper::initialize: No queue set\n");
|
||||
#endif
|
||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
void ActionHelper::step(uint8_t step, MessageQueueId_t reportTo, ActionId_t commandId,
|
||||
@@ -62,7 +62,7 @@ void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t act
|
||||
const uint8_t* dataPtr = nullptr;
|
||||
size_t size = 0;
|
||||
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result != returnvalue::OK) {
|
||||
CommandMessage reply;
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
@@ -75,7 +75,7 @@ void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t act
|
||||
ActionMessage::setCompletionReply(&reply, actionId, true, result);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
}
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result != returnvalue::OK) {
|
||||
CommandMessage reply;
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
@@ -91,11 +91,11 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, ActionId_t rep
|
||||
size_t maxSize = data->getSerializedSize();
|
||||
if (maxSize == 0) {
|
||||
/* No error, there's simply nothing to report. */
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
size_t size = 0;
|
||||
ReturnValue_t result = ipcStore->getFreeElement(&storeAddress, maxSize, &dataPtr);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result != returnvalue::OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "ActionHelper::reportData: Getting free element from IPC store failed!"
|
||||
<< std::endl;
|
||||
@@ -107,7 +107,7 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, ActionId_t rep
|
||||
return result;
|
||||
}
|
||||
result = data->serialize(&dataPtr, &size, maxSize, SerializeIF::Endianness::BIG);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result != returnvalue::OK) {
|
||||
ipcStore->deleteData(storeAddress);
|
||||
return result;
|
||||
}
|
||||
@@ -124,7 +124,7 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, ActionId_t rep
|
||||
result = queueToUse->sendMessage(reportTo, &reply);
|
||||
}
|
||||
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result != returnvalue::OK) {
|
||||
ipcStore->deleteData(storeAddress);
|
||||
}
|
||||
return result;
|
||||
@@ -137,7 +137,7 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, ActionId_t rep
|
||||
CommandMessage reply;
|
||||
store_address_t storeAddress;
|
||||
ReturnValue_t result = ipcStore->addData(&storeAddress, data, dataSize);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result != returnvalue::OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "ActionHelper::reportData: Adding data to IPC store failed!" << std::endl;
|
||||
#else
|
||||
@@ -158,7 +158,7 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, ActionId_t rep
|
||||
result = queueToUse->sendMessage(reportTo, &reply);
|
||||
}
|
||||
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result != returnvalue::OK) {
|
||||
ipcStore->deleteData(storeAddress);
|
||||
}
|
||||
return result;
|
||||
|
@@ -36,7 +36,7 @@ class ActionHelper {
|
||||
* send to the sender of the message automatically.
|
||||
*
|
||||
* @param command Pointer to a command message received by the owner
|
||||
* @return HasReturnvaluesIF::RETURN_OK if the message is a action message,
|
||||
* @return returnvalue::OK if the message is a action message,
|
||||
* CommandMessage::UNKNOW_COMMAND if this message ID is unkown
|
||||
*/
|
||||
ReturnValue_t handleActionMessage(CommandMessage* command);
|
||||
@@ -45,7 +45,7 @@ class ActionHelper {
|
||||
* helper function
|
||||
* @param queueToUse_ Pointer to the messageQueue to be used, optional
|
||||
* if queue was set in constructor
|
||||
* @return Returns RETURN_OK if successful
|
||||
* @return Returns returnvalue::OK if successful
|
||||
*/
|
||||
ReturnValue_t initialize(MessageQueueIF* queueToUse_ = nullptr);
|
||||
/**
|
||||
@@ -58,7 +58,7 @@ class ActionHelper {
|
||||
* @param result Result of the execution
|
||||
*/
|
||||
void step(uint8_t step, MessageQueueId_t reportTo, ActionId_t commandId,
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
ReturnValue_t result = returnvalue::OK);
|
||||
/**
|
||||
* Function to be called by the owner to send a action completion message
|
||||
* @param success Specify whether action was completed successfully or not.
|
||||
@@ -67,7 +67,7 @@ class ActionHelper {
|
||||
* @param result Result of the execution
|
||||
*/
|
||||
void finish(bool success, MessageQueueId_t reportTo, ActionId_t commandId,
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
ReturnValue_t result = returnvalue::OK);
|
||||
/**
|
||||
* Function to be called by the owner if an action does report data.
|
||||
* Takes a SerializeIF* pointer and serializes it into the IPC store.
|
||||
@@ -75,7 +75,7 @@ class ActionHelper {
|
||||
* message to
|
||||
* @param replyId ID of the executed command
|
||||
* @param data Pointer to the data
|
||||
* @return Returns RETURN_OK if successful, otherwise failure code
|
||||
* @return Returns returnvalue::OK if successful, otherwise failure code
|
||||
*/
|
||||
ReturnValue_t reportData(MessageQueueId_t reportTo, ActionId_t replyId, SerializeIF* data,
|
||||
bool hideSender = false);
|
||||
@@ -86,7 +86,7 @@ class ActionHelper {
|
||||
* message to
|
||||
* @param replyId ID of the executed command
|
||||
* @param data Pointer to the data
|
||||
* @return Returns RETURN_OK if successful, otherwise failure code
|
||||
* @return Returns returnvalue::OK if successful, otherwise failure code
|
||||
*/
|
||||
ReturnValue_t reportData(MessageQueueId_t reportTo, ActionId_t replyId, const uint8_t* data,
|
||||
size_t dataSize, bool hideSender = false);
|
||||
|
@@ -25,7 +25,7 @@ store_address_t ActionMessage::getStoreId(const CommandMessage* message) {
|
||||
|
||||
void ActionMessage::setStepReply(CommandMessage* message, ActionId_t fid, uint8_t step,
|
||||
ReturnValue_t result) {
|
||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result == returnvalue::OK) {
|
||||
message->setCommand(STEP_SUCCESS);
|
||||
} else {
|
||||
message->setCommand(STEP_FAILED);
|
||||
|
@@ -33,12 +33,12 @@ class ActionMessage {
|
||||
static store_address_t getStoreId(const CommandMessage* message);
|
||||
|
||||
static void setStepReply(CommandMessage* message, ActionId_t fid, uint8_t step,
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
ReturnValue_t result = returnvalue::OK);
|
||||
static uint8_t getStep(const CommandMessage* message);
|
||||
static ReturnValue_t getReturnCode(const CommandMessage* message);
|
||||
static void setDataReply(CommandMessage* message, ActionId_t actionId, store_address_t data);
|
||||
static void setCompletionReply(CommandMessage* message, ActionId_t fid, bool success,
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
ReturnValue_t result = returnvalue::OK);
|
||||
|
||||
static void clear(CommandMessage* message);
|
||||
};
|
||||
|
@@ -16,12 +16,12 @@ ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo, ActionId
|
||||
uint8_t *storePointer;
|
||||
size_t maxSize = data->getSerializedSize();
|
||||
ReturnValue_t result = ipcStore->getFreeElement(&storeId, maxSize, &storePointer);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
size_t size = 0;
|
||||
result = data->serialize(&storePointer, &size, maxSize, SerializeIF::Endianness::BIG);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
return sendCommand(receiver->getCommandQueue(), actionId, storeId);
|
||||
@@ -35,7 +35,7 @@ ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo, ActionId
|
||||
}
|
||||
store_address_t storeId;
|
||||
ReturnValue_t result = ipcStore->addData(&storeId, data, size);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
return sendCommand(receiver->getCommandQueue(), actionId, storeId);
|
||||
@@ -46,7 +46,7 @@ ReturnValue_t CommandActionHelper::sendCommand(MessageQueueId_t queueId, ActionI
|
||||
CommandMessage command;
|
||||
ActionMessage::setCommand(&command, actionId, storeId);
|
||||
ReturnValue_t result = queueToUse->sendMessage(queueId, &command);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result != returnvalue::OK) {
|
||||
ipcStore->deleteData(storeId);
|
||||
}
|
||||
lastTarget = queueId;
|
||||
@@ -57,44 +57,44 @@ ReturnValue_t CommandActionHelper::sendCommand(MessageQueueId_t queueId, ActionI
|
||||
ReturnValue_t CommandActionHelper::initialize() {
|
||||
ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
||||
if (ipcStore == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
||||
queueToUse = owner->getCommandQueuePtr();
|
||||
if (queueToUse == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t CommandActionHelper::handleReply(CommandMessage *reply) {
|
||||
if (reply->getSender() != lastTarget) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
switch (reply->getCommand()) {
|
||||
case ActionMessage::COMPLETION_SUCCESS:
|
||||
commandCount--;
|
||||
owner->completionSuccessfulReceived(ActionMessage::getActionId(reply));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
case ActionMessage::COMPLETION_FAILED:
|
||||
commandCount--;
|
||||
owner->completionFailedReceived(ActionMessage::getActionId(reply),
|
||||
ActionMessage::getReturnCode(reply));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
case ActionMessage::STEP_SUCCESS:
|
||||
owner->stepSuccessfulReceived(ActionMessage::getActionId(reply),
|
||||
ActionMessage::getStep(reply));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
case ActionMessage::STEP_FAILED:
|
||||
commandCount--;
|
||||
owner->stepFailedReceived(ActionMessage::getActionId(reply), ActionMessage::getStep(reply),
|
||||
ActionMessage::getReturnCode(reply));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
case ActionMessage::DATA_REPLY:
|
||||
extractDataForOwner(ActionMessage::getActionId(reply), ActionMessage::getStoreId(reply));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
default:
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ void CommandActionHelper::extractDataForOwner(ActionId_t actionId, store_address
|
||||
const uint8_t *data = nullptr;
|
||||
size_t size = 0;
|
||||
ReturnValue_t result = ipcStore->getData(storeId, &data, &size);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result != returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
owner->dataReceived(actionId, data, size);
|
||||
|
@@ -4,7 +4,7 @@
|
||||
#include "ActionMessage.h"
|
||||
#include "fsfw/ipc/MessageQueueIF.h"
|
||||
#include "fsfw/objectmanager/ObjectManagerIF.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include "fsfw/returnvalues/returnvalue.h"
|
||||
#include "fsfw/serialize/SerializeIF.h"
|
||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "CommandActionHelper.h"
|
||||
#include "fsfw/ipc/MessageQueueIF.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include "fsfw/returnvalues/returnvalue.h"
|
||||
|
||||
/**
|
||||
* Interface to separate commanding actions of other objects.
|
||||
|
@@ -5,7 +5,7 @@
|
||||
#include "ActionMessage.h"
|
||||
#include "SimpleActionHelper.h"
|
||||
#include "fsfw/ipc/MessageQueueIF.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include "fsfw/returnvalues/returnvalue.h"
|
||||
|
||||
/**
|
||||
* @brief
|
||||
@@ -53,7 +53,7 @@ class HasActionsIF {
|
||||
*
|
||||
* @return
|
||||
* -@c EXECUTION_FINISHED Finish reply will be generated
|
||||
* -@c Not RETURN_OK Step failure reply will be generated
|
||||
* -@c Not returnvalue::OK Step failure reply will be generated
|
||||
*/
|
||||
virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size) = 0;
|
||||
|
@@ -9,7 +9,7 @@ void SimpleActionHelper::step(ReturnValue_t result) {
|
||||
// STEP_OFFESET is subtracted to compensate for adding offset in base
|
||||
// method, which is not necessary here.
|
||||
ActionHelper::step(stepCount - STEP_OFFSET, lastCommander, lastAction, result);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result != returnvalue::OK) {
|
||||
resetHelper();
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@ void SimpleActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId
|
||||
const uint8_t* dataPtr = nullptr;
|
||||
size_t size = 0;
|
||||
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result != returnvalue::OK) {
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
return;
|
||||
@@ -51,12 +51,12 @@ void SimpleActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId
|
||||
result = owner->executeAction(actionId, commandedBy, dataPtr, size);
|
||||
ipcStore->deleteData(dataAddress);
|
||||
switch (result) {
|
||||
case HasReturnvaluesIF::RETURN_OK:
|
||||
case returnvalue::OK:
|
||||
isExecuting = true;
|
||||
stepCount++;
|
||||
break;
|
||||
case HasActionsIF::EXECUTION_FINISHED:
|
||||
ActionMessage::setCompletionReply(&reply, actionId, true, HasReturnvaluesIF::RETURN_OK);
|
||||
ActionMessage::setCompletionReply(&reply, actionId, true, returnvalue::OK);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
break;
|
||||
default:
|
||||
|
@@ -12,8 +12,8 @@ class SimpleActionHelper : public ActionHelper {
|
||||
public:
|
||||
SimpleActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
|
||||
~SimpleActionHelper() override;
|
||||
void step(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
void finish(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
void step(ReturnValue_t result = returnvalue::OK);
|
||||
void finish(ReturnValue_t result = returnvalue::OK);
|
||||
ReturnValue_t reportData(SerializeIF* data);
|
||||
|
||||
protected:
|
||||
|
11
src/fsfw/cfdp.h
Normal file
11
src/fsfw/cfdp.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef FSFW_CFDP_H
|
||||
#define FSFW_CFDP_H
|
||||
|
||||
#include "cfdp/definitions.h"
|
||||
#include "cfdp/handler/DestHandler.h"
|
||||
#include "cfdp/handler/FaultHandlerBase.h"
|
||||
#include "cfdp/tlv/Lv.h"
|
||||
#include "cfdp/tlv/StringLv.h"
|
||||
#include "cfdp/tlv/Tlv.h"
|
||||
|
||||
#endif // FSFW_CFDP_H
|
@@ -1,57 +0,0 @@
|
||||
#include "fsfw/cfdp/CFDPHandler.h"
|
||||
|
||||
#include "fsfw/cfdp/CFDPMessage.h"
|
||||
#include "fsfw/ipc/CommandMessage.h"
|
||||
#include "fsfw/ipc/QueueFactory.h"
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw/storagemanager/storeAddress.h"
|
||||
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
|
||||
|
||||
object_id_t CFDPHandler::packetSource = 0;
|
||||
object_id_t CFDPHandler::packetDestination = 0;
|
||||
|
||||
CFDPHandler::CFDPHandler(object_id_t setObjectId, CFDPDistributor* dist)
|
||||
: SystemObject(setObjectId) {
|
||||
requestQueue = QueueFactory::instance()->createMessageQueue(CFDP_HANDLER_MAX_RECEPTION);
|
||||
distributor = dist;
|
||||
}
|
||||
|
||||
CFDPHandler::~CFDPHandler() {}
|
||||
|
||||
ReturnValue_t CFDPHandler::initialize() {
|
||||
ReturnValue_t result = SystemObject::initialize();
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
this->distributor->registerHandler(this);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t CFDPHandler::handleRequest(store_address_t storeId) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "CFDPHandler::handleRequest" << std::endl;
|
||||
#else
|
||||
sif::printDebug("CFDPHandler::handleRequest\n");
|
||||
#endif /* !FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||
#endif
|
||||
|
||||
// TODO read out packet from store using storeId
|
||||
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t CFDPHandler::performOperation(uint8_t opCode) {
|
||||
ReturnValue_t status = RETURN_OK;
|
||||
CommandMessage currentMessage;
|
||||
for (status = this->requestQueue->receiveMessage(¤tMessage); status == RETURN_OK;
|
||||
status = this->requestQueue->receiveMessage(¤tMessage)) {
|
||||
store_address_t storeId = CFDPMessage::getStoreId(¤tMessage);
|
||||
this->handleRequest(storeId);
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
uint16_t CFDPHandler::getIdentifier() { return 0; }
|
||||
|
||||
MessageQueueId_t CFDPHandler::getRequestQueue() { return this->requestQueue->getId(); }
|
@@ -1,63 +0,0 @@
|
||||
#ifndef FSFW_CFDP_CFDPHANDLER_H_
|
||||
#define FSFW_CFDP_CFDPHANDLER_H_
|
||||
|
||||
#include "fsfw/ipc/MessageQueueIF.h"
|
||||
#include "fsfw/objectmanager/SystemObject.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||
#include "fsfw/tcdistribution/CFDPDistributor.h"
|
||||
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
||||
|
||||
namespace Factory {
|
||||
void setStaticFrameworkObjectIds();
|
||||
}
|
||||
|
||||
class CFDPHandler : public ExecutableObjectIF,
|
||||
public AcceptsTelecommandsIF,
|
||||
public SystemObject,
|
||||
public HasReturnvaluesIF {
|
||||
friend void(Factory::setStaticFrameworkObjectIds)();
|
||||
|
||||
public:
|
||||
CFDPHandler(object_id_t setObjectId, CFDPDistributor* distributor);
|
||||
/**
|
||||
* The destructor is empty.
|
||||
*/
|
||||
virtual ~CFDPHandler();
|
||||
|
||||
virtual ReturnValue_t handleRequest(store_address_t storeId);
|
||||
|
||||
virtual ReturnValue_t initialize() override;
|
||||
virtual uint16_t getIdentifier() override;
|
||||
MessageQueueId_t getRequestQueue() override;
|
||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* This is a complete instance of the telecommand reception queue
|
||||
* of the class. It is initialized on construction of the class.
|
||||
*/
|
||||
MessageQueueIF* requestQueue = nullptr;
|
||||
|
||||
CFDPDistributor* distributor = nullptr;
|
||||
|
||||
/**
|
||||
* The current CFDP packet to be processed.
|
||||
* It is deleted after handleRequest was executed.
|
||||
*/
|
||||
CFDPPacketStored currentPacket;
|
||||
|
||||
static object_id_t packetSource;
|
||||
|
||||
static object_id_t packetDestination;
|
||||
|
||||
private:
|
||||
/**
|
||||
* This constant sets the maximum number of packets accepted per call.
|
||||
* Remember that one packet must be completely handled in one
|
||||
* #handleRequest call.
|
||||
*/
|
||||
static const uint8_t CFDP_HANDLER_MAX_RECEPTION = 100;
|
||||
};
|
||||
|
||||
#endif /* FSFW_CFDP_CFDPHANDLER_H_ */
|
@@ -1,17 +0,0 @@
|
||||
#include "CFDPMessage.h"
|
||||
|
||||
CFDPMessage::CFDPMessage() {}
|
||||
|
||||
CFDPMessage::~CFDPMessage() {}
|
||||
|
||||
void CFDPMessage::setCommand(CommandMessage *message, store_address_t cfdpPacket) {
|
||||
message->setParameter(cfdpPacket.raw);
|
||||
}
|
||||
|
||||
store_address_t CFDPMessage::getStoreId(const CommandMessage *message) {
|
||||
store_address_t storeAddressCFDPPacket;
|
||||
storeAddressCFDPPacket = message->getParameter();
|
||||
return storeAddressCFDPPacket;
|
||||
}
|
||||
|
||||
void CFDPMessage::clear(CommandMessage *message) {}
|
@@ -1,4 +1,6 @@
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE CFDPHandler.cpp CFDPMessage.cpp)
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE CfdpMessage.cpp CfdpDistributor.cpp
|
||||
VarLenFields.cpp)
|
||||
|
||||
add_subdirectory(pdu)
|
||||
add_subdirectory(tlv)
|
||||
add_subdirectory(handler)
|
||||
|
54
src/fsfw/cfdp/CfdpDistributor.cpp
Normal file
54
src/fsfw/cfdp/CfdpDistributor.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include "CfdpDistributor.h"
|
||||
|
||||
#include "fsfw/tcdistribution/definitions.h"
|
||||
|
||||
CfdpDistributor::CfdpDistributor(CfdpDistribCfg cfg)
|
||||
: TcDistributorBase(cfg.objectId, cfg.tcQueue), cfg(cfg) {}
|
||||
|
||||
ReturnValue_t CfdpDistributor::registerTcDestination(const cfdp::EntityId& address,
|
||||
AcceptsTelecommandsIF& tcDest) {
|
||||
for (const auto& dest : tcDestinations) {
|
||||
if (dest.id == address) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
}
|
||||
tcDestinations.emplace_back(address, tcDest.getName(), tcDest.getRequestQueue());
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t CfdpDistributor::selectDestination(MessageQueueId_t& destId) {
|
||||
auto accessorPair = cfg.tcStore.getData(currentMessage.getStorageId());
|
||||
if (accessorPair.first != returnvalue::OK) {
|
||||
return accessorPair.first;
|
||||
}
|
||||
ReturnValue_t result = pduReader.setData(accessorPair.second.data(), accessorPair.second.size());
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = pduReader.parseData();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
cfdp::EntityId foundId;
|
||||
pduReader.getDestId(foundId);
|
||||
bool destFound = false;
|
||||
for (const auto& dest : tcDestinations) {
|
||||
if (dest.id == foundId) {
|
||||
destId = dest.queueId;
|
||||
destFound = true;
|
||||
}
|
||||
}
|
||||
if (not destFound) {
|
||||
// TODO: Warning and event?
|
||||
return tmtcdistrib::NO_DESTINATION_FOUND;
|
||||
}
|
||||
// Packet was forwarded successfully, so do not delete it.
|
||||
accessorPair.second.release();
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
const char* CfdpDistributor::getName() const { return "CFDP Distributor"; }
|
||||
|
||||
uint32_t CfdpDistributor::getIdentifier() const { return 0; }
|
||||
|
||||
MessageQueueId_t CfdpDistributor::getRequestQueue() const { return tcQueue->getId(); }
|
76
src/fsfw/cfdp/CfdpDistributor.h
Normal file
76
src/fsfw/cfdp/CfdpDistributor.h
Normal file
@@ -0,0 +1,76 @@
|
||||
#ifndef FSFW_TCDISTRIBUTION_CFDPDISTRIBUTOR_H_
|
||||
#define FSFW_TCDISTRIBUTION_CFDPDISTRIBUTOR_H_
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "fsfw/cfdp/pdu/HeaderReader.h"
|
||||
#include "fsfw/returnvalues/returnvalue.h"
|
||||
#include "fsfw/tcdistribution/CfdpPacketChecker.h"
|
||||
#include "fsfw/tcdistribution/TcDistributorBase.h"
|
||||
#include "fsfw/tmtcpacket/cfdp/CfdpPacketStored.h"
|
||||
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
||||
#include "fsfw/tmtcservices/VerificationReporter.h"
|
||||
|
||||
struct CfdpDistribCfg {
|
||||
CfdpDistribCfg(object_id_t objectId, StorageManagerIF& tcStore, MessageQueueIF* tcQueue)
|
||||
: objectId(objectId), tcStore(tcStore), tcQueue(tcQueue) {}
|
||||
|
||||
object_id_t objectId;
|
||||
StorageManagerIF& tcStore;
|
||||
MessageQueueIF* tcQueue;
|
||||
};
|
||||
|
||||
/**
|
||||
* This will be the primary component to perform PDU forwading procedures. This includes forwarding
|
||||
* CFDP TC packets to registered source or destination handlers, and forwarding all telemetry
|
||||
* generated by them to registered TM sinks.
|
||||
* @ingroup tc_distribution
|
||||
*/
|
||||
class CfdpDistributor : public TcDistributorBase, public AcceptsTelecommandsIF {
|
||||
public:
|
||||
/**
|
||||
* The ctor passes @c set_apid to the checker class and calls the
|
||||
* TcDistribution ctor with a certain object id.
|
||||
* @param setApid The APID of this receiving Application.
|
||||
* @param setObjectId Object ID of the distributor itself
|
||||
* @param setPacketSource Object ID of the source of TC packets.
|
||||
* Must implement CcsdsDistributorIF.
|
||||
*/
|
||||
explicit CfdpDistributor(CfdpDistribCfg cfg);
|
||||
|
||||
[[nodiscard]] const char* getName() const override;
|
||||
[[nodiscard]] uint32_t getIdentifier() const override;
|
||||
[[nodiscard]] MessageQueueId_t getRequestQueue() const override;
|
||||
|
||||
/**
|
||||
* Register a new CFDP entity which can receive PDUs.
|
||||
* @param address
|
||||
* @param tcDest
|
||||
* @return
|
||||
* - @c RETURN_FAILED: Entry already exists for the given address
|
||||
*/
|
||||
ReturnValue_t registerTcDestination(const cfdp::EntityId& address, AcceptsTelecommandsIF& tcDest);
|
||||
|
||||
protected:
|
||||
struct EntityInfo {
|
||||
EntityInfo(cfdp::EntityId id, const char* name, MessageQueueId_t queueId)
|
||||
: id(std::move(id)), name(name), queueId(queueId) {}
|
||||
cfdp::EntityId id;
|
||||
const char* name;
|
||||
MessageQueueId_t queueId;
|
||||
};
|
||||
HeaderReader pduReader;
|
||||
ReturnValue_t lastTcError = returnvalue::OK;
|
||||
ReturnValue_t lastTmError = returnvalue::OK;
|
||||
// I don't think a regular OBSW will have more than 1 or 2 of these destinations, so I think
|
||||
// it is okay to accept the overhead here
|
||||
std::vector<EntityInfo> tcDestinations;
|
||||
CfdpDistribCfg cfg;
|
||||
|
||||
ReturnValue_t selectDestination(MessageQueueId_t& destId) override;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif /* FSFW_TCDISTRIBUTION_CFDPDISTRIBUTOR_H_ */
|
54
src/fsfw/cfdp/CfdpHandler.cpp
Normal file
54
src/fsfw/cfdp/CfdpHandler.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
//#include "fsfw/cfdp/CfdpHandler.h"
|
||||
//
|
||||
//#include "fsfw/cfdp/CfdpMessage.h"
|
||||
//#include "fsfw/ipc/CommandMessage.h"
|
||||
//#include "fsfw/ipc/QueueFactory.h"
|
||||
//#include "fsfw/objectmanager/ObjectManager.h"
|
||||
//#include "fsfw/storagemanager/storeAddress.h"
|
||||
//#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
|
||||
//
|
||||
// CfdpHandler::CfdpHandler(object_id_t setObjectId, CfdpHandler* dist)
|
||||
// : SystemObject(setObjectId) {
|
||||
// requestQueue = QueueFactory::instance()->createMessageQueue(CFDP_HANDLER_MAX_RECEPTION);
|
||||
// distributor = dist;
|
||||
//}
|
||||
//
|
||||
// CfdpHandler::~CfdpHandler() = default;
|
||||
//
|
||||
// ReturnValue_t CfdpHandler::initialize() {
|
||||
// ReturnValue_t result = SystemObject::initialize();
|
||||
// if (result != RETURN_OK) {
|
||||
// return result;
|
||||
// }
|
||||
// this->distributor->registerHandler(this);
|
||||
// return HasReturnvaluesIF::RETURN_OK;
|
||||
//}
|
||||
//
|
||||
// ReturnValue_t CfdpHandler::handleRequest(store_address_t storeId) {
|
||||
//#if FSFW_VERBOSE_LEVEL >= 1
|
||||
//#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
// sif::debug << "CFDPHandler::handleRequest" << std::endl;
|
||||
//#else
|
||||
// sif::printDebug("CFDPHandler::handleRequest\n");
|
||||
//#endif /* !FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||
//#endif
|
||||
//
|
||||
// // TODO read out packet from store using storeId
|
||||
//
|
||||
// return RETURN_OK;
|
||||
//}
|
||||
//
|
||||
// ReturnValue_t CfdpHandler::performOperation(uint8_t opCode) {
|
||||
// ReturnValue_t status = RETURN_OK;
|
||||
// CommandMessage currentMessage;
|
||||
// for (status = this->requestQueue->receiveMessage(¤tMessage); status == RETURN_OK;
|
||||
// status = this->requestQueue->receiveMessage(¤tMessage)) {
|
||||
// store_address_t storeId = CfdpMessage::getStoreId(¤tMessage);
|
||||
// this->handleRequest(storeId);
|
||||
// }
|
||||
// return RETURN_OK;
|
||||
//}
|
||||
//
|
||||
// uint32_t CfdpHandler::getIdentifier() const { return 0; }
|
||||
//
|
||||
// MessageQueueId_t CfdpHandler::getRequestQueue() const { return this->requestQueue->getId(); }
|
63
src/fsfw/cfdp/CfdpHandler.h
Normal file
63
src/fsfw/cfdp/CfdpHandler.h
Normal file
@@ -0,0 +1,63 @@
|
||||
//#ifndef FSFW_CFDP_CFDPHANDLER_H_
|
||||
//#define FSFW_CFDP_CFDPHANDLER_H_
|
||||
//
|
||||
//#include "fsfw/ipc/MessageQueueIF.h"
|
||||
//#include "fsfw/objectmanager/SystemObject.h"
|
||||
//#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
//#include "fsfw/storagemanager/storeAddress.h"
|
||||
//#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||
//#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
||||
//
|
||||
// namespace Factory {
|
||||
// void setStaticFrameworkObjectIds();
|
||||
//}
|
||||
//
|
||||
// class CfdpHandler : public ExecutableObjectIF,
|
||||
// public AcceptsTelecommandsIF,
|
||||
// public SystemObject,
|
||||
// public HasReturnvaluesIF {
|
||||
// friend void(Factory::setStaticFrameworkObjectIds)();
|
||||
//
|
||||
// public:
|
||||
// CfdpHandler(object_id_t setObjectId, CfdpHandler* distributor);
|
||||
// /**
|
||||
// * The destructor is empty.
|
||||
// */
|
||||
// virtual ~CfdpHandler();
|
||||
//
|
||||
// virtual ReturnValue_t handleRequest(store_address_t storeId);
|
||||
//
|
||||
// virtual ReturnValue_t initialize() override;
|
||||
// virtual uint32_t getIdentifier() const override;
|
||||
// MessageQueueId_t getRequestQueue() const override;
|
||||
// ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
//
|
||||
// protected:
|
||||
// /**
|
||||
// * This is a complete instance of the telecommand reception queue
|
||||
// * of the class. It is initialized on construction of the class.
|
||||
// */
|
||||
// MessageQueueIF* requestQueue = nullptr;
|
||||
//
|
||||
// CfdpHandler* distributor = nullptr;
|
||||
//
|
||||
// /**
|
||||
// * The current CFDP packet to be processed.
|
||||
// * It is deleted after handleRequest was executed.
|
||||
// */
|
||||
// CfdpPacketStored currentPacket;
|
||||
//
|
||||
// static object_id_t packetSource;
|
||||
//
|
||||
// static object_id_t packetDestination;
|
||||
//
|
||||
// private:
|
||||
// /**
|
||||
// * This constant sets the maximum number of packets accepted per call.
|
||||
// * Remember that one packet must be completely handled in one
|
||||
// * #handleRequest call.
|
||||
// */
|
||||
// static const uint8_t CFDP_HANDLER_MAX_RECEPTION = 100;
|
||||
//};
|
||||
//
|
||||
//#endif /* FSFW_CFDP_CFDPHANDLER_H_ */
|
17
src/fsfw/cfdp/CfdpMessage.cpp
Normal file
17
src/fsfw/cfdp/CfdpMessage.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "CfdpMessage.h"
|
||||
|
||||
CfdpMessage::CfdpMessage() = default;
|
||||
|
||||
CfdpMessage::~CfdpMessage() = default;
|
||||
|
||||
void CfdpMessage::setCommand(CommandMessage *message, store_address_t cfdpPacket) {
|
||||
message->setParameter(cfdpPacket.raw);
|
||||
}
|
||||
|
||||
store_address_t CfdpMessage::getStoreId(const CommandMessage *message) {
|
||||
store_address_t storeId;
|
||||
storeId = static_cast<store_address_t>(message->getParameter());
|
||||
return storeId;
|
||||
}
|
||||
|
||||
void CfdpMessage::clear(CommandMessage *message) {}
|
@@ -5,14 +5,14 @@
|
||||
#include "fsfw/objectmanager/ObjectManagerIF.h"
|
||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||
|
||||
class CFDPMessage {
|
||||
class CfdpMessage {
|
||||
private:
|
||||
CFDPMessage();
|
||||
CfdpMessage();
|
||||
|
||||
public:
|
||||
static const uint8_t MESSAGE_ID = messagetypes::CFDP;
|
||||
|
||||
virtual ~CFDPMessage();
|
||||
virtual ~CfdpMessage();
|
||||
static void setCommand(CommandMessage* message, store_address_t cfdpPacket);
|
||||
|
||||
static store_address_t getStoreId(const CommandMessage* message);
|
@@ -1,5 +1,7 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_FILESIZE_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_FILESIZE_H_
|
||||
#ifndef FSFW_CFDP_FILESIZE_H_
|
||||
#define FSFW_CFDP_FILESIZE_H_
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include "fsfw/serialize/SerializeAdapter.h"
|
||||
#include "fsfw/serialize/SerializeIF.h"
|
||||
@@ -8,9 +10,11 @@ namespace cfdp {
|
||||
|
||||
struct FileSize : public SerializeIF {
|
||||
public:
|
||||
FileSize() : largeFile(false){};
|
||||
FileSize() = default;
|
||||
|
||||
FileSize(uint64_t fileSize, bool isLarge = false) { setFileSize(fileSize, isLarge); };
|
||||
explicit FileSize(uint64_t fileSize, bool isLarge = false) { setFileSize(fileSize, isLarge); };
|
||||
|
||||
[[nodiscard]] uint64_t value() const { return fileSize; }
|
||||
|
||||
ReturnValue_t serialize(bool isLarge, uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) {
|
||||
@@ -27,7 +31,7 @@ struct FileSize : public SerializeIF {
|
||||
return SerializeAdapter::serialize(&fileSize, buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
|
||||
size_t getSerializedSize() const override {
|
||||
[[nodiscard]] size_t getSerializedSize() const override {
|
||||
if (largeFile) {
|
||||
return 8;
|
||||
} else {
|
||||
@@ -43,27 +47,29 @@ struct FileSize : public SerializeIF {
|
||||
uint32_t sizeTmp = 0;
|
||||
ReturnValue_t result =
|
||||
SerializeAdapter::deSerialize(&sizeTmp, buffer, size, streamEndianness);
|
||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result == returnvalue::OK) {
|
||||
fileSize = sizeTmp;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t setFileSize(uint64_t fileSize, bool largeFile) {
|
||||
ReturnValue_t setFileSize(uint64_t fileSize_, std::optional<bool> largeFile_) {
|
||||
if (largeFile_) {
|
||||
largeFile = largeFile_.value();
|
||||
}
|
||||
if (not largeFile and fileSize > UINT32_MAX) {
|
||||
// TODO: emit warning here
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
this->fileSize = fileSize;
|
||||
this->largeFile = largeFile;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
this->fileSize = fileSize_;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
bool isLargeFile() const { return largeFile; }
|
||||
uint64_t getSize(bool *largeFile = nullptr) const {
|
||||
if (largeFile != nullptr) {
|
||||
*largeFile = this->largeFile;
|
||||
[[nodiscard]] bool isLargeFile() const { return largeFile; }
|
||||
uint64_t getSize(bool *largeFile_ = nullptr) const {
|
||||
if (largeFile_ != nullptr) {
|
||||
*largeFile_ = this->largeFile;
|
||||
}
|
||||
return fileSize;
|
||||
}
|
||||
@@ -75,4 +81,4 @@ struct FileSize : public SerializeIF {
|
||||
|
||||
} // namespace cfdp
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_FILESIZE_H_ */
|
||||
#endif /* FSFW_CFDP_FILESIZE_H_ */
|
||||
|
@@ -1,12 +1,11 @@
|
||||
#include "VarLenField.h"
|
||||
#include "VarLenFields.h"
|
||||
|
||||
#include "fsfw/FSFW.h"
|
||||
#include "fsfw/serialize/SerializeAdapter.h"
|
||||
#include "fsfw/serviceinterface.h"
|
||||
|
||||
cfdp::VarLenField::VarLenField(cfdp::WidthInBytes width, size_t value) : VarLenField() {
|
||||
ReturnValue_t result = this->setValue(width, value);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result != returnvalue::OK) {
|
||||
#if FSFW_DISABLE_PRINTOUT == 0
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "cfdp::VarLenField: Setting value failed" << std::endl;
|
||||
@@ -21,27 +20,27 @@ cfdp::VarLenField::VarLenField() : width(cfdp::WidthInBytes::ONE_BYTE) { value.o
|
||||
|
||||
cfdp::WidthInBytes cfdp::VarLenField::getWidth() const { return width; }
|
||||
|
||||
ReturnValue_t cfdp::VarLenField::setValue(cfdp::WidthInBytes widthInBytes, size_t value) {
|
||||
ReturnValue_t cfdp::VarLenField::setValue(cfdp::WidthInBytes widthInBytes, size_t value_) {
|
||||
switch (widthInBytes) {
|
||||
case (cfdp::WidthInBytes::ONE_BYTE): {
|
||||
if (value > UINT8_MAX) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
if (value_ > UINT8_MAX) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
this->value.oneByte = value;
|
||||
this->value.oneByte = value_;
|
||||
break;
|
||||
}
|
||||
case (cfdp::WidthInBytes::TWO_BYTES): {
|
||||
if (value > UINT16_MAX) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
if (value_ > UINT16_MAX) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
this->value.twoBytes = value;
|
||||
this->value.twoBytes = value_;
|
||||
break;
|
||||
}
|
||||
case (cfdp::WidthInBytes::FOUR_BYTES): {
|
||||
if (value > UINT32_MAX) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
if (value_ > UINT32_MAX) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
this->value.fourBytes = value;
|
||||
this->value.fourBytes = value_;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -49,7 +48,7 @@ ReturnValue_t cfdp::VarLenField::setValue(cfdp::WidthInBytes widthInBytes, size_
|
||||
}
|
||||
}
|
||||
this->width = widthInBytes;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
size_t cfdp::VarLenField::getValue() const {
|
||||
@@ -77,7 +76,7 @@ ReturnValue_t cfdp::VarLenField::serialize(uint8_t **buffer, size_t *size, size_
|
||||
**buffer = value.oneByte;
|
||||
*size += 1;
|
||||
*buffer += 1;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
case (cfdp::WidthInBytes::TWO_BYTES): {
|
||||
return SerializeAdapter::serialize(&value.twoBytes, buffer, size, maxSize, streamEndianness);
|
||||
@@ -86,16 +85,16 @@ ReturnValue_t cfdp::VarLenField::serialize(uint8_t **buffer, size_t *size, size_
|
||||
return SerializeAdapter::serialize(&value.fourBytes, buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
default: {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t cfdp::VarLenField::getSerializedSize() const { return width; }
|
||||
|
||||
ReturnValue_t cfdp::VarLenField::deSerialize(cfdp::WidthInBytes width, const uint8_t **buffer,
|
||||
ReturnValue_t cfdp::VarLenField::deSerialize(cfdp::WidthInBytes width_, const uint8_t **buffer,
|
||||
size_t *size, Endianness streamEndianness) {
|
||||
this->width = width;
|
||||
this->width = width_;
|
||||
return deSerialize(buffer, size, streamEndianness);
|
||||
}
|
||||
|
||||
@@ -105,7 +104,7 @@ ReturnValue_t cfdp::VarLenField::deSerialize(const uint8_t **buffer, size_t *siz
|
||||
case (cfdp::WidthInBytes::ONE_BYTE): {
|
||||
value.oneByte = **buffer;
|
||||
*size += 1;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
case (cfdp::WidthInBytes::TWO_BYTES): {
|
||||
return SerializeAdapter::deSerialize(&value.twoBytes, buffer, size, streamEndianness);
|
||||
@@ -114,7 +113,21 @@ ReturnValue_t cfdp::VarLenField::deSerialize(const uint8_t **buffer, size_t *siz
|
||||
return SerializeAdapter::deSerialize(&value.fourBytes, buffer, size, streamEndianness);
|
||||
}
|
||||
default: {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool cfdp::VarLenField::operator<(const cfdp::VarLenField &other) const {
|
||||
if (getWidth() < other.getWidth()) {
|
||||
return true;
|
||||
} else if (getWidth() == other.getWidth()) {
|
||||
return getValue() < other.getValue();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool cfdp::VarLenField::operator==(const cfdp::VarLenField &other) const {
|
||||
return getWidth() == other.getWidth() and getValue() == other.getValue();
|
||||
}
|
91
src/fsfw/cfdp/VarLenFields.h
Normal file
91
src/fsfw/cfdp/VarLenFields.h
Normal file
@@ -0,0 +1,91 @@
|
||||
#ifndef FSFW_CFDP_PDU_VARLENFIELD_H_
|
||||
#define FSFW_CFDP_PDU_VARLENFIELD_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
|
||||
#include "fsfw/cfdp/definitions.h"
|
||||
#include "fsfw/serialize/SerializeIF.h"
|
||||
#include "fsfw/util/UnsignedByteField.h"
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
class VarLenField : public SerializeIF {
|
||||
public:
|
||||
union LengthFieldLen {
|
||||
uint8_t oneByte;
|
||||
uint16_t twoBytes;
|
||||
uint32_t fourBytes;
|
||||
uint64_t eightBytes;
|
||||
};
|
||||
|
||||
VarLenField();
|
||||
template <typename T>
|
||||
explicit VarLenField(UnsignedByteField<T> byteField);
|
||||
|
||||
VarLenField(cfdp::WidthInBytes width, size_t value);
|
||||
|
||||
bool operator==(const VarLenField &other) const;
|
||||
bool operator<(const VarLenField &other) const;
|
||||
|
||||
ReturnValue_t setValue(cfdp::WidthInBytes, size_t value);
|
||||
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
[[nodiscard]] size_t getSerializedSize() const override;
|
||||
|
||||
ReturnValue_t deSerialize(cfdp::WidthInBytes width, const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness);
|
||||
|
||||
[[nodiscard]] cfdp::WidthInBytes getWidth() const;
|
||||
[[nodiscard]] size_t getValue() const;
|
||||
|
||||
private:
|
||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
cfdp::WidthInBytes width;
|
||||
LengthFieldLen value{};
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
cfdp::VarLenField::VarLenField(UnsignedByteField<T> byteField)
|
||||
: width(static_cast<cfdp::WidthInBytes>(sizeof(T))) {
|
||||
static_assert((sizeof(T) % 2) == 0);
|
||||
setValue(width, byteField.getValue());
|
||||
}
|
||||
|
||||
struct EntityId : public VarLenField {
|
||||
public:
|
||||
EntityId() : VarLenField() {}
|
||||
template <typename T>
|
||||
explicit EntityId(UnsignedByteField<T> byteField) : VarLenField(byteField) {}
|
||||
EntityId(cfdp::WidthInBytes width, size_t entityId) : VarLenField(width, entityId) {}
|
||||
};
|
||||
|
||||
struct TransactionSeqNum : public VarLenField {
|
||||
public:
|
||||
TransactionSeqNum() : VarLenField() {}
|
||||
template <typename T>
|
||||
explicit TransactionSeqNum(UnsignedByteField<T> byteField) : VarLenField(byteField) {}
|
||||
TransactionSeqNum(cfdp::WidthInBytes width, size_t seqNum) : VarLenField(width, seqNum) {}
|
||||
};
|
||||
|
||||
struct TransactionId {
|
||||
TransactionId() = default;
|
||||
TransactionId(EntityId entityId, TransactionSeqNum seqNum)
|
||||
: entityId(std::move(entityId)), seqNum(std::move(seqNum)) {}
|
||||
|
||||
bool operator==(const TransactionId &other) {
|
||||
return entityId == other.entityId and seqNum == other.seqNum;
|
||||
}
|
||||
|
||||
EntityId entityId;
|
||||
TransactionSeqNum seqNum;
|
||||
};
|
||||
|
||||
} // namespace cfdp
|
||||
|
||||
#endif /* FSFW_CFDP_PDU_VARLENFIELD_H_ */
|
@@ -7,36 +7,36 @@
|
||||
#include <cstdint>
|
||||
|
||||
#include "fsfw/returnvalues/FwClassIds.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include "fsfw/returnvalues/returnvalue.h"
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
static constexpr uint8_t VERSION_BITS = 0b00100000;
|
||||
static constexpr char CFDP_VERSION_2_NAME[] = "CCSDS 727.0-B-5";
|
||||
|
||||
// Second version of the protocol, only this one is supported here
|
||||
static constexpr uint8_t CFDP_VERSION_2 = 0b001;
|
||||
static constexpr uint8_t VERSION_BITS = CFDP_VERSION_2 << 5;
|
||||
|
||||
static constexpr uint8_t CFDP_CLASS_ID = CLASS_ID::CFDP;
|
||||
|
||||
static constexpr ReturnValue_t INVALID_TLV_TYPE =
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 1);
|
||||
static constexpr ReturnValue_t INVALID_DIRECTIVE_FIELDS =
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 2);
|
||||
static constexpr ReturnValue_t INVALID_PDU_DATAFIELD_LEN =
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 3);
|
||||
static constexpr ReturnValue_t INVALID_TLV_TYPE = returnvalue::makeCode(CFDP_CLASS_ID, 1);
|
||||
static constexpr ReturnValue_t INVALID_DIRECTIVE_FIELDS = returnvalue::makeCode(CFDP_CLASS_ID, 2);
|
||||
static constexpr ReturnValue_t INVALID_PDU_DATAFIELD_LEN = returnvalue::makeCode(CFDP_CLASS_ID, 3);
|
||||
static constexpr ReturnValue_t INVALID_ACK_DIRECTIVE_FIELDS =
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 4);
|
||||
returnvalue::makeCode(CFDP_CLASS_ID, 4);
|
||||
//! Can not parse options. This can also occur because there are options
|
||||
//! available but the user did not pass a valid options array
|
||||
static constexpr ReturnValue_t METADATA_CANT_PARSE_OPTIONS =
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 5);
|
||||
static constexpr ReturnValue_t NAK_CANT_PARSE_OPTIONS =
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 6);
|
||||
returnvalue::makeCode(CFDP_CLASS_ID, 5);
|
||||
static constexpr ReturnValue_t NAK_CANT_PARSE_OPTIONS = returnvalue::makeCode(CFDP_CLASS_ID, 6);
|
||||
static constexpr ReturnValue_t FINISHED_CANT_PARSE_FS_RESPONSES =
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 6);
|
||||
returnvalue::makeCode(CFDP_CLASS_ID, 6);
|
||||
static constexpr ReturnValue_t FILESTORE_REQUIRES_SECOND_FILE =
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 8);
|
||||
returnvalue::makeCode(CFDP_CLASS_ID, 8);
|
||||
//! Can not parse filestore response because user did not pass a valid instance
|
||||
//! or remaining size is invalid
|
||||
static constexpr ReturnValue_t FILESTORE_RESPONSE_CANT_PARSE_FS_MESSAGE =
|
||||
HasReturnvaluesIF::makeReturnCode(CFDP_CLASS_ID, 9);
|
||||
returnvalue::makeCode(CFDP_CLASS_ID, 9);
|
||||
|
||||
//! Checksum types according to the SANA Checksum Types registry
|
||||
//! https://sanaregistry.org/r/checksum_identifiers/
|
||||
@@ -49,17 +49,17 @@ enum ChecksumType {
|
||||
NULL_CHECKSUM = 15
|
||||
};
|
||||
|
||||
enum PduType : bool { FILE_DIRECTIVE = 0, FILE_DATA = 1 };
|
||||
enum PduType : uint8_t { FILE_DIRECTIVE = 0, FILE_DATA = 1 };
|
||||
|
||||
enum TransmissionModes : bool { ACKNOWLEDGED = 0, UNACKNOWLEDGED = 1 };
|
||||
enum TransmissionModes : uint8_t { ACKNOWLEDGED = 0, UNACKNOWLEDGED = 1 };
|
||||
|
||||
enum SegmentMetadataFlag : bool { NOT_PRESENT = 0, PRESENT = 1 };
|
||||
enum SegmentMetadataFlag : bool { NOT_PRESENT = false, PRESENT = true };
|
||||
|
||||
enum Direction : bool { TOWARDS_RECEIVER = 0, TOWARDS_SENDER = 1 };
|
||||
enum Direction : uint8_t { TOWARDS_RECEIVER = 0, TOWARDS_SENDER = 1 };
|
||||
|
||||
enum SegmentationControl : bool {
|
||||
NO_RECORD_BOUNDARIES_PRESERVATION = 0,
|
||||
RECORD_BOUNDARIES_PRESERVATION = 1
|
||||
NO_RECORD_BOUNDARIES_PRESERVATION = false,
|
||||
RECORD_BOUNDARIES_PRESERVATION = true
|
||||
};
|
||||
|
||||
enum WidthInBytes : uint8_t {
|
||||
@@ -97,6 +97,14 @@ enum ConditionCode : uint8_t {
|
||||
CANCEL_REQUEST_RECEIVED = 0b1111
|
||||
};
|
||||
|
||||
enum FaultHandlerCodes {
|
||||
RESERVED = 0b0000,
|
||||
NOTICE_OF_CANCELLATION = 0b0001,
|
||||
NOTICE_OF_SUSPENSION = 0b0010,
|
||||
IGNORE_ERROR = 0b0011,
|
||||
ABANDON_TRANSACTION = 0b0100
|
||||
};
|
||||
|
||||
enum AckTransactionStatus {
|
||||
UNDEFINED = 0b00,
|
||||
ACTIVE = 0b01,
|
||||
@@ -104,16 +112,16 @@ enum AckTransactionStatus {
|
||||
UNRECOGNIZED = 0b11
|
||||
};
|
||||
|
||||
enum FinishedDeliveryCode { DATA_COMPLETE = 0, DATA_INCOMPLETE = 1 };
|
||||
enum FileDeliveryCode { DATA_COMPLETE = 0, DATA_INCOMPLETE = 1 };
|
||||
|
||||
enum FinishedFileStatus {
|
||||
enum FileDeliveryStatus {
|
||||
DISCARDED_DELIBERATELY = 0,
|
||||
DISCARDED_FILESTORE_REJECTION = 1,
|
||||
RETAINED_IN_FILESTORE = 2,
|
||||
FILE_STATUS_UNREPORTED = 3
|
||||
};
|
||||
|
||||
enum PromptResponseRequired : bool { PROMPT_NAK = 0, PROMPT_KEEP_ALIVE = 1 };
|
||||
enum PromptResponseRequired : uint8_t { PROMPT_NAK = 0, PROMPT_KEEP_ALIVE = 1 };
|
||||
|
||||
enum TlvTypes : uint8_t {
|
||||
FILESTORE_REQUEST = 0x00,
|
||||
|
2
src/fsfw/cfdp/handler/CMakeLists.txt
Normal file
2
src/fsfw/cfdp/handler/CMakeLists.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE SourceHandler.cpp DestHandler.cpp
|
||||
FaultHandlerBase.cpp UserBase.cpp)
|
289
src/fsfw/cfdp/handler/DestHandler.cpp
Normal file
289
src/fsfw/cfdp/handler/DestHandler.cpp
Normal file
@@ -0,0 +1,289 @@
|
||||
#include "DestHandler.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "fsfw/FSFW.h"
|
||||
#include "fsfw/cfdp/pdu/EofPduReader.h"
|
||||
#include "fsfw/cfdp/pdu/FileDataReader.h"
|
||||
#include "fsfw/cfdp/pdu/HeaderReader.h"
|
||||
#include "fsfw/objectmanager.h"
|
||||
|
||||
using namespace returnvalue;
|
||||
|
||||
cfdp::DestHandler::DestHandler(DestHandlerParams params, FsfwParams fsfwParams)
|
||||
: tlvVec(params.maxTlvsInOnePdu),
|
||||
userTlvVec(params.maxTlvsInOnePdu),
|
||||
dp(std::move(params)),
|
||||
fp(fsfwParams),
|
||||
tp(params.maxFilenameLen) {
|
||||
tp.pduConf.direction = cfdp::Direction::TOWARDS_SENDER;
|
||||
}
|
||||
|
||||
ReturnValue_t cfdp::DestHandler::performStateMachine() {
|
||||
ReturnValue_t result;
|
||||
ReturnValue_t status = returnvalue::OK;
|
||||
if (step == TransactionStep::IDLE) {
|
||||
for (auto infoIter = dp.packetListRef.begin(); infoIter != dp.packetListRef.end();) {
|
||||
if (infoIter->pduType == PduType::FILE_DIRECTIVE and
|
||||
infoIter->directiveType == FileDirectives::METADATA) {
|
||||
result = handleMetadataPdu(*infoIter);
|
||||
if (result != OK) {
|
||||
status = result;
|
||||
}
|
||||
// Store data was deleted in PDU handler because a store guard is used
|
||||
dp.packetListRef.erase(infoIter++);
|
||||
}
|
||||
}
|
||||
if (step == TransactionStep::IDLE) {
|
||||
// To decrease the already high complexity of the software, all packets arriving before
|
||||
// a metadata PDU are deleted.
|
||||
for (auto infoIter = dp.packetListRef.begin(); infoIter != dp.packetListRef.end();) {
|
||||
fp.tcStore->deleteData(infoIter->storeId);
|
||||
}
|
||||
dp.packetListRef.clear();
|
||||
}
|
||||
|
||||
if (step != TransactionStep::IDLE) {
|
||||
return CALL_FSM_AGAIN;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
if (cfdpState == CfdpStates::BUSY_CLASS_1_NACKED) {
|
||||
if (step == TransactionStep::RECEIVING_FILE_DATA_PDUS) {
|
||||
for (auto infoIter = dp.packetListRef.begin(); infoIter != dp.packetListRef.end();) {
|
||||
if (infoIter->pduType == PduType::FILE_DATA) {
|
||||
result = handleFileDataPdu(*infoIter);
|
||||
if (result != OK) {
|
||||
status = result;
|
||||
}
|
||||
// Store data was deleted in PDU handler because a store guard is used
|
||||
dp.packetListRef.erase(infoIter++);
|
||||
}
|
||||
// TODO: Support for check timer missing
|
||||
if (infoIter->pduType == PduType::FILE_DIRECTIVE and
|
||||
infoIter->directiveType == FileDirectives::EOF_DIRECTIVE) {
|
||||
result = handleEofPdu(*infoIter);
|
||||
if (result != OK) {
|
||||
status = result;
|
||||
}
|
||||
// Store data was deleted in PDU handler because a store guard is used
|
||||
dp.packetListRef.erase(infoIter++);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (step == TransactionStep::TRANSFER_COMPLETION) {
|
||||
}
|
||||
if (step == TransactionStep::SENDING_FINISHED_PDU) {
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
if (cfdpState == CfdpStates::BUSY_CLASS_2_ACKED) {
|
||||
// TODO: Will be implemented at a later stage
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "CFDP state machine for acknowledged mode not implemented yet" << std::endl;
|
||||
#endif
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
ReturnValue_t cfdp::DestHandler::passPacket(PacketInfo packet) {
|
||||
if (dp.packetListRef.full()) {
|
||||
return FAILED;
|
||||
}
|
||||
dp.packetListRef.push_back(packet);
|
||||
return OK;
|
||||
}
|
||||
|
||||
ReturnValue_t cfdp::DestHandler::initialize() {
|
||||
if (fp.tmStore == nullptr) {
|
||||
fp.tmStore = ObjectManager::instance()->get<StorageManagerIF>(objects::TM_STORE);
|
||||
if (fp.tmStore == nullptr) {
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
if (fp.tcStore == nullptr) {
|
||||
fp.tcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::TC_STORE);
|
||||
if (fp.tcStore == nullptr) {
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
ReturnValue_t cfdp::DestHandler::handleMetadataPdu(const PacketInfo& info) {
|
||||
// Process metadata PDU
|
||||
auto constAccessorPair = fp.tcStore->getData(info.storeId);
|
||||
if (constAccessorPair.first != OK) {
|
||||
// TODO: This is not a CFDP error. Event and/or warning?
|
||||
return constAccessorPair.first;
|
||||
}
|
||||
cfdp::StringLv sourceFileName;
|
||||
cfdp::StringLv destFileName;
|
||||
MetadataInfo metadataInfo(tp.fileSize, sourceFileName, destFileName);
|
||||
cfdp::Tlv* tlvArrayAsPtr = tlvVec.data();
|
||||
metadataInfo.setOptionsArray(&tlvArrayAsPtr, std::nullopt, tlvVec.size());
|
||||
MetadataPduReader reader(constAccessorPair.second.data(), constAccessorPair.second.size(),
|
||||
metadataInfo);
|
||||
ReturnValue_t result = reader.parseData();
|
||||
// TODO: The standard does not really specify what happens if this kind of error happens
|
||||
// I think it might be a good idea to cache some sort of error code, which
|
||||
// is translated into a warning and/or event by an upper layer
|
||||
if (result != OK) {
|
||||
return handleMetadataParseError(constAccessorPair.second.data(),
|
||||
constAccessorPair.second.size());
|
||||
}
|
||||
return startTransaction(reader, metadataInfo);
|
||||
}
|
||||
|
||||
ReturnValue_t cfdp::DestHandler::handleFileDataPdu(const cfdp::PacketInfo& info) {
|
||||
// Process file data PDU
|
||||
auto constAccessorPair = fp.tcStore->getData(info.storeId);
|
||||
if (constAccessorPair.first != OK) {
|
||||
// TODO: This is not a CFDP error. Event and/or warning?
|
||||
return constAccessorPair.first;
|
||||
}
|
||||
cfdp::FileSize offset;
|
||||
FileDataInfo fdInfo(offset);
|
||||
FileDataReader reader(constAccessorPair.second.data(), constAccessorPair.second.size(), fdInfo);
|
||||
ReturnValue_t result = reader.parseData();
|
||||
if (result != OK) {
|
||||
return result;
|
||||
}
|
||||
size_t fileSegmentLen = 0;
|
||||
const uint8_t* fileData = fdInfo.getFileData(&fileSegmentLen);
|
||||
FileOpParams fileOpParams(tp.sourceName.data(), fileSegmentLen);
|
||||
if (dp.cfg.indicCfg.fileSegmentRecvIndicRequired) {
|
||||
FileSegmentRecvdParams segParams;
|
||||
segParams.offset = offset.value();
|
||||
segParams.id = tp.transactionId;
|
||||
segParams.length = fileSegmentLen;
|
||||
segParams.recContState = fdInfo.getRecordContinuationState();
|
||||
size_t segmentMetadatLen = 0;
|
||||
auto* segMetadata = fdInfo.getSegmentMetadata(&segmentMetadatLen);
|
||||
segParams.segmentMetadata = {segMetadata, segmentMetadatLen};
|
||||
dp.user.fileSegmentRecvdIndication(segParams);
|
||||
}
|
||||
result = dp.user.vfs.writeToFile(fileOpParams, fileData);
|
||||
if (offset.value() + fileSegmentLen > tp.progress) {
|
||||
tp.progress = offset.value() + fileSegmentLen;
|
||||
}
|
||||
if (result != returnvalue::OK) {
|
||||
// TODO: Proper Error handling
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "File write error" << std::endl;
|
||||
#endif
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t cfdp::DestHandler::handleEofPdu(const cfdp::PacketInfo& info) {
|
||||
// Process EOF PDU
|
||||
auto constAccessorPair = fp.tcStore->getData(info.storeId);
|
||||
if (constAccessorPair.first != OK) {
|
||||
// TODO: This is not a CFDP error. Event and/or warning?
|
||||
return constAccessorPair.first;
|
||||
}
|
||||
EofInfo eofInfo(nullptr);
|
||||
EofPduReader reader(constAccessorPair.second.data(), constAccessorPair.second.size(), eofInfo);
|
||||
ReturnValue_t result = reader.parseData();
|
||||
if (result != OK) {
|
||||
return result;
|
||||
}
|
||||
// TODO: Error handling
|
||||
if (eofInfo.getConditionCode() == ConditionCode::NO_ERROR) {
|
||||
tp.crc = eofInfo.getChecksum();
|
||||
uint64_t fileSizeFromEof = eofInfo.getFileSize().value();
|
||||
// CFDP 4.6.1.2.9: Declare file size error if progress exceeds file size
|
||||
if (fileSizeFromEof > tp.progress) {
|
||||
// TODO: File size error
|
||||
}
|
||||
tp.fileSize.setFileSize(fileSizeFromEof, std::nullopt);
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t cfdp::DestHandler::handleMetadataParseError(const uint8_t* rawData, size_t maxSize) {
|
||||
// TODO: try to extract destination ID for error
|
||||
// TODO: Invalid metadata PDU.
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "Parsing Metadata PDU failed with code " << result << std::endl;
|
||||
#else
|
||||
#endif
|
||||
HeaderReader headerReader(rawData, maxSize);
|
||||
ReturnValue_t result = headerReader.parseData();
|
||||
if (result != OK) {
|
||||
// TODO: Now this really should not happen. Warning or error,
|
||||
// yield or cache appropriate returnvalue
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "Parsing Header failed" << std::endl;
|
||||
#else
|
||||
#endif
|
||||
// TODO: Trigger appropriate event
|
||||
return result;
|
||||
}
|
||||
cfdp::EntityId destId;
|
||||
headerReader.getDestId(destId);
|
||||
RemoteEntityCfg* remoteCfg;
|
||||
if (not dp.remoteCfgTable.getRemoteCfg(destId, &remoteCfg)) {
|
||||
// TODO: No remote config for dest ID. I consider this a configuration error.
|
||||
// Warning or error, yield or cache appropriate returnvalue
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "No remote config exists for destination ID" << std::endl;
|
||||
#else
|
||||
#endif
|
||||
// TODO: Trigger appropriate event
|
||||
}
|
||||
// TODO: Appropriate returnvalue?
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
||||
ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, MetadataInfo& info) {
|
||||
if (cfdpState != CfdpStates::IDLE) {
|
||||
// According to standard, discard metadata PDU if we are busy
|
||||
return returnvalue::OK;
|
||||
}
|
||||
step = TransactionStep::TRANSACTION_START;
|
||||
if (reader.getTransmissionMode() == TransmissionModes::UNACKNOWLEDGED) {
|
||||
cfdpState = CfdpStates::BUSY_CLASS_1_NACKED;
|
||||
} else if (reader.getTransmissionMode() == TransmissionModes::ACKNOWLEDGED) {
|
||||
cfdpState = CfdpStates::BUSY_CLASS_2_ACKED;
|
||||
}
|
||||
tp.checksumType = info.getChecksumType();
|
||||
tp.closureRequested = info.isClosureRequested();
|
||||
size_t sourceNameSize = 0;
|
||||
const uint8_t* sourceNamePtr = info.getSourceFileName().getValue(&sourceNameSize);
|
||||
if (sourceNameSize > tp.sourceName.size()) {
|
||||
// TODO: Warning, event etc.
|
||||
return FAILED;
|
||||
}
|
||||
std::memcpy(tp.sourceName.data(), sourceNamePtr, sourceNameSize);
|
||||
tp.sourceName[sourceNameSize] = '\0';
|
||||
size_t destNameSize = 0;
|
||||
const uint8_t* destNamePtr = info.getDestFileName().getValue(&destNameSize);
|
||||
if (destNameSize > tp.destName.size()) {
|
||||
// TODO: Warning, event etc.
|
||||
return FAILED;
|
||||
}
|
||||
std::memcpy(tp.destName.data(), destNamePtr, destNameSize);
|
||||
tp.destName[destNameSize] = '\0';
|
||||
reader.fillConfig(tp.pduConf);
|
||||
tp.pduConf.direction = Direction::TOWARDS_SENDER;
|
||||
tp.transactionId.entityId = tp.pduConf.sourceId;
|
||||
tp.transactionId.seqNum = tp.pduConf.seqNum;
|
||||
if (not dp.remoteCfgTable.getRemoteCfg(tp.pduConf.destId, &tp.remoteCfg)) {
|
||||
// TODO: Warning, event etc.
|
||||
return FAILED;
|
||||
}
|
||||
step = TransactionStep::RECEIVING_FILE_DATA_PDUS;
|
||||
MetadataRecvdParams params(tp.transactionId, tp.pduConf.sourceId);
|
||||
params.fileSize = tp.fileSize.getSize();
|
||||
params.destFileName = tp.destName.data();
|
||||
params.sourceFileName = tp.sourceName.data();
|
||||
params.msgsToUserArray = dynamic_cast<MessageToUserTlv*>(userTlvVec.data());
|
||||
params.msgsToUserLen = info.getOptionsLen();
|
||||
dp.user.metadataRecvdIndication(params);
|
||||
return OK;
|
||||
}
|
||||
|
||||
cfdp::CfdpStates cfdp::DestHandler::getCfdpState() const { return cfdpState; }
|
130
src/fsfw/cfdp/handler/DestHandler.h
Normal file
130
src/fsfw/cfdp/handler/DestHandler.h
Normal file
@@ -0,0 +1,130 @@
|
||||
#ifndef FSFW_CFDP_CFDPDESTHANDLER_H
|
||||
#define FSFW_CFDP_CFDPDESTHANDLER_H
|
||||
|
||||
#include <etl/list.h>
|
||||
#include <etl/set.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "RemoteConfigTableIF.h"
|
||||
#include "UserBase.h"
|
||||
#include "defs.h"
|
||||
#include "fsfw/cfdp/handler/mib.h"
|
||||
#include "fsfw/cfdp/pdu/MetadataPduReader.h"
|
||||
#include "fsfw/cfdp/pdu/PduConfig.h"
|
||||
#include "fsfw/container/DynamicFIFO.h"
|
||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||
#include "fsfw/storagemanager/storeAddress.h"
|
||||
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
struct PacketInfo {
|
||||
PacketInfo(PduType type, FileDirectives directive, store_address_t storeId)
|
||||
: pduType(type), directiveType(directive), storeId(storeId) {}
|
||||
|
||||
PduType pduType = PduType::FILE_DATA;
|
||||
FileDirectives directiveType = FileDirectives::INVALID_DIRECTIVE;
|
||||
store_address_t storeId = store_address_t::invalid();
|
||||
PacketInfo() = default;
|
||||
};
|
||||
|
||||
struct DestHandlerParams {
|
||||
DestHandlerParams(LocalEntityCfg cfg, UserBase& user, RemoteConfigTableIF& remoteCfgTable,
|
||||
etl::ilist<PacketInfo>& packetList,
|
||||
// TODO: This container can potentially take tons of space. For a better
|
||||
// memory efficient implementation, an additional abstraction could be
|
||||
// be used so users can use uint32_t as the pair type
|
||||
etl::iset<etl::pair<uint64_t, uint64_t>>& lostSegmentsContainer)
|
||||
: cfg(std::move(cfg)),
|
||||
user(user),
|
||||
remoteCfgTable(remoteCfgTable),
|
||||
packetListRef(packetList),
|
||||
lostSegmentsContainer(lostSegmentsContainer) {}
|
||||
|
||||
LocalEntityCfg cfg;
|
||||
UserBase& user;
|
||||
RemoteConfigTableIF& remoteCfgTable;
|
||||
|
||||
etl::ilist<PacketInfo>& packetListRef;
|
||||
etl::iset<etl::pair<uint64_t, uint64_t>>& lostSegmentsContainer;
|
||||
uint8_t maxTlvsInOnePdu = 10;
|
||||
size_t maxFilenameLen = 255;
|
||||
};
|
||||
|
||||
struct FsfwParams {
|
||||
FsfwParams(AcceptsTelemetryIF& packetDest, MessageQueueIF& msgQueue,
|
||||
EventReportingProxyIF& eventReporter)
|
||||
: packetDest(packetDest), msgQueue(msgQueue), eventReporter(eventReporter) {}
|
||||
AcceptsTelemetryIF& packetDest;
|
||||
MessageQueueIF& msgQueue;
|
||||
EventReportingProxyIF& eventReporter;
|
||||
StorageManagerIF* tcStore = nullptr;
|
||||
StorageManagerIF* tmStore = nullptr;
|
||||
};
|
||||
|
||||
class DestHandler {
|
||||
public:
|
||||
/**
|
||||
* Will be returned if it is advisable to call the state machine operation call again
|
||||
*/
|
||||
ReturnValue_t CALL_FSM_AGAIN = returnvalue::makeCode(1, 0);
|
||||
explicit DestHandler(DestHandlerParams handlerParams, FsfwParams fsfwParams);
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
* - @c returnvalue::OK State machine OK for this execution cycle
|
||||
* - @c CALL_FSM_AGAIN State machine should be called again.
|
||||
*/
|
||||
ReturnValue_t performStateMachine();
|
||||
|
||||
ReturnValue_t passPacket(PacketInfo packet);
|
||||
|
||||
ReturnValue_t initialize();
|
||||
|
||||
[[nodiscard]] CfdpStates getCfdpState() const;
|
||||
|
||||
private:
|
||||
enum class TransactionStep {
|
||||
IDLE = 0,
|
||||
TRANSACTION_START = 1,
|
||||
RECEIVING_FILE_DATA_PDUS = 2,
|
||||
SENDING_ACK_PDU = 3,
|
||||
TRANSFER_COMPLETION = 4,
|
||||
SENDING_FINISHED_PDU = 5
|
||||
};
|
||||
struct TransactionParams {
|
||||
explicit TransactionParams(size_t maxFileNameLen)
|
||||
: sourceName(maxFileNameLen), destName(maxFileNameLen) {}
|
||||
|
||||
ChecksumType checksumType = ChecksumType::NULL_CHECKSUM;
|
||||
bool closureRequested = false;
|
||||
std::vector<char> sourceName;
|
||||
std::vector<char> destName;
|
||||
cfdp::FileSize fileSize;
|
||||
TransactionId transactionId;
|
||||
PduConfig pduConf;
|
||||
uint32_t crc = 0;
|
||||
uint64_t progress = 0;
|
||||
RemoteEntityCfg* remoteCfg = nullptr;
|
||||
};
|
||||
|
||||
TransactionStep step = TransactionStep::IDLE;
|
||||
CfdpStates cfdpState = CfdpStates::IDLE;
|
||||
std::vector<cfdp::Tlv> tlvVec;
|
||||
std::vector<cfdp::Tlv> userTlvVec;
|
||||
DestHandlerParams dp;
|
||||
FsfwParams fp;
|
||||
TransactionParams tp;
|
||||
|
||||
ReturnValue_t startTransaction(MetadataPduReader& reader, MetadataInfo& info);
|
||||
ReturnValue_t handleMetadataPdu(const PacketInfo& info);
|
||||
ReturnValue_t handleFileDataPdu(const PacketInfo& info);
|
||||
ReturnValue_t handleEofPdu(const PacketInfo& info);
|
||||
ReturnValue_t handleMetadataParseError(const uint8_t* rawData, size_t maxSize);
|
||||
};
|
||||
|
||||
} // namespace cfdp
|
||||
|
||||
#endif // FSFW_CFDP_CFDPDESTHANDLER_H
|
51
src/fsfw/cfdp/handler/FaultHandlerBase.cpp
Normal file
51
src/fsfw/cfdp/handler/FaultHandlerBase.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "FaultHandlerBase.h"
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
FaultHandlerBase::FaultHandlerBase() = default;
|
||||
FaultHandlerBase::~FaultHandlerBase() = default;
|
||||
|
||||
bool FaultHandlerBase::getFaultHandler(cfdp::ConditionCode code,
|
||||
cfdp::FaultHandlerCodes& handler) const {
|
||||
auto iter = faultHandlerMap.find(code);
|
||||
if (iter == faultHandlerMap.end()) {
|
||||
return false;
|
||||
}
|
||||
handler = iter->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FaultHandlerBase::setFaultHandler(cfdp::ConditionCode code, cfdp::FaultHandlerCodes handler) {
|
||||
if (not faultHandlerMap.contains(code)) {
|
||||
return false;
|
||||
}
|
||||
if (handler != FaultHandlerCodes::NOTICE_OF_SUSPENSION and
|
||||
handler != FaultHandlerCodes::ABANDON_TRANSACTION and
|
||||
handler != FaultHandlerCodes::NOTICE_OF_CANCELLATION and
|
||||
handler != FaultHandlerCodes::IGNORE_ERROR) {
|
||||
return false;
|
||||
}
|
||||
faultHandlerMap[code] = handler;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FaultHandlerBase::reportFault(cfdp::ConditionCode code) {
|
||||
if (not faultHandlerMap.contains(code)) {
|
||||
return false;
|
||||
}
|
||||
cfdp::FaultHandlerCodes fh = faultHandlerMap[code];
|
||||
if (fh == cfdp::FaultHandlerCodes::IGNORE_ERROR) {
|
||||
ignoreCb(code);
|
||||
} else if (fh == cfdp::FaultHandlerCodes::ABANDON_TRANSACTION) {
|
||||
abandonCb(code);
|
||||
} else if (fh == cfdp::FaultHandlerCodes::NOTICE_OF_CANCELLATION) {
|
||||
noticeOfCancellationCb(code);
|
||||
} else if (fh == cfdp::FaultHandlerCodes::NOTICE_OF_SUSPENSION) {
|
||||
noticeOfSuspensionCb(code);
|
||||
} else {
|
||||
// Should never happen, but use defensive programming
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace cfdp
|
76
src/fsfw/cfdp/handler/FaultHandlerBase.h
Normal file
76
src/fsfw/cfdp/handler/FaultHandlerBase.h
Normal file
@@ -0,0 +1,76 @@
|
||||
#ifndef FSFW_CFDP_FAULTHANDLERBASE_H
|
||||
#define FSFW_CFDP_FAULTHANDLERBASE_H
|
||||
|
||||
#include <etl/flat_map.h>
|
||||
|
||||
#include "fsfw/cfdp/definitions.h"
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
/**
|
||||
* @brief Provides a way to implement the fault handling procedures as specified
|
||||
* in chapter 4.8 of the CFDP standard.
|
||||
*
|
||||
* @details
|
||||
* It is passed into the CFDP handlers as part of the local entity configuration and provides
|
||||
* a way to specify custom user error handlers.
|
||||
*
|
||||
* It does so by mapping each applicable CFDP condition code to a fault handler which
|
||||
* is denoted by the four @cfdp::FaultHandlerCodes. This code is used to dispatch
|
||||
* to a user-provided callback function:
|
||||
*
|
||||
* 1. @FaultHandlerCodes::IGNORE_ERROR -> @ignore_cb
|
||||
* 2. @FaultHandlerCodes::NOTICE_OF_CANCELLATION` -> @notice_of_cancellation_cb
|
||||
* 3. @FaultHandlerCodes::NOTICE_OF_SUSPENSION` -> @notice_of_suspension_cb
|
||||
* 4. @FaultHandlerCodes::ABANDON_TRANSACTION` -> @abandon_transaction_cb
|
||||
*
|
||||
* For each error reported by @reportError, the appropriate fault handler callback
|
||||
* will be called. The user provides the callbacks by providing a custom class which implements
|
||||
* these base class and all abstract fault handler callbacks.
|
||||
*/
|
||||
class FaultHandlerBase {
|
||||
public:
|
||||
virtual ~FaultHandlerBase();
|
||||
FaultHandlerBase();
|
||||
|
||||
/**
|
||||
* Get the fault handler code for the given condition code
|
||||
* @param code
|
||||
* @param handler [out] Will be set to the approrpiate handler for the condition code if
|
||||
* it is valid
|
||||
* @return
|
||||
* - true if the condition code is valid
|
||||
* - false otherwise
|
||||
*/
|
||||
bool getFaultHandler(cfdp::ConditionCode code, cfdp::FaultHandlerCodes& handler) const;
|
||||
|
||||
bool setFaultHandler(cfdp::ConditionCode code, cfdp::FaultHandlerCodes handler);
|
||||
|
||||
bool reportFault(cfdp::ConditionCode code);
|
||||
|
||||
virtual void noticeOfSuspensionCb(cfdp::ConditionCode code) = 0;
|
||||
virtual void noticeOfCancellationCb(cfdp::ConditionCode code) = 0;
|
||||
virtual void abandonCb(cfdp::ConditionCode code) = 0;
|
||||
virtual void ignoreCb(cfdp::ConditionCode code) = 0;
|
||||
|
||||
private:
|
||||
etl::flat_map<cfdp::ConditionCode, cfdp::FaultHandlerCodes, 10> faultHandlerMap = {
|
||||
etl::pair{cfdp::ConditionCode::POSITIVE_ACK_LIMIT_REACHED,
|
||||
cfdp::FaultHandlerCodes::IGNORE_ERROR},
|
||||
etl::pair{cfdp::ConditionCode::KEEP_ALIVE_LIMIT_REACHED,
|
||||
cfdp::FaultHandlerCodes::IGNORE_ERROR},
|
||||
etl::pair{cfdp::ConditionCode::INVALID_TRANSMISSION_MODE,
|
||||
cfdp::FaultHandlerCodes::IGNORE_ERROR},
|
||||
etl::pair{cfdp::ConditionCode::FILE_CHECKSUM_FAILURE, cfdp::FaultHandlerCodes::IGNORE_ERROR},
|
||||
etl::pair{cfdp::ConditionCode::FILE_SIZE_ERROR, cfdp::FaultHandlerCodes::IGNORE_ERROR},
|
||||
etl::pair{cfdp::ConditionCode::NAK_LIMIT_REACHED, cfdp::FaultHandlerCodes::IGNORE_ERROR},
|
||||
etl::pair{cfdp::ConditionCode::INACTIVITY_DETECTED, cfdp::FaultHandlerCodes::IGNORE_ERROR},
|
||||
etl::pair{cfdp::ConditionCode::UNSUPPORTED_CHECKSUM_TYPE,
|
||||
cfdp::FaultHandlerCodes::IGNORE_ERROR},
|
||||
etl::pair{cfdp::ConditionCode::FILESTORE_REJECTION, cfdp::FaultHandlerCodes::IGNORE_ERROR},
|
||||
etl::pair{cfdp::ConditionCode::CHECK_LIMIT_REACHED, cfdp::FaultHandlerCodes::IGNORE_ERROR}};
|
||||
};
|
||||
|
||||
} // namespace cfdp
|
||||
|
||||
#endif // FSFW_CFDP_FAULTHANDLERBASE_H
|
16
src/fsfw/cfdp/handler/RemoteConfigTableIF.h
Normal file
16
src/fsfw/cfdp/handler/RemoteConfigTableIF.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef FSFW_CFDP_HANDLER_REMOTECONFIGTABLEIF_H
|
||||
#define FSFW_CFDP_HANDLER_REMOTECONFIGTABLEIF_H
|
||||
|
||||
#include "fsfw/cfdp/handler/mib.h"
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
class RemoteConfigTableIF {
|
||||
public:
|
||||
virtual ~RemoteConfigTableIF() = default;
|
||||
virtual bool getRemoteCfg(const cfdp::EntityId& remoteId, cfdp::RemoteEntityCfg** cfg) = 0;
|
||||
};
|
||||
|
||||
} // namespace cfdp
|
||||
|
||||
#endif // FSFW_CFDP_HANDLER_REMOTECONFIGTABLEIF_H
|
1
src/fsfw/cfdp/handler/SourceHandler.cpp
Normal file
1
src/fsfw/cfdp/handler/SourceHandler.cpp
Normal file
@@ -0,0 +1 @@
|
||||
#include "SourceHandler.h"
|
6
src/fsfw/cfdp/handler/SourceHandler.h
Normal file
6
src/fsfw/cfdp/handler/SourceHandler.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef FSFW_CFDP_CFDPSOURCEHANDLER_H
|
||||
#define FSFW_CFDP_CFDPSOURCEHANDLER_H
|
||||
|
||||
class SourceHandler {};
|
||||
|
||||
#endif // FSFW_CFDP_CFDPSOURCEHANDLER_H
|
12
src/fsfw/cfdp/handler/StatusReportIF.h
Normal file
12
src/fsfw/cfdp/handler/StatusReportIF.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef FSFW_CFDP_HANDLER_STATUSREPORTIF_H
|
||||
#define FSFW_CFDP_HANDLER_STATUSREPORTIF_H
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
class StatusReportIF {
|
||||
virtual ~StatusReportIF() = default;
|
||||
};
|
||||
|
||||
} // namespace cfdp
|
||||
|
||||
#endif // FSFW_CFDP_HANDLER_STATUSREPORTIF_H
|
3
src/fsfw/cfdp/handler/UserBase.cpp
Normal file
3
src/fsfw/cfdp/handler/UserBase.cpp
Normal file
@@ -0,0 +1,3 @@
|
||||
#include "UserBase.h"
|
||||
|
||||
cfdp::UserBase::UserBase(HasFileSystemIF& vfs) : vfs(vfs) {}
|
101
src/fsfw/cfdp/handler/UserBase.h
Normal file
101
src/fsfw/cfdp/handler/UserBase.h
Normal file
@@ -0,0 +1,101 @@
|
||||
#ifndef FSFW_CFDP_USERBASE_H
|
||||
#define FSFW_CFDP_USERBASE_H
|
||||
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "StatusReportIF.h"
|
||||
#include "fsfw/cfdp/VarLenFields.h"
|
||||
#include "fsfw/cfdp/tlv/FilestoreResponseTlv.h"
|
||||
#include "fsfw/cfdp/tlv/MessageToUserTlv.h"
|
||||
#include "fsfw/filesystem/HasFileSystemIF.h"
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
struct TransactionFinishedParams {
|
||||
TransactionFinishedParams(TransactionId id, ConditionCode code, FileDeliveryStatus status,
|
||||
FileDeliveryCode delivCode)
|
||||
: id(std::move(id)), condCode(code), status(status), deliveryCode(delivCode) {}
|
||||
|
||||
TransactionId id;
|
||||
ConditionCode condCode;
|
||||
FileDeliveryStatus status;
|
||||
FileDeliveryCode deliveryCode;
|
||||
std::vector<FilestoreResponseTlv*> fsResponses;
|
||||
StatusReportIF* statusReport = nullptr;
|
||||
};
|
||||
|
||||
struct MetadataRecvdParams {
|
||||
MetadataRecvdParams(const TransactionId& id, const EntityId& sourceId)
|
||||
: id(id), sourceId(sourceId) {}
|
||||
const TransactionId& id;
|
||||
const EntityId& sourceId;
|
||||
uint64_t fileSize = 0;
|
||||
const char* sourceFileName = "";
|
||||
const char* destFileName = "";
|
||||
size_t msgsToUserLen = 0;
|
||||
const MessageToUserTlv* msgsToUserArray = nullptr;
|
||||
};
|
||||
|
||||
struct FileSegmentRecvdParams {
|
||||
TransactionId id;
|
||||
size_t offset;
|
||||
size_t length;
|
||||
std::optional<RecordContinuationState> recContState = std::nullopt;
|
||||
std::pair<const uint8_t*, size_t> segmentMetadata;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Base class which provides a user interface to interact with CFDP handlers.
|
||||
*
|
||||
* @details
|
||||
* This class is also used to pass the Virtual Filestore (VFS) Implementation to the CFDP
|
||||
* handlers so the filestore operations can be mapped to the underlying filestore.
|
||||
*
|
||||
* It is used by implementing it in a child class and then passing it to the CFDP
|
||||
* handler objects. The base class provides default implementation for the user indication
|
||||
* primitives specified in the CFDP standard. The user can override these implementations
|
||||
* to provide custom indication handlers.
|
||||
*
|
||||
* Please note that for all indication callbacks, the passed transaction ID reference will
|
||||
* become invalid shortly after the function has been executed. If the transaction ID is to be
|
||||
* cached or used, create an own copy of it.
|
||||
* @param vfs Virtual Filestore Object. Will be used for all file operations
|
||||
*/
|
||||
class UserBase {
|
||||
friend class DestHandler;
|
||||
|
||||
public:
|
||||
explicit UserBase(HasFileSystemIF& vfs);
|
||||
|
||||
virtual void transactionIndication(const TransactionId& id) = 0;
|
||||
virtual void eofSentIndication(const TransactionId& id) = 0;
|
||||
virtual void transactionFinishedIndication(const TransactionFinishedParams& params) = 0;
|
||||
/**
|
||||
* Will be called if metadata was received.
|
||||
*
|
||||
* IMPORTANT: The passed struct contains the messages to the user in form of a raw C array.
|
||||
* The TLVs in these arrays are zero-copy types, which means that they point to the raw data
|
||||
* inside the metadata packet directly. The metadata packet will be deleted from the TC store
|
||||
* shortly after it was processed. If some of the data is to be cached and/or used after the
|
||||
* function call, it needs to be copied into another user-provided buffer.
|
||||
* @param params
|
||||
*/
|
||||
virtual void metadataRecvdIndication(const MetadataRecvdParams& params) = 0;
|
||||
virtual void fileSegmentRecvdIndication(const FileSegmentRecvdParams& params) = 0;
|
||||
virtual void reportIndication(const TransactionId& id, StatusReportIF& report) = 0;
|
||||
virtual void suspendedIndication(const TransactionId& id, ConditionCode code) = 0;
|
||||
virtual void resumedIndication(const TransactionId& id, size_t progress) = 0;
|
||||
virtual void faultIndication(const TransactionId& id, ConditionCode code, size_t progress) = 0;
|
||||
virtual void abandonedIndication(const TransactionId& id, ConditionCode code,
|
||||
size_t progress) = 0;
|
||||
virtual void eofRecvIndication(const TransactionId& id) = 0;
|
||||
|
||||
private:
|
||||
HasFileSystemIF& vfs;
|
||||
};
|
||||
|
||||
} // namespace cfdp
|
||||
|
||||
#endif // FSFW_CFDP_USERBASE_H
|
9
src/fsfw/cfdp/handler/defs.h
Normal file
9
src/fsfw/cfdp/handler/defs.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef FSFW_CFDP_HANDLER_DEFS_H
|
||||
#define FSFW_CFDP_HANDLER_DEFS_H
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
enum class CfdpStates { IDLE, BUSY_CLASS_1_NACKED, BUSY_CLASS_2_ACKED, SUSPENDED };
|
||||
|
||||
}
|
||||
#endif // FSFW_CFDP_HANDLER_DEFS_H
|
41
src/fsfw/cfdp/handler/mib.h
Normal file
41
src/fsfw/cfdp/handler/mib.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef FSFW_CFDP_MIB_H
|
||||
#define FSFW_CFDP_MIB_H
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "FaultHandlerBase.h"
|
||||
#include "fsfw/cfdp/pdu/PduConfig.h"
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
struct IndicationCfg {
|
||||
bool eofSentIndicRequired = true;
|
||||
bool eofRecvIndicRequired = true;
|
||||
bool fileSegmentRecvIndicRequired = true;
|
||||
bool transactionFinishedIndicRequired = true;
|
||||
bool suspendedIndicRequired = true;
|
||||
bool resumedIndicRequired = true;
|
||||
};
|
||||
|
||||
struct LocalEntityCfg {
|
||||
LocalEntityCfg(EntityId localId, IndicationCfg indicationCfg, FaultHandlerBase& fhBase)
|
||||
: localId(std::move(localId)), indicCfg(indicationCfg), fhBase(fhBase) {}
|
||||
|
||||
EntityId localId;
|
||||
IndicationCfg indicCfg;
|
||||
FaultHandlerBase& fhBase;
|
||||
};
|
||||
|
||||
struct RemoteEntityCfg {
|
||||
EntityId remoteId;
|
||||
size_t maxFileSegmentLen = 2048;
|
||||
bool closureRequested = false;
|
||||
bool crcOnTransmission = false;
|
||||
TransmissionModes defaultTransmissionMode = TransmissionModes::UNACKNOWLEDGED;
|
||||
ChecksumType defaultChecksum = ChecksumType::NULL_CHECKSUM;
|
||||
const uint8_t version = CFDP_VERSION_2;
|
||||
};
|
||||
|
||||
} // namespace cfdp
|
||||
|
||||
#endif // FSFW_CFDP_MIB_H
|
@@ -1,21 +1,21 @@
|
||||
#include "AckPduDeserializer.h"
|
||||
|
||||
AckPduDeserializer::AckPduDeserializer(const uint8_t* pduBuf, size_t maxSize, AckInfo& info)
|
||||
: FileDirectiveDeserializer(pduBuf, maxSize), info(info) {}
|
||||
: FileDirectiveReader(pduBuf, maxSize), info(info) {}
|
||||
|
||||
ReturnValue_t AckPduDeserializer::parseData() {
|
||||
ReturnValue_t result = FileDirectiveDeserializer::parseData();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
ReturnValue_t result = FileDirectiveReader::parseData();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
size_t currentIdx = FileDirectiveDeserializer::getHeaderSize();
|
||||
size_t currentIdx = FileDirectiveReader::getHeaderSize();
|
||||
if (currentIdx + 2 > this->maxSize) {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
if (not checkAndSetCodes(rawPtr[currentIdx], rawPtr[currentIdx + 1])) {
|
||||
if (not checkAndSetCodes(pointers.rawPtr[currentIdx], pointers.rawPtr[currentIdx + 1])) {
|
||||
return cfdp::INVALID_ACK_DIRECTIVE_FIELDS;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
bool AckPduDeserializer::checkAndSetCodes(uint8_t firstByte, uint8_t secondByte) {
|
||||
|
@@ -2,9 +2,9 @@
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_ACKPDUDESERIALIZER_H_
|
||||
|
||||
#include "AckInfo.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveDeserializer.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveReader.h"
|
||||
|
||||
class AckPduDeserializer : public FileDirectiveDeserializer {
|
||||
class AckPduDeserializer : public FileDirectiveReader {
|
||||
public:
|
||||
AckPduDeserializer(const uint8_t* pduBuf, size_t maxSize, AckInfo& info);
|
||||
|
||||
|
@@ -1,17 +1,16 @@
|
||||
#include "AckPduSerializer.h"
|
||||
|
||||
AckPduSerializer::AckPduSerializer(AckInfo &ackInfo, PduConfig &pduConf)
|
||||
: FileDirectiveSerializer(pduConf, cfdp::FileDirectives::ACK, 2), ackInfo(ackInfo) {}
|
||||
: FileDirectiveCreator(pduConf, cfdp::FileDirectives::ACK, 2), ackInfo(ackInfo) {}
|
||||
|
||||
size_t AckPduSerializer::getSerializedSize() const {
|
||||
return FileDirectiveSerializer::getWholePduSize();
|
||||
return FileDirectiveCreator::getWholePduSize();
|
||||
}
|
||||
|
||||
ReturnValue_t AckPduSerializer::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result =
|
||||
FileDirectiveSerializer::serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
ReturnValue_t result = FileDirectiveCreator::serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
cfdp::FileDirectives ackedDirective = ackInfo.getAckedDirective();
|
||||
@@ -21,7 +20,7 @@ ReturnValue_t AckPduSerializer::serialize(uint8_t **buffer, size_t *size, size_t
|
||||
if (ackedDirective != cfdp::FileDirectives::FINISH and
|
||||
ackedDirective != cfdp::FileDirectives::EOF_DIRECTIVE) {
|
||||
// TODO: better returncode
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
if (*size + 2 > maxSize) {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
@@ -32,5 +31,5 @@ ReturnValue_t AckPduSerializer::serialize(uint8_t **buffer, size_t *size, size_t
|
||||
**buffer = ackedConditionCode << 4 | transactionStatus;
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
@@ -2,10 +2,10 @@
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_ACKPDUSERIALIZER_H_
|
||||
|
||||
#include "AckInfo.h"
|
||||
#include "FileDirectiveDeserializer.h"
|
||||
#include "FileDirectiveSerializer.h"
|
||||
#include "FileDirectiveCreator.h"
|
||||
#include "FileDirectiveReader.h"
|
||||
|
||||
class AckPduSerializer : public FileDirectiveSerializer {
|
||||
class AckPduSerializer : public FileDirectiveCreator {
|
||||
public:
|
||||
/**
|
||||
* @brief Serializer to pack ACK PDUs
|
||||
|
@@ -1,17 +1,16 @@
|
||||
target_sources(
|
||||
${LIB_FSFW_NAME}
|
||||
PRIVATE PduConfig.cpp
|
||||
VarLenField.cpp
|
||||
HeaderSerializer.cpp
|
||||
HeaderDeserializer.cpp
|
||||
FileDirectiveDeserializer.cpp
|
||||
FileDirectiveSerializer.cpp
|
||||
HeaderCreator.cpp
|
||||
HeaderReader.cpp
|
||||
FileDirectiveReader.cpp
|
||||
FileDirectiveCreator.cpp
|
||||
AckInfo.cpp
|
||||
AckPduSerializer.cpp
|
||||
AckPduDeserializer.cpp
|
||||
EofInfo.cpp
|
||||
EofPduSerializer.cpp
|
||||
EofPduDeserializer.cpp
|
||||
EofPduCreator.cpp
|
||||
EofPduReader.cpp
|
||||
NakInfo.cpp
|
||||
NakPduSerializer.cpp
|
||||
NakPduDeserializer.cpp
|
||||
@@ -19,12 +18,12 @@ target_sources(
|
||||
FinishedPduSerializer.cpp
|
||||
FinishedPduDeserializer.cpp
|
||||
MetadataInfo.cpp
|
||||
MetadataPduSerializer.cpp
|
||||
MetadataPduDeserializer.cpp
|
||||
MetadataPduCreator.cpp
|
||||
MetadataPduReader.cpp
|
||||
KeepAlivePduSerializer.cpp
|
||||
KeepAlivePduDeserializer.cpp
|
||||
PromptPduSerializer.cpp
|
||||
PromptPduDeserializer.cpp
|
||||
FileDataSerializer.cpp
|
||||
FileDataDeserializer.cpp
|
||||
FileDataCreator.cpp
|
||||
FileDataReader.cpp
|
||||
FileDataInfo.cpp)
|
||||
|
@@ -7,16 +7,16 @@
|
||||
|
||||
struct EofInfo {
|
||||
public:
|
||||
EofInfo(EntityIdTlv* faultLoc = nullptr);
|
||||
explicit EofInfo(EntityIdTlv* faultLoc = nullptr);
|
||||
EofInfo(cfdp::ConditionCode conditionCode, uint32_t checksum, cfdp::FileSize fileSize,
|
||||
EntityIdTlv* faultLoc = nullptr);
|
||||
|
||||
size_t getSerializedSize(bool fssLarge = false);
|
||||
|
||||
uint32_t getChecksum() const;
|
||||
cfdp::ConditionCode getConditionCode() const;
|
||||
[[nodiscard]] uint32_t getChecksum() const;
|
||||
[[nodiscard]] cfdp::ConditionCode getConditionCode() const;
|
||||
|
||||
EntityIdTlv* getFaultLoc() const;
|
||||
[[nodiscard]] EntityIdTlv* getFaultLoc() const;
|
||||
cfdp::FileSize& getFileSize();
|
||||
void setChecksum(uint32_t checksum);
|
||||
void setConditionCode(cfdp::ConditionCode conditionCode);
|
||||
|
@@ -1,22 +1,18 @@
|
||||
#include "EofPduSerializer.h"
|
||||
#include "EofPduCreator.h"
|
||||
|
||||
#include "fsfw/FSFW.h"
|
||||
#include "fsfw/serviceinterface.h"
|
||||
|
||||
EofPduSerializer::EofPduSerializer(PduConfig &conf, EofInfo &info)
|
||||
: FileDirectiveSerializer(conf, cfdp::FileDirectives::EOF_DIRECTIVE, 9), info(info) {
|
||||
setDirectiveDataFieldLen(info.getSerializedSize(getLargeFileFlag()));
|
||||
EofPduCreator::EofPduCreator(PduConfig &conf, EofInfo &info)
|
||||
: FileDirectiveCreator(conf, cfdp::FileDirectives::EOF_DIRECTIVE, 9), info(info) {
|
||||
setDirectiveDataFieldLen(info.getSerializedSize(HeaderCreator::getLargeFileFlag()));
|
||||
}
|
||||
|
||||
size_t EofPduSerializer::getSerializedSize() const {
|
||||
return FileDirectiveSerializer::getWholePduSize();
|
||||
}
|
||||
size_t EofPduCreator::getSerializedSize() const { return FileDirectiveCreator::getWholePduSize(); }
|
||||
|
||||
ReturnValue_t EofPduSerializer::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result =
|
||||
FileDirectiveSerializer::serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
ReturnValue_t EofPduCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result = FileDirectiveCreator::serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
if (*size + 1 > maxSize) {
|
||||
@@ -27,7 +23,7 @@ ReturnValue_t EofPduSerializer::serialize(uint8_t **buffer, size_t *size, size_t
|
||||
*size += 1;
|
||||
uint32_t checksum = info.getChecksum();
|
||||
result = SerializeAdapter::serialize(&checksum, buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
if (info.getFileSize().isLargeFile()) {
|
@@ -2,14 +2,14 @@
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_EOFPDUSERIALIZER_H_
|
||||
|
||||
#include "EofInfo.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveSerializer.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveCreator.h"
|
||||
#include "fsfw/cfdp/tlv/EntityIdTlv.h"
|
||||
|
||||
class EofPduSerializer : public FileDirectiveSerializer {
|
||||
class EofPduCreator : public FileDirectiveCreator {
|
||||
public:
|
||||
EofPduSerializer(PduConfig& conf, EofInfo& info);
|
||||
EofPduCreator(PduConfig& conf, EofInfo& info);
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
[[nodiscard]] size_t getSerializedSize() const override;
|
||||
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
@@ -1,17 +0,0 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_EOFPDUDESERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_EOFPDUDESERIALIZER_H_
|
||||
|
||||
#include "EofInfo.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveDeserializer.h"
|
||||
|
||||
class EofPduDeserializer : public FileDirectiveDeserializer {
|
||||
public:
|
||||
EofPduDeserializer(const uint8_t* pduBuf, size_t maxSize, EofInfo& eofInfo);
|
||||
|
||||
virtual ReturnValue_t parseData() override;
|
||||
|
||||
private:
|
||||
EofInfo& info;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_EOFPDUDESERIALIZER_H_ */
|
@@ -1,23 +1,23 @@
|
||||
#include "EofPduDeserializer.h"
|
||||
#include "EofPduReader.h"
|
||||
|
||||
#include "fsfw/FSFW.h"
|
||||
#include "fsfw/serviceinterface.h"
|
||||
|
||||
EofPduDeserializer::EofPduDeserializer(const uint8_t* pduBuf, size_t maxSize, EofInfo& eofInfo)
|
||||
: FileDirectiveDeserializer(pduBuf, maxSize), info(eofInfo) {}
|
||||
EofPduReader::EofPduReader(const uint8_t* pduBuf, size_t maxSize, EofInfo& eofInfo)
|
||||
: FileDirectiveReader(pduBuf, maxSize), info(eofInfo) {}
|
||||
|
||||
ReturnValue_t EofPduDeserializer::parseData() {
|
||||
ReturnValue_t result = FileDirectiveDeserializer::parseData();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
ReturnValue_t EofPduReader::parseData() {
|
||||
ReturnValue_t result = FileDirectiveReader::parseData();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const uint8_t* bufPtr = rawPtr;
|
||||
const uint8_t* bufPtr = pointers.rawPtr;
|
||||
size_t expectedFileFieldLen = 4;
|
||||
if (this->getLargeFileFlag()) {
|
||||
expectedFileFieldLen = 8;
|
||||
}
|
||||
size_t currentIdx = FileDirectiveDeserializer::getHeaderSize();
|
||||
size_t currentIdx = FileDirectiveReader::getHeaderSize();
|
||||
size_t deserLen = maxSize;
|
||||
if (maxSize < currentIdx + 5 + expectedFileFieldLen) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
@@ -31,7 +31,7 @@ ReturnValue_t EofPduDeserializer::parseData() {
|
||||
uint32_t checksum = 0;
|
||||
auto endianness = getEndianness();
|
||||
result = SerializeAdapter::deSerialize(&checksum, &bufPtr, &deserLen, endianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
info.setChecksum(checksum);
|
||||
@@ -44,7 +44,7 @@ ReturnValue_t EofPduDeserializer::parseData() {
|
||||
result = SerializeAdapter::deSerialize(&fileSizeValue, &bufPtr, &deserLen, endianness);
|
||||
info.setFileSize(fileSizeValue, false);
|
||||
}
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
if (info.getConditionCode() != cfdp::ConditionCode::NO_ERROR) {
|
||||
@@ -61,7 +61,7 @@ ReturnValue_t EofPduDeserializer::parseData() {
|
||||
" given TLV pointer invalid");
|
||||
#endif
|
||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
result = tlvPtr->deSerialize(&bufPtr, &deserLen, endianness);
|
||||
}
|
17
src/fsfw/cfdp/pdu/EofPduReader.h
Normal file
17
src/fsfw/cfdp/pdu/EofPduReader.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_EOFPDUDESERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_EOFPDUDESERIALIZER_H_
|
||||
|
||||
#include "EofInfo.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveReader.h"
|
||||
|
||||
class EofPduReader : public FileDirectiveReader {
|
||||
public:
|
||||
EofPduReader(const uint8_t* pduBuf, size_t maxSize, EofInfo& eofInfo);
|
||||
|
||||
ReturnValue_t parseData() override;
|
||||
|
||||
private:
|
||||
EofInfo& info;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_EOFPDUDESERIALIZER_H_ */
|
@@ -1,23 +1,22 @@
|
||||
#include "FileDataSerializer.h"
|
||||
#include "FileDataCreator.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
FileDataSerializer::FileDataSerializer(PduConfig& conf, FileDataInfo& info)
|
||||
: HeaderSerializer(conf, cfdp::PduType::FILE_DATA, 0, info.getSegmentMetadataFlag()),
|
||||
info(info) {
|
||||
FileDataCreator::FileDataCreator(PduConfig& conf, FileDataInfo& info)
|
||||
: HeaderCreator(conf, cfdp::PduType::FILE_DATA, 0, info.getSegmentMetadataFlag()), info(info) {
|
||||
update();
|
||||
}
|
||||
|
||||
void FileDataSerializer::update() {
|
||||
void FileDataCreator::update() {
|
||||
this->setSegmentMetadataFlag(info.getSegmentMetadataFlag());
|
||||
this->setSegmentationControl(info.getSegmentationControl());
|
||||
setPduDataFieldLen(info.getSerializedSize(this->getLargeFileFlag()));
|
||||
}
|
||||
|
||||
ReturnValue_t FileDataSerializer::serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result = HeaderSerializer::serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
ReturnValue_t FileDataCreator::serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result = HeaderCreator::serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
if (*size + this->getSerializedSize() > maxSize) {
|
||||
@@ -36,7 +35,7 @@ ReturnValue_t FileDataSerializer::serialize(uint8_t** buffer, size_t* size, size
|
||||
}
|
||||
cfdp::FileSize& offset = info.getOffset();
|
||||
result = offset.serialize(this->getLargeFileFlag(), buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
size_t fileSize = 0;
|
||||
@@ -47,9 +46,9 @@ ReturnValue_t FileDataSerializer::serialize(uint8_t** buffer, size_t* size, size
|
||||
std::memcpy(*buffer, readOnlyPtr, fileSize);
|
||||
*buffer += fileSize;
|
||||
*size += fileSize;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
size_t FileDataSerializer::getSerializedSize() const {
|
||||
return HeaderSerializer::getSerializedSize() + info.getSerializedSize(this->getLargeFileFlag());
|
||||
size_t FileDataCreator::getSerializedSize() const {
|
||||
return HeaderCreator::getSerializedSize() + info.getSerializedSize(this->getLargeFileFlag());
|
||||
}
|
23
src/fsfw/cfdp/pdu/FileDataCreator.h
Normal file
23
src/fsfw/cfdp/pdu/FileDataCreator.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef FSFW_CFDP_PDU_FILEDATASERIALIZER_H_
|
||||
#define FSFW_CFDP_PDU_FILEDATASERIALIZER_H_
|
||||
|
||||
#include "../definitions.h"
|
||||
#include "FileDataInfo.h"
|
||||
#include "HeaderCreator.h"
|
||||
|
||||
class FileDataCreator : public HeaderCreator {
|
||||
public:
|
||||
FileDataCreator(PduConfig& conf, FileDataInfo& info);
|
||||
|
||||
void update();
|
||||
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
[[nodiscard]] size_t getSerializedSize() const override;
|
||||
|
||||
private:
|
||||
FileDataInfo& info;
|
||||
};
|
||||
|
||||
#endif /* FSFW_CFDP_PDU_FILEDATASERIALIZER_H_ */
|
@@ -1,48 +0,0 @@
|
||||
#include "FileDataDeserializer.h"
|
||||
|
||||
FileDataDeserializer::FileDataDeserializer(const uint8_t* pduBuf, size_t maxSize,
|
||||
FileDataInfo& info)
|
||||
: HeaderDeserializer(pduBuf, maxSize), info(info) {}
|
||||
|
||||
ReturnValue_t FileDataDeserializer::parseData() {
|
||||
ReturnValue_t result = HeaderDeserializer::parseData();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
size_t currentIdx = HeaderDeserializer::getHeaderSize();
|
||||
const uint8_t* buf = rawPtr + currentIdx;
|
||||
size_t remSize = HeaderDeserializer::getWholePduSize() - currentIdx;
|
||||
if (remSize < 1) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
if (hasSegmentMetadataFlag()) {
|
||||
info.setSegmentMetadataFlag(true);
|
||||
info.setRecordContinuationState(static_cast<cfdp::RecordContinuationState>((*buf >> 6) & 0b11));
|
||||
size_t segmentMetadataLen = *buf & 0b00111111;
|
||||
info.setSegmentMetadataLen(segmentMetadataLen);
|
||||
if (remSize < segmentMetadataLen + 1) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
if (segmentMetadataLen > 0) {
|
||||
buf += 1;
|
||||
remSize -= 1;
|
||||
info.setSegmentMetadata(buf);
|
||||
buf += segmentMetadataLen;
|
||||
remSize -= segmentMetadataLen;
|
||||
}
|
||||
}
|
||||
result = info.getOffset().deSerialize(&buf, &remSize, this->getEndianness());
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if (remSize > 0) {
|
||||
info.setFileData(buf, remSize);
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
SerializeIF::Endianness FileDataDeserializer::getEndianness() const { return endianness; }
|
||||
|
||||
void FileDataDeserializer::setEndianness(SerializeIF::Endianness endianness) {
|
||||
this->endianness = endianness;
|
||||
}
|
@@ -50,23 +50,23 @@ ReturnValue_t FileDataInfo::addSegmentMetadataInfo(cfdp::RecordContinuationState
|
||||
this->segmentMetadataFlag = cfdp::SegmentMetadataFlag::PRESENT;
|
||||
this->recContState = recContState;
|
||||
if (segmentMetadataLen > 63) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
this->segmentMetadata = segmentMetadata;
|
||||
this->segmentMetadataLen = segmentMetadataLen;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
const uint8_t *FileDataInfo::getFileData(size_t *fileSize) const {
|
||||
if (fileSize != nullptr) {
|
||||
*fileSize = this->fileSize;
|
||||
const uint8_t *FileDataInfo::getFileData(size_t *fileSize_) const {
|
||||
if (fileSize_ != nullptr) {
|
||||
*fileSize_ = this->fileSize;
|
||||
}
|
||||
return fileData;
|
||||
}
|
||||
|
||||
const uint8_t *FileDataInfo::getSegmentMetadata(size_t *segmentMetadataLen) {
|
||||
if (segmentMetadataLen != nullptr) {
|
||||
*segmentMetadataLen = this->segmentMetadataLen;
|
||||
const uint8_t *FileDataInfo::getSegmentMetadata(size_t *segmentMetadataLen_) {
|
||||
if (segmentMetadataLen_ != nullptr) {
|
||||
*segmentMetadataLen_ = this->segmentMetadataLen;
|
||||
}
|
||||
return segmentMetadata;
|
||||
}
|
||||
|
@@ -6,25 +6,25 @@
|
||||
|
||||
class FileDataInfo {
|
||||
public:
|
||||
FileDataInfo(cfdp::FileSize& offset);
|
||||
explicit FileDataInfo(cfdp::FileSize& offset);
|
||||
FileDataInfo(cfdp::FileSize& offset, const uint8_t* fileData, size_t fileSize);
|
||||
|
||||
size_t getSerializedSize(bool largeFile = false) const;
|
||||
[[nodiscard]] size_t getSerializedSize(bool largeFile = false) const;
|
||||
|
||||
cfdp::FileSize& getOffset();
|
||||
const uint8_t* getFileData(size_t* fileSize = nullptr) const;
|
||||
void setFileData(const uint8_t* fileData, size_t fileSize);
|
||||
|
||||
cfdp::SegmentMetadataFlag getSegmentMetadataFlag() const;
|
||||
cfdp::SegmentationControl getSegmentationControl() const;
|
||||
cfdp::RecordContinuationState getRecordContinuationState() const;
|
||||
[[nodiscard]] cfdp::SegmentMetadataFlag getSegmentMetadataFlag() const;
|
||||
[[nodiscard]] cfdp::SegmentationControl getSegmentationControl() const;
|
||||
[[nodiscard]] cfdp::RecordContinuationState getRecordContinuationState() const;
|
||||
void setRecordContinuationState(cfdp::RecordContinuationState recContState);
|
||||
void setSegmentationControl(cfdp::SegmentationControl segCtrl);
|
||||
|
||||
size_t getSegmentMetadataLen() const;
|
||||
[[nodiscard]] size_t getSegmentMetadataLen() const;
|
||||
void setSegmentMetadataLen(size_t len);
|
||||
void setSegmentMetadata(const uint8_t* ptr);
|
||||
bool hasSegmentMetadata() const;
|
||||
[[nodiscard]] bool hasSegmentMetadata() const;
|
||||
void setSegmentMetadataFlag(bool enable);
|
||||
ReturnValue_t addSegmentMetadataInfo(cfdp::RecordContinuationState recContState,
|
||||
const uint8_t* segmentMetadata, size_t segmentMetadataLen);
|
||||
|
47
src/fsfw/cfdp/pdu/FileDataReader.cpp
Normal file
47
src/fsfw/cfdp/pdu/FileDataReader.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
#include "FileDataReader.h"
|
||||
|
||||
FileDataReader::FileDataReader(const uint8_t* pduBuf, size_t maxSize, FileDataInfo& info)
|
||||
: HeaderReader(pduBuf, maxSize), info(info) {}
|
||||
|
||||
ReturnValue_t FileDataReader::parseData() {
|
||||
ReturnValue_t result = HeaderReader::parseData();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
size_t currentIdx = HeaderReader::getHeaderSize();
|
||||
const uint8_t* buf = pointers.rawPtr + currentIdx;
|
||||
size_t remSize = HeaderReader::getWholePduSize() - currentIdx;
|
||||
if (remSize < 1) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
if (hasSegmentMetadataFlag()) {
|
||||
info.setSegmentMetadataFlag(true);
|
||||
info.setRecordContinuationState(static_cast<cfdp::RecordContinuationState>((*buf >> 6) & 0b11));
|
||||
size_t segmentMetadataLen = *buf & 0b00111111;
|
||||
info.setSegmentMetadataLen(segmentMetadataLen);
|
||||
if (remSize < segmentMetadataLen + 1) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
if (segmentMetadataLen > 0) {
|
||||
buf += 1;
|
||||
remSize -= 1;
|
||||
info.setSegmentMetadata(buf);
|
||||
buf += segmentMetadataLen;
|
||||
remSize -= segmentMetadataLen;
|
||||
}
|
||||
}
|
||||
result = info.getOffset().deSerialize(&buf, &remSize, this->getEndianness());
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
if (remSize > 0) {
|
||||
info.setFileData(buf, remSize);
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
SerializeIF::Endianness FileDataReader::getEndianness() const { return endianness; }
|
||||
|
||||
void FileDataReader::setEndianness(SerializeIF::Endianness endianness_) {
|
||||
endianness = endianness_;
|
||||
}
|
@@ -3,14 +3,14 @@
|
||||
|
||||
#include "../definitions.h"
|
||||
#include "FileDataInfo.h"
|
||||
#include "HeaderDeserializer.h"
|
||||
#include "HeaderReader.h"
|
||||
|
||||
class FileDataDeserializer : public HeaderDeserializer {
|
||||
class FileDataReader : public HeaderReader {
|
||||
public:
|
||||
FileDataDeserializer(const uint8_t* pduBuf, size_t maxSize, FileDataInfo& info);
|
||||
FileDataReader(const uint8_t* pduBuf, size_t maxSize, FileDataInfo& info);
|
||||
|
||||
ReturnValue_t parseData();
|
||||
SerializeIF::Endianness getEndianness() const;
|
||||
ReturnValue_t parseData() override;
|
||||
[[nodiscard]] SerializeIF::Endianness getEndianness() const;
|
||||
void setEndianness(SerializeIF::Endianness endianness = SerializeIF::Endianness::NETWORK);
|
||||
|
||||
private:
|
@@ -1,23 +0,0 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_FILEDATASERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_FILEDATASERIALIZER_H_
|
||||
|
||||
#include "../definitions.h"
|
||||
#include "FileDataInfo.h"
|
||||
#include "HeaderSerializer.h"
|
||||
|
||||
class FileDataSerializer : public HeaderSerializer {
|
||||
public:
|
||||
FileDataSerializer(PduConfig& conf, FileDataInfo& info);
|
||||
|
||||
void update();
|
||||
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
private:
|
||||
FileDataInfo& info;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_CFDP_PDU_FILEDATADESERIALIZER_H_ */
|
37
src/fsfw/cfdp/pdu/FileDirectiveCreator.cpp
Normal file
37
src/fsfw/cfdp/pdu/FileDirectiveCreator.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#include "FileDirectiveCreator.h"
|
||||
|
||||
FileDirectiveCreator::FileDirectiveCreator(PduConfig &pduConf, cfdp::FileDirectives directiveCode,
|
||||
size_t directiveParamFieldLen)
|
||||
: HeaderCreator(pduConf, cfdp::PduType::FILE_DIRECTIVE, directiveParamFieldLen + 1),
|
||||
directiveCode(directiveCode) {}
|
||||
|
||||
size_t FileDirectiveCreator::getSerializedSize() const {
|
||||
return HeaderCreator::getSerializedSize() + 1;
|
||||
}
|
||||
|
||||
ReturnValue_t FileDirectiveCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
if (buffer == nullptr or size == nullptr) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
if (FileDirectiveCreator::getWholePduSize() > maxSize) {
|
||||
return BUFFER_TOO_SHORT;
|
||||
}
|
||||
ReturnValue_t result = HeaderCreator::serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (*size >= maxSize) {
|
||||
return BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = directiveCode;
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
void FileDirectiveCreator::setDirectiveDataFieldLen(size_t len) {
|
||||
// Set length of data field plus 1 byte for the directive octet
|
||||
HeaderCreator::setPduDataFieldLen(len + 1);
|
||||
}
|
@@ -1,20 +1,20 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_FILEDIRECTIVESERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_FILEDIRECTIVESERIALIZER_H_
|
||||
|
||||
#include "fsfw/cfdp/pdu/HeaderSerializer.h"
|
||||
#include "fsfw/cfdp/pdu/HeaderCreator.h"
|
||||
|
||||
class FileDirectiveSerializer : public HeaderSerializer {
|
||||
class FileDirectiveCreator : public HeaderCreator {
|
||||
public:
|
||||
FileDirectiveSerializer(PduConfig& pduConf, cfdp::FileDirectives directiveCode,
|
||||
size_t directiveParamFieldLen);
|
||||
FileDirectiveCreator(PduConfig& pduConf, cfdp::FileDirectives directiveCode,
|
||||
size_t directiveParamFieldLen);
|
||||
|
||||
/**
|
||||
* This only returns the size of the PDU header + 1 for the directive code octet.
|
||||
* Use FileDirectiveSerializer::getWholePduSize to get the full packet length, assuming
|
||||
* Use FileDirectiveCreator::getWholePduSize to get the full packet length, assuming
|
||||
* the length fields was set correctly
|
||||
* @return
|
||||
*/
|
||||
size_t getSerializedSize() const override;
|
||||
[[nodiscard]] size_t getSerializedSize() const override;
|
||||
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
@@ -1,49 +0,0 @@
|
||||
#include "FileDirectiveDeserializer.h"
|
||||
|
||||
FileDirectiveDeserializer::FileDirectiveDeserializer(const uint8_t *pduBuf, size_t maxSize)
|
||||
: HeaderDeserializer(pduBuf, maxSize) {}
|
||||
|
||||
cfdp::FileDirectives FileDirectiveDeserializer::getFileDirective() const { return fileDirective; }
|
||||
|
||||
ReturnValue_t FileDirectiveDeserializer::parseData() {
|
||||
ReturnValue_t result = HeaderDeserializer::parseData();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if (this->getPduDataFieldLen() < 1) {
|
||||
return cfdp::INVALID_PDU_DATAFIELD_LEN;
|
||||
}
|
||||
if (FileDirectiveDeserializer::getWholePduSize() > maxSize) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
size_t currentIdx = HeaderDeserializer::getHeaderSize();
|
||||
if (not checkFileDirective(rawPtr[currentIdx])) {
|
||||
return cfdp::INVALID_DIRECTIVE_FIELDS;
|
||||
}
|
||||
setFileDirective(static_cast<cfdp::FileDirectives>(rawPtr[currentIdx]));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
size_t FileDirectiveDeserializer::getHeaderSize() const {
|
||||
// return size of header plus the directive byte
|
||||
return HeaderDeserializer::getHeaderSize() + 1;
|
||||
}
|
||||
|
||||
bool FileDirectiveDeserializer::checkFileDirective(uint8_t rawByte) {
|
||||
if (rawByte < cfdp::FileDirectives::EOF_DIRECTIVE or
|
||||
(rawByte > cfdp::FileDirectives::PROMPT and rawByte != cfdp::FileDirectives::KEEP_ALIVE)) {
|
||||
// Invalid directive field. TODO: Custom returnvalue
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileDirectiveDeserializer::setFileDirective(cfdp::FileDirectives fileDirective) {
|
||||
this->fileDirective = fileDirective;
|
||||
}
|
||||
|
||||
void FileDirectiveDeserializer::setEndianness(SerializeIF::Endianness endianness) {
|
||||
this->endianness = endianness;
|
||||
}
|
||||
|
||||
SerializeIF::Endianness FileDirectiveDeserializer::getEndianness() const { return endianness; }
|
49
src/fsfw/cfdp/pdu/FileDirectiveReader.cpp
Normal file
49
src/fsfw/cfdp/pdu/FileDirectiveReader.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include "FileDirectiveReader.h"
|
||||
|
||||
FileDirectiveReader::FileDirectiveReader(const uint8_t *pduBuf, size_t maxSize)
|
||||
: HeaderReader(pduBuf, maxSize) {}
|
||||
|
||||
cfdp::FileDirectives FileDirectiveReader::getFileDirective() const { return fileDirective; }
|
||||
|
||||
ReturnValue_t FileDirectiveReader::parseData() {
|
||||
ReturnValue_t result = HeaderReader::parseData();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
if (this->getPduDataFieldLen() < 1) {
|
||||
return cfdp::INVALID_PDU_DATAFIELD_LEN;
|
||||
}
|
||||
if (FileDirectiveReader::getWholePduSize() > maxSize) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
size_t currentIdx = HeaderReader::getHeaderSize();
|
||||
if (not checkFileDirective(pointers.rawPtr[currentIdx])) {
|
||||
return cfdp::INVALID_DIRECTIVE_FIELDS;
|
||||
}
|
||||
setFileDirective(static_cast<cfdp::FileDirectives>(pointers.rawPtr[currentIdx]));
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
size_t FileDirectiveReader::getHeaderSize() const {
|
||||
// return size of header plus the directive byte
|
||||
return HeaderReader::getHeaderSize() + 1;
|
||||
}
|
||||
|
||||
bool FileDirectiveReader::checkFileDirective(uint8_t rawByte) {
|
||||
if (rawByte < cfdp::FileDirectives::EOF_DIRECTIVE or
|
||||
(rawByte > cfdp::FileDirectives::PROMPT and rawByte != cfdp::FileDirectives::KEEP_ALIVE)) {
|
||||
// Invalid directive field. TODO: Custom returnvalue
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileDirectiveReader::setFileDirective(cfdp::FileDirectives fileDirective_) {
|
||||
fileDirective = fileDirective_;
|
||||
}
|
||||
|
||||
void FileDirectiveReader::setEndianness(SerializeIF::Endianness endianness_) {
|
||||
endianness = endianness_;
|
||||
}
|
||||
|
||||
SerializeIF::Endianness FileDirectiveReader::getEndianness() const { return endianness; }
|
@@ -2,7 +2,7 @@
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_FILEDIRECTIVEDESERIALIZER_H_
|
||||
|
||||
#include "../definitions.h"
|
||||
#include "fsfw/cfdp/pdu/HeaderDeserializer.h"
|
||||
#include "fsfw/cfdp/pdu/HeaderReader.h"
|
||||
|
||||
/**
|
||||
* @brief This class is used to deserialize a PDU file directive header from raw memory.
|
||||
@@ -11,24 +11,24 @@
|
||||
* This is a zero-copy implementation and #parseData needs to be called to ensure the data is
|
||||
* valid.
|
||||
*/
|
||||
class FileDirectiveDeserializer : public HeaderDeserializer {
|
||||
class FileDirectiveReader : public HeaderReader {
|
||||
public:
|
||||
FileDirectiveDeserializer(const uint8_t* pduBuf, size_t maxSize);
|
||||
FileDirectiveReader(const uint8_t* pduBuf, size_t maxSize);
|
||||
|
||||
/**
|
||||
* This needs to be called before accessing the PDU fields to avoid segmentation faults.
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t parseData();
|
||||
size_t getHeaderSize() const;
|
||||
ReturnValue_t parseData() override;
|
||||
[[nodiscard]] size_t getHeaderSize() const override;
|
||||
|
||||
cfdp::FileDirectives getFileDirective() const;
|
||||
[[nodiscard]] cfdp::FileDirectives getFileDirective() const;
|
||||
|
||||
void setEndianness(SerializeIF::Endianness endianness);
|
||||
SerializeIF::Endianness getEndianness() const;
|
||||
[[nodiscard]] SerializeIF::Endianness getEndianness() const;
|
||||
|
||||
protected:
|
||||
bool checkFileDirective(uint8_t rawByte);
|
||||
static bool checkFileDirective(uint8_t rawByte);
|
||||
|
||||
private:
|
||||
void setFileDirective(cfdp::FileDirectives fileDirective);
|
@@ -1,38 +0,0 @@
|
||||
#include "FileDirectiveSerializer.h"
|
||||
|
||||
FileDirectiveSerializer::FileDirectiveSerializer(PduConfig &pduConf,
|
||||
cfdp::FileDirectives directiveCode,
|
||||
size_t directiveParamFieldLen)
|
||||
: HeaderSerializer(pduConf, cfdp::PduType::FILE_DIRECTIVE, directiveParamFieldLen + 1),
|
||||
directiveCode(directiveCode) {}
|
||||
|
||||
size_t FileDirectiveSerializer::getSerializedSize() const {
|
||||
return HeaderSerializer::getSerializedSize() + 1;
|
||||
}
|
||||
|
||||
ReturnValue_t FileDirectiveSerializer::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
if (buffer == nullptr or size == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
if (FileDirectiveSerializer::getWholePduSize() > maxSize) {
|
||||
return BUFFER_TOO_SHORT;
|
||||
}
|
||||
ReturnValue_t result = HeaderSerializer::serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (*size >= maxSize) {
|
||||
return BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = directiveCode;
|
||||
*buffer += 1;
|
||||
*size += 1;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
void FileDirectiveSerializer::setDirectiveDataFieldLen(size_t len) {
|
||||
// Set length of data field plus 1 byte for the directive octet
|
||||
HeaderSerializer::setPduDataFieldLen(len + 1);
|
||||
}
|
@@ -2,9 +2,8 @@
|
||||
|
||||
FinishedInfo::FinishedInfo() {}
|
||||
|
||||
FinishedInfo::FinishedInfo(cfdp::ConditionCode conditionCode,
|
||||
cfdp::FinishedDeliveryCode deliveryCode,
|
||||
cfdp::FinishedFileStatus fileStatus)
|
||||
FinishedInfo::FinishedInfo(cfdp::ConditionCode conditionCode, cfdp::FileDeliveryCode deliveryCode,
|
||||
cfdp::FileDeliveryStatus fileStatus)
|
||||
: conditionCode(conditionCode), deliveryCode(deliveryCode), fileStatus(fileStatus) {}
|
||||
|
||||
size_t FinishedInfo::getSerializedSize() const {
|
||||
@@ -46,14 +45,14 @@ ReturnValue_t FinishedInfo::setFilestoreResponsesArray(FilestoreResponseTlv** fs
|
||||
if (maxFsResponsesLen != nullptr) {
|
||||
this->fsResponsesMaxLen = *maxFsResponsesLen;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t FinishedInfo::getFilestoreResonses(FilestoreResponseTlv*** fsResponses,
|
||||
size_t* fsResponsesLen,
|
||||
size_t* fsResponsesMaxLen) {
|
||||
if (fsResponses == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
*fsResponses = this->fsResponses;
|
||||
if (fsResponsesLen != nullptr) {
|
||||
@@ -62,7 +61,7 @@ ReturnValue_t FinishedInfo::getFilestoreResonses(FilestoreResponseTlv*** fsRespo
|
||||
if (fsResponsesMaxLen != nullptr) {
|
||||
*fsResponsesMaxLen = this->fsResponsesMaxLen;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
void FinishedInfo::setFaultLocation(EntityIdTlv* faultLocation) {
|
||||
@@ -71,10 +70,10 @@ void FinishedInfo::setFaultLocation(EntityIdTlv* faultLocation) {
|
||||
|
||||
ReturnValue_t FinishedInfo::getFaultLocation(EntityIdTlv** faultLocation) {
|
||||
if (this->faultLocation == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
*faultLocation = this->faultLocation;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
cfdp::ConditionCode FinishedInfo::getConditionCode() const { return conditionCode; }
|
||||
@@ -83,13 +82,13 @@ void FinishedInfo::setConditionCode(cfdp::ConditionCode conditionCode) {
|
||||
this->conditionCode = conditionCode;
|
||||
}
|
||||
|
||||
cfdp::FinishedDeliveryCode FinishedInfo::getDeliveryCode() const { return deliveryCode; }
|
||||
cfdp::FileDeliveryCode FinishedInfo::getDeliveryCode() const { return deliveryCode; }
|
||||
|
||||
void FinishedInfo::setDeliveryCode(cfdp::FinishedDeliveryCode deliveryCode) {
|
||||
void FinishedInfo::setDeliveryCode(cfdp::FileDeliveryCode deliveryCode) {
|
||||
this->deliveryCode = deliveryCode;
|
||||
}
|
||||
|
||||
cfdp::FinishedFileStatus FinishedInfo::getFileStatus() const { return fileStatus; }
|
||||
cfdp::FileDeliveryStatus FinishedInfo::getFileStatus() const { return fileStatus; }
|
||||
|
||||
void FinishedInfo::setFilestoreResponsesArrayLen(size_t fsResponsesLen) {
|
||||
this->fsResponsesLen = fsResponsesLen;
|
||||
@@ -97,6 +96,6 @@ void FinishedInfo::setFilestoreResponsesArrayLen(size_t fsResponsesLen) {
|
||||
|
||||
size_t FinishedInfo::getFsResponsesLen() const { return fsResponsesLen; }
|
||||
|
||||
void FinishedInfo::setFileStatus(cfdp::FinishedFileStatus fileStatus) {
|
||||
void FinishedInfo::setFileStatus(cfdp::FileDeliveryStatus fileStatus) {
|
||||
this->fileStatus = fileStatus;
|
||||
}
|
||||
|
@@ -8,13 +8,13 @@
|
||||
class FinishedInfo {
|
||||
public:
|
||||
FinishedInfo();
|
||||
FinishedInfo(cfdp::ConditionCode conditionCode, cfdp::FinishedDeliveryCode deliveryCode,
|
||||
cfdp::FinishedFileStatus fileStatus);
|
||||
FinishedInfo(cfdp::ConditionCode conditionCode, cfdp::FileDeliveryCode deliveryCode,
|
||||
cfdp::FileDeliveryStatus fileStatus);
|
||||
|
||||
size_t getSerializedSize() const;
|
||||
[[nodiscard]] size_t getSerializedSize() const;
|
||||
|
||||
bool hasFsResponses() const;
|
||||
bool canHoldFsResponses() const;
|
||||
[[nodiscard]] bool hasFsResponses() const;
|
||||
[[nodiscard]] bool canHoldFsResponses() const;
|
||||
|
||||
ReturnValue_t setFilestoreResponsesArray(FilestoreResponseTlv** fsResponses,
|
||||
size_t* fsResponsesLen, const size_t* maxFsResponseLen);
|
||||
@@ -22,20 +22,20 @@ class FinishedInfo {
|
||||
|
||||
ReturnValue_t getFilestoreResonses(FilestoreResponseTlv*** fsResponses, size_t* fsResponsesLen,
|
||||
size_t* fsResponsesMaxLen);
|
||||
size_t getFsResponsesLen() const;
|
||||
[[nodiscard]] size_t getFsResponsesLen() const;
|
||||
void setFilestoreResponsesArrayLen(size_t fsResponsesLen);
|
||||
ReturnValue_t getFaultLocation(EntityIdTlv** entityId);
|
||||
cfdp::ConditionCode getConditionCode() const;
|
||||
[[nodiscard]] cfdp::ConditionCode getConditionCode() const;
|
||||
void setConditionCode(cfdp::ConditionCode conditionCode);
|
||||
cfdp::FinishedDeliveryCode getDeliveryCode() const;
|
||||
void setDeliveryCode(cfdp::FinishedDeliveryCode deliveryCode);
|
||||
cfdp::FinishedFileStatus getFileStatus() const;
|
||||
void setFileStatus(cfdp::FinishedFileStatus fileStatus);
|
||||
[[nodiscard]] cfdp::FileDeliveryCode getDeliveryCode() const;
|
||||
void setDeliveryCode(cfdp::FileDeliveryCode deliveryCode);
|
||||
[[nodiscard]] cfdp::FileDeliveryStatus getFileStatus() const;
|
||||
void setFileStatus(cfdp::FileDeliveryStatus fileStatus);
|
||||
|
||||
private:
|
||||
cfdp::ConditionCode conditionCode = cfdp::ConditionCode::NO_CONDITION_FIELD;
|
||||
cfdp::FinishedDeliveryCode deliveryCode = cfdp::FinishedDeliveryCode::DATA_COMPLETE;
|
||||
cfdp::FinishedFileStatus fileStatus = cfdp::FinishedFileStatus::DISCARDED_DELIBERATELY;
|
||||
cfdp::FileDeliveryCode deliveryCode = cfdp::FileDeliveryCode::DATA_COMPLETE;
|
||||
cfdp::FileDeliveryStatus fileStatus = cfdp::FileDeliveryStatus::DISCARDED_DELIBERATELY;
|
||||
FilestoreResponseTlv** fsResponses = nullptr;
|
||||
size_t fsResponsesLen = 0;
|
||||
size_t fsResponsesMaxLen = 0;
|
||||
|
@@ -2,24 +2,24 @@
|
||||
|
||||
FinishPduDeserializer::FinishPduDeserializer(const uint8_t* pduBuf, size_t maxSize,
|
||||
FinishedInfo& info)
|
||||
: FileDirectiveDeserializer(pduBuf, maxSize), finishedInfo(info) {}
|
||||
: FileDirectiveReader(pduBuf, maxSize), finishedInfo(info) {}
|
||||
|
||||
ReturnValue_t FinishPduDeserializer::parseData() {
|
||||
ReturnValue_t result = FileDirectiveDeserializer::parseData();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
ReturnValue_t result = FileDirectiveReader::parseData();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
size_t currentIdx = FileDirectiveDeserializer::getHeaderSize();
|
||||
const uint8_t* buf = rawPtr + currentIdx;
|
||||
size_t remSize = FileDirectiveDeserializer::getWholePduSize() - currentIdx;
|
||||
size_t currentIdx = FileDirectiveReader::getHeaderSize();
|
||||
const uint8_t* buf = pointers.rawPtr + currentIdx;
|
||||
size_t remSize = FileDirectiveReader::getWholePduSize() - currentIdx;
|
||||
if (remSize < 1) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
uint8_t firstByte = *buf;
|
||||
cfdp::ConditionCode condCode = static_cast<cfdp::ConditionCode>((firstByte >> 4) & 0x0f);
|
||||
auto condCode = static_cast<cfdp::ConditionCode>((firstByte >> 4) & 0x0f);
|
||||
finishedInfo.setConditionCode(condCode);
|
||||
finishedInfo.setDeliveryCode(static_cast<cfdp::FinishedDeliveryCode>(firstByte >> 2 & 0b1));
|
||||
finishedInfo.setFileStatus(static_cast<cfdp::FinishedFileStatus>(firstByte & 0b11));
|
||||
finishedInfo.setDeliveryCode(static_cast<cfdp::FileDeliveryCode>(firstByte >> 2 & 0b1));
|
||||
finishedInfo.setFileStatus(static_cast<cfdp::FileDeliveryStatus>(firstByte & 0b11));
|
||||
buf += 1;
|
||||
remSize -= 1;
|
||||
currentIdx += 1;
|
||||
@@ -33,7 +33,7 @@ FinishedInfo& FinishPduDeserializer::getInfo() { return finishedInfo; }
|
||||
|
||||
ReturnValue_t FinishPduDeserializer::parseTlvs(size_t remLen, size_t currentIdx, const uint8_t* buf,
|
||||
cfdp::ConditionCode conditionCode) {
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
size_t fsResponsesIdx = 0;
|
||||
auto endianness = getEndianness();
|
||||
FilestoreResponseTlv** fsResponseArray = nullptr;
|
||||
@@ -60,7 +60,7 @@ ReturnValue_t FinishPduDeserializer::parseTlvs(size_t remLen, size_t currentIdx,
|
||||
return cfdp::FINISHED_CANT_PARSE_FS_RESPONSES;
|
||||
}
|
||||
result = fsResponseArray[fsResponsesIdx]->deSerialize(&buf, &remLen, endianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
fsResponsesIdx += 1;
|
||||
@@ -72,11 +72,11 @@ ReturnValue_t FinishPduDeserializer::parseTlvs(size_t remLen, size_t currentIdx,
|
||||
return cfdp::INVALID_TLV_TYPE;
|
||||
}
|
||||
result = finishedInfo.getFaultLocation(&faultLocation);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = faultLocation->deSerialize(&buf, &remLen, endianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
|
@@ -1,10 +1,10 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_FINISHEDPDUDESERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_FINISHEDPDUDESERIALIZER_H_
|
||||
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveDeserializer.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveReader.h"
|
||||
#include "fsfw/cfdp/pdu/FinishedInfo.h"
|
||||
|
||||
class FinishPduDeserializer : public FileDirectiveDeserializer {
|
||||
class FinishPduDeserializer : public FileDirectiveReader {
|
||||
public:
|
||||
FinishPduDeserializer(const uint8_t* pduBuf, size_t maxSize, FinishedInfo& info);
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#include "FinishedPduSerializer.h"
|
||||
|
||||
FinishPduSerializer::FinishPduSerializer(PduConfig &conf, FinishedInfo &finishInfo)
|
||||
: FileDirectiveSerializer(conf, cfdp::FileDirectives::FINISH, 0), finishInfo(finishInfo) {
|
||||
: FileDirectiveCreator(conf, cfdp::FileDirectives::FINISH, 0), finishInfo(finishInfo) {
|
||||
updateDirectiveFieldLen();
|
||||
}
|
||||
|
||||
@@ -15,9 +15,8 @@ void FinishPduSerializer::updateDirectiveFieldLen() {
|
||||
|
||||
ReturnValue_t FinishPduSerializer::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result =
|
||||
FileDirectiveSerializer::serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
ReturnValue_t result = FileDirectiveCreator::serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
if (*size + 1 >= maxSize) {
|
||||
@@ -34,13 +33,13 @@ ReturnValue_t FinishPduSerializer::serialize(uint8_t **buffer, size_t *size, siz
|
||||
finishInfo.getFilestoreResonses(&fsResponsesArray, &fsResponsesArrayLen, nullptr);
|
||||
for (size_t idx = 0; idx < fsResponsesArrayLen; idx++) {
|
||||
result = fsResponsesArray[idx]->serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
EntityIdTlv *entityId = nullptr;
|
||||
if (finishInfo.getFaultLocation(&entityId) == HasReturnvaluesIF::RETURN_OK) {
|
||||
if (finishInfo.getFaultLocation(&entityId) == returnvalue::OK) {
|
||||
result = entityId->serialize(buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
return result;
|
||||
|
@@ -2,10 +2,10 @@
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_FINISHEDPDUSERIALIZER_H_
|
||||
|
||||
#include "FinishedInfo.h"
|
||||
#include "fsfw/cfdp/pdu/FileDataSerializer.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveSerializer.h"
|
||||
#include "fsfw/cfdp/pdu/FileDataCreator.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveCreator.h"
|
||||
|
||||
class FinishPduSerializer : public FileDirectiveSerializer {
|
||||
class FinishPduSerializer : public FileDirectiveCreator {
|
||||
public:
|
||||
FinishPduSerializer(PduConfig& pduConf, FinishedInfo& finishInfo);
|
||||
|
||||
|
111
src/fsfw/cfdp/pdu/HeaderCreator.cpp
Normal file
111
src/fsfw/cfdp/pdu/HeaderCreator.cpp
Normal file
@@ -0,0 +1,111 @@
|
||||
#include "HeaderCreator.h"
|
||||
|
||||
HeaderCreator::HeaderCreator(PduConfig &pduConf, cfdp::PduType pduType, size_t initPduDataFieldLen,
|
||||
cfdp::SegmentMetadataFlag segmentMetadataFlag,
|
||||
cfdp::SegmentationControl segCtrl)
|
||||
: pduType(pduType),
|
||||
segmentMetadataFlag(segmentMetadataFlag),
|
||||
segmentationCtrl(segCtrl),
|
||||
pduDataFieldLen(initPduDataFieldLen),
|
||||
pduConf(pduConf) {}
|
||||
|
||||
ReturnValue_t HeaderCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
if (buffer == nullptr or size == nullptr) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
if (maxSize < this->getSerializedSize()) {
|
||||
return BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = cfdp::VERSION_BITS | this->pduType << 4 | pduConf.direction << 3 | pduConf.mode << 2 |
|
||||
pduConf.crcFlag << 1 | pduConf.largeFile;
|
||||
*buffer += 1;
|
||||
**buffer = (pduDataFieldLen & 0xff00) >> 8;
|
||||
*buffer += 1;
|
||||
**buffer = pduDataFieldLen & 0x00ff;
|
||||
*buffer += 1;
|
||||
**buffer = segmentationCtrl << 7 | pduConf.sourceId.getWidth() << 4 | segmentMetadataFlag << 3 |
|
||||
pduConf.seqNum.getWidth();
|
||||
*buffer += 1;
|
||||
*size += 4;
|
||||
ReturnValue_t result = pduConf.sourceId.serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = pduConf.seqNum.serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = pduConf.destId.serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
size_t HeaderCreator::getSerializedSize() const {
|
||||
return pduConf.seqNum.getWidth() + pduConf.sourceId.getWidth() * 2 + 4;
|
||||
}
|
||||
|
||||
ReturnValue_t HeaderCreator::deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) {
|
||||
// We could implement this, but I prefer dedicated classes
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
||||
size_t HeaderCreator::getWholePduSize() const {
|
||||
// Return size of header plus the PDU data field length
|
||||
return pduDataFieldLen + HeaderCreator::getSerializedSize();
|
||||
}
|
||||
|
||||
size_t HeaderCreator::getPduDataFieldLen() const { return pduDataFieldLen; }
|
||||
|
||||
void HeaderCreator::setPduDataFieldLen(size_t pduDataFieldLen_) {
|
||||
pduDataFieldLen = pduDataFieldLen_;
|
||||
}
|
||||
|
||||
void HeaderCreator::setPduType(cfdp::PduType pduType_) { pduType = pduType_; }
|
||||
|
||||
void HeaderCreator::setSegmentMetadataFlag(cfdp::SegmentMetadataFlag segmentMetadataFlag_) {
|
||||
segmentMetadataFlag = segmentMetadataFlag_;
|
||||
}
|
||||
|
||||
cfdp::PduType HeaderCreator::getPduType() const { return pduType; }
|
||||
|
||||
cfdp::Direction HeaderCreator::getDirection() const { return pduConf.direction; }
|
||||
|
||||
cfdp::TransmissionModes HeaderCreator::getTransmissionMode() const { return pduConf.mode; }
|
||||
|
||||
bool HeaderCreator::getCrcFlag() const { return pduConf.crcFlag; }
|
||||
|
||||
bool HeaderCreator::getLargeFileFlag() const { return pduConf.largeFile; }
|
||||
|
||||
cfdp::SegmentationControl HeaderCreator::getSegmentationControl() const { return segmentationCtrl; }
|
||||
|
||||
cfdp::WidthInBytes HeaderCreator::getLenEntityIds() const { return pduConf.sourceId.getWidth(); }
|
||||
|
||||
cfdp::WidthInBytes HeaderCreator::getLenSeqNum() const { return pduConf.seqNum.getWidth(); }
|
||||
|
||||
cfdp::SegmentMetadataFlag HeaderCreator::getSegmentMetadataFlag() const {
|
||||
return segmentMetadataFlag;
|
||||
}
|
||||
|
||||
void HeaderCreator::getSourceId(cfdp::EntityId &sourceId) const { sourceId = pduConf.sourceId; }
|
||||
|
||||
void HeaderCreator::getDestId(cfdp::EntityId &destId) const { destId = pduConf.destId; }
|
||||
|
||||
void HeaderCreator::setSegmentationControl(cfdp::SegmentationControl segmentationControl) {
|
||||
this->segmentationCtrl = segmentationControl;
|
||||
}
|
||||
|
||||
void HeaderCreator::getTransactionSeqNum(cfdp::TransactionSeqNum &seqNum) const {
|
||||
seqNum = pduConf.seqNum;
|
||||
}
|
||||
|
||||
bool HeaderCreator::hasSegmentMetadataFlag() const {
|
||||
if (this->segmentMetadataFlag == cfdp::SegmentMetadataFlag::PRESENT) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
@@ -1,14 +1,14 @@
|
||||
#ifndef FSFW_SRC_FSFW_CFDP_PDU_HEADERSERIALIZER_H_
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_HEADERSERIALIZER_H_
|
||||
|
||||
#include "../definitions.h"
|
||||
#include "PduConfig.h"
|
||||
#include "PduHeaderIF.h"
|
||||
#include "fsfw/cfdp/definitions.h"
|
||||
#include "fsfw/serialize/SerializeIF.h"
|
||||
|
||||
class HeaderSerializer : public SerializeIF, public PduHeaderIF {
|
||||
class HeaderCreator : public SerializeIF, public PduHeaderIF {
|
||||
public:
|
||||
HeaderSerializer(
|
||||
HeaderCreator(
|
||||
PduConfig& pduConf, cfdp::PduType pduType, size_t initPduDataFieldLen,
|
||||
cfdp::SegmentMetadataFlag segmentMetadataFlag = cfdp::SegmentMetadataFlag::NOT_PRESENT,
|
||||
cfdp::SegmentationControl segCtrl =
|
||||
@@ -23,7 +23,7 @@ class HeaderSerializer : public SerializeIF, public PduHeaderIF {
|
||||
* data field length was not properly.
|
||||
* @return
|
||||
*/
|
||||
size_t getSerializedSize() const override;
|
||||
[[nodiscard]] size_t getSerializedSize() const override;
|
||||
|
||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
Endianness streamEndianness) override;
|
||||
@@ -32,19 +32,19 @@ class HeaderSerializer : public SerializeIF, public PduHeaderIF {
|
||||
void setPduType(cfdp::PduType pduType);
|
||||
void setSegmentMetadataFlag(cfdp::SegmentMetadataFlag);
|
||||
|
||||
size_t getPduDataFieldLen() const override;
|
||||
size_t getWholePduSize() const override;
|
||||
[[nodiscard]] size_t getPduDataFieldLen() const override;
|
||||
[[nodiscard]] size_t getWholePduSize() const override;
|
||||
|
||||
cfdp::PduType getPduType() const override;
|
||||
cfdp::Direction getDirection() const override;
|
||||
cfdp::TransmissionModes getTransmissionMode() const override;
|
||||
bool getCrcFlag() const override;
|
||||
bool getLargeFileFlag() const override;
|
||||
cfdp::SegmentationControl getSegmentationControl() const override;
|
||||
cfdp::WidthInBytes getLenEntityIds() const override;
|
||||
cfdp::WidthInBytes getLenSeqNum() const override;
|
||||
cfdp::SegmentMetadataFlag getSegmentMetadataFlag() const override;
|
||||
bool hasSegmentMetadataFlag() const override;
|
||||
[[nodiscard]] cfdp::PduType getPduType() const override;
|
||||
[[nodiscard]] cfdp::Direction getDirection() const override;
|
||||
[[nodiscard]] cfdp::TransmissionModes getTransmissionMode() const override;
|
||||
[[nodiscard]] bool getCrcFlag() const override;
|
||||
[[nodiscard]] bool getLargeFileFlag() const override;
|
||||
[[nodiscard]] cfdp::SegmentationControl getSegmentationControl() const override;
|
||||
[[nodiscard]] cfdp::WidthInBytes getLenEntityIds() const override;
|
||||
[[nodiscard]] cfdp::WidthInBytes getLenSeqNum() const override;
|
||||
[[nodiscard]] cfdp::SegmentMetadataFlag getSegmentMetadataFlag() const override;
|
||||
[[nodiscard]] bool hasSegmentMetadataFlag() const override;
|
||||
void setSegmentationControl(cfdp::SegmentationControl);
|
||||
|
||||
void getSourceId(cfdp::EntityId& sourceId) const override;
|
@@ -1,128 +0,0 @@
|
||||
#include "HeaderDeserializer.h"
|
||||
|
||||
#include <fsfw/serialize/SerializeAdapter.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
HeaderDeserializer::HeaderDeserializer(const uint8_t *pduBuf, size_t maxSize)
|
||||
: rawPtr(pduBuf), maxSize(maxSize) {}
|
||||
|
||||
ReturnValue_t HeaderDeserializer::parseData() {
|
||||
if (maxSize < 7) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
return setData(const_cast<uint8_t *>(rawPtr), maxSize);
|
||||
}
|
||||
|
||||
ReturnValue_t HeaderDeserializer::setData(uint8_t *dataPtr, size_t maxSize, void *args) {
|
||||
if (dataPtr == nullptr) {
|
||||
// Allowed for now
|
||||
this->fixedHeader = nullptr;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
this->fixedHeader = reinterpret_cast<PduHeaderFixedStruct *>(const_cast<uint8_t *>(dataPtr));
|
||||
sourceIdRaw = static_cast<uint8_t *>(&fixedHeader->variableFieldsStart);
|
||||
cfdp::WidthInBytes widthEntityIds = getLenEntityIds();
|
||||
cfdp::WidthInBytes widthSeqNum = getLenSeqNum();
|
||||
seqNumRaw = static_cast<uint8_t *>(sourceIdRaw) + static_cast<uint8_t>(widthEntityIds);
|
||||
destIdRaw = static_cast<uint8_t *>(seqNumRaw) + static_cast<uint8_t>(widthSeqNum);
|
||||
this->maxSize = maxSize;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
size_t HeaderDeserializer::getHeaderSize() const {
|
||||
if (fixedHeader != nullptr) {
|
||||
return getLenEntityIds() * 2 + getLenSeqNum() + 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t HeaderDeserializer::getPduDataFieldLen() const {
|
||||
uint16_t pduFiedlLen = (fixedHeader->pduDataFieldLenH << 8) | fixedHeader->pduDataFieldLenL;
|
||||
return pduFiedlLen;
|
||||
}
|
||||
|
||||
size_t HeaderDeserializer::getWholePduSize() const {
|
||||
return getPduDataFieldLen() + getHeaderSize();
|
||||
}
|
||||
|
||||
cfdp::PduType HeaderDeserializer::getPduType() const {
|
||||
return static_cast<cfdp::PduType>((fixedHeader->firstByte >> 4) & 0x01);
|
||||
}
|
||||
|
||||
cfdp::Direction HeaderDeserializer::getDirection() const {
|
||||
return static_cast<cfdp::Direction>((fixedHeader->firstByte >> 3) & 0x01);
|
||||
}
|
||||
|
||||
cfdp::TransmissionModes HeaderDeserializer::getTransmissionMode() const {
|
||||
return static_cast<cfdp::TransmissionModes>((fixedHeader->firstByte >> 2) & 0x01);
|
||||
}
|
||||
|
||||
bool HeaderDeserializer::getCrcFlag() const { return (fixedHeader->firstByte >> 1) & 0x01; }
|
||||
|
||||
bool HeaderDeserializer::getLargeFileFlag() const { return fixedHeader->firstByte & 0x01; }
|
||||
|
||||
cfdp::SegmentationControl HeaderDeserializer::getSegmentationControl() const {
|
||||
return static_cast<cfdp::SegmentationControl>((fixedHeader->fourthByte >> 7) & 0x01);
|
||||
}
|
||||
|
||||
cfdp::WidthInBytes HeaderDeserializer::getLenEntityIds() const {
|
||||
return static_cast<cfdp::WidthInBytes>((fixedHeader->fourthByte >> 4) & 0x07);
|
||||
}
|
||||
|
||||
cfdp::WidthInBytes HeaderDeserializer::getLenSeqNum() const {
|
||||
return static_cast<cfdp::WidthInBytes>(fixedHeader->fourthByte & 0x07);
|
||||
}
|
||||
|
||||
cfdp::SegmentMetadataFlag HeaderDeserializer::getSegmentMetadataFlag() const {
|
||||
return static_cast<cfdp::SegmentMetadataFlag>((fixedHeader->fourthByte >> 3) & 0x01);
|
||||
}
|
||||
|
||||
void HeaderDeserializer::getSourceId(cfdp::EntityId &sourceId) const {
|
||||
assignVarLenField(dynamic_cast<cfdp::VarLenField *>(&sourceId), getLenEntityIds(),
|
||||
this->sourceIdRaw);
|
||||
}
|
||||
|
||||
void HeaderDeserializer::getDestId(cfdp::EntityId &destId) const {
|
||||
assignVarLenField(dynamic_cast<cfdp::VarLenField *>(&destId), getLenEntityIds(), this->destIdRaw);
|
||||
}
|
||||
|
||||
void HeaderDeserializer::getTransactionSeqNum(cfdp::TransactionSeqNum &seqNum) const {
|
||||
assignVarLenField(dynamic_cast<cfdp::VarLenField *>(&seqNum), getLenSeqNum(), this->seqNumRaw);
|
||||
}
|
||||
|
||||
void HeaderDeserializer::assignVarLenField(cfdp::VarLenField *field, cfdp::WidthInBytes width,
|
||||
void *sourcePtr) const {
|
||||
switch (width) {
|
||||
case (cfdp::WidthInBytes::ONE_BYTE): {
|
||||
uint8_t *fieldTyped = static_cast<uint8_t *>(sourcePtr);
|
||||
field->setValue(width, *fieldTyped);
|
||||
break;
|
||||
}
|
||||
case (cfdp::WidthInBytes::TWO_BYTES): {
|
||||
uint16_t fieldTyped = 0;
|
||||
size_t deserSize = 0;
|
||||
SerializeAdapter::deSerialize(&fieldTyped, static_cast<uint8_t *>(sourcePtr), &deserSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
field->setValue(width, fieldTyped);
|
||||
break;
|
||||
}
|
||||
case (cfdp::WidthInBytes::FOUR_BYTES): {
|
||||
uint32_t fieldTyped = 0;
|
||||
size_t deserSize = 0;
|
||||
SerializeAdapter::deSerialize(&fieldTyped, static_cast<uint8_t *>(sourcePtr), &deserSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
field->setValue(width, fieldTyped);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t HeaderDeserializer::getMaxSize() const { return maxSize; }
|
||||
|
||||
bool HeaderDeserializer::hasSegmentMetadataFlag() const {
|
||||
if (this->getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::PRESENT) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
151
src/fsfw/cfdp/pdu/HeaderReader.cpp
Normal file
151
src/fsfw/cfdp/pdu/HeaderReader.cpp
Normal file
@@ -0,0 +1,151 @@
|
||||
#include "HeaderReader.h"
|
||||
|
||||
#include <fsfw/serialize/SerializeAdapter.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
HeaderReader::HeaderReader(const uint8_t *pduBuf, size_t maxSize) { setData(pduBuf, maxSize); }
|
||||
|
||||
ReturnValue_t HeaderReader::parseData() {
|
||||
if (pointers.rawPtr == nullptr) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
if (maxSize < 7) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
pointers.fixedHeader =
|
||||
reinterpret_cast<PduHeaderFixedStruct *>(const_cast<uint8_t *>(pointers.rawPtr));
|
||||
sourceIdRaw = static_cast<uint8_t *>(&pointers.fixedHeader->variableFieldsStart);
|
||||
cfdp::WidthInBytes widthEntityIds = getLenEntityIds();
|
||||
cfdp::WidthInBytes widthSeqNum = getLenSeqNum();
|
||||
seqNumRaw = static_cast<uint8_t *>(sourceIdRaw) + static_cast<uint8_t>(widthEntityIds);
|
||||
destIdRaw = static_cast<uint8_t *>(seqNumRaw) + static_cast<uint8_t>(widthSeqNum);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t HeaderReader::setData(uint8_t *dataPtr, size_t maxSize_, void *args) {
|
||||
if (dataPtr == nullptr) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
if (maxSize_ < 7) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
pointers.rawPtr = dataPtr;
|
||||
maxSize = maxSize_;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
size_t HeaderReader::getHeaderSize() const {
|
||||
if (pointers.fixedHeader != nullptr) {
|
||||
return getLenEntityIds() * 2 + getLenSeqNum() + 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t HeaderReader::getPduDataFieldLen() const {
|
||||
return (pointers.fixedHeader->pduDataFieldLenH << 8) | pointers.fixedHeader->pduDataFieldLenL;
|
||||
}
|
||||
|
||||
size_t HeaderReader::getWholePduSize() const {
|
||||
return getPduDataFieldLen() + HeaderReader::getHeaderSize();
|
||||
}
|
||||
|
||||
cfdp::PduType HeaderReader::getPduType() const {
|
||||
return static_cast<cfdp::PduType>((pointers.fixedHeader->firstByte >> 4) & 0x01);
|
||||
}
|
||||
|
||||
cfdp::Direction HeaderReader::getDirection() const {
|
||||
return static_cast<cfdp::Direction>((pointers.fixedHeader->firstByte >> 3) & 0x01);
|
||||
}
|
||||
|
||||
cfdp::TransmissionModes HeaderReader::getTransmissionMode() const {
|
||||
return static_cast<cfdp::TransmissionModes>((pointers.fixedHeader->firstByte >> 2) & 0x01);
|
||||
}
|
||||
|
||||
bool HeaderReader::getCrcFlag() const { return (pointers.fixedHeader->firstByte >> 1) & 0x01; }
|
||||
|
||||
bool HeaderReader::getLargeFileFlag() const { return pointers.fixedHeader->firstByte & 0x01; }
|
||||
|
||||
cfdp::SegmentationControl HeaderReader::getSegmentationControl() const {
|
||||
return static_cast<cfdp::SegmentationControl>((pointers.fixedHeader->fourthByte >> 7) & 0x01);
|
||||
}
|
||||
|
||||
cfdp::WidthInBytes HeaderReader::getLenEntityIds() const {
|
||||
return static_cast<cfdp::WidthInBytes>((pointers.fixedHeader->fourthByte >> 4) & 0x07);
|
||||
}
|
||||
|
||||
cfdp::WidthInBytes HeaderReader::getLenSeqNum() const {
|
||||
return static_cast<cfdp::WidthInBytes>(pointers.fixedHeader->fourthByte & 0x07);
|
||||
}
|
||||
|
||||
cfdp::SegmentMetadataFlag HeaderReader::getSegmentMetadataFlag() const {
|
||||
return static_cast<cfdp::SegmentMetadataFlag>((pointers.fixedHeader->fourthByte >> 3) & 0x01);
|
||||
}
|
||||
|
||||
void HeaderReader::getSourceId(cfdp::EntityId &sourceId) const {
|
||||
assignVarLenField(dynamic_cast<cfdp::VarLenField *>(&sourceId), getLenEntityIds(),
|
||||
this->sourceIdRaw);
|
||||
}
|
||||
|
||||
void HeaderReader::getDestId(cfdp::EntityId &destId) const {
|
||||
assignVarLenField(dynamic_cast<cfdp::VarLenField *>(&destId), getLenEntityIds(), this->destIdRaw);
|
||||
}
|
||||
|
||||
void HeaderReader::getTransactionSeqNum(cfdp::TransactionSeqNum &seqNum) const {
|
||||
assignVarLenField(dynamic_cast<cfdp::VarLenField *>(&seqNum), getLenSeqNum(), this->seqNumRaw);
|
||||
}
|
||||
|
||||
void HeaderReader::assignVarLenField(cfdp::VarLenField *field, cfdp::WidthInBytes width,
|
||||
void *sourcePtr) const {
|
||||
switch (width) {
|
||||
case (cfdp::WidthInBytes::ONE_BYTE): {
|
||||
auto *fieldTyped = static_cast<uint8_t *>(sourcePtr);
|
||||
field->setValue(width, *fieldTyped);
|
||||
break;
|
||||
}
|
||||
case (cfdp::WidthInBytes::TWO_BYTES): {
|
||||
uint16_t fieldTyped = 0;
|
||||
size_t deserSize = 0;
|
||||
SerializeAdapter::deSerialize(&fieldTyped, static_cast<uint8_t *>(sourcePtr), &deserSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
field->setValue(width, fieldTyped);
|
||||
break;
|
||||
}
|
||||
case (cfdp::WidthInBytes::FOUR_BYTES): {
|
||||
uint32_t fieldTyped = 0;
|
||||
size_t deserSize = 0;
|
||||
SerializeAdapter::deSerialize(&fieldTyped, static_cast<uint8_t *>(sourcePtr), &deserSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
field->setValue(width, fieldTyped);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t HeaderReader::getMaxSize() const { return maxSize; }
|
||||
|
||||
bool HeaderReader::hasSegmentMetadataFlag() const {
|
||||
if (this->getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::PRESENT) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ReturnValue_t HeaderReader::setData(const uint8_t *dataPtr, size_t maxSize_) {
|
||||
return setData(const_cast<uint8_t *>(dataPtr), maxSize_, nullptr);
|
||||
}
|
||||
bool HeaderReader::isNull() const {
|
||||
return pointers.rawPtr == nullptr or pointers.fixedHeader == nullptr;
|
||||
}
|
||||
|
||||
HeaderReader::operator bool() const { return not isNull(); }
|
||||
|
||||
void HeaderReader::fillConfig(PduConfig &cfg) const {
|
||||
cfg.largeFile = getLargeFileFlag();
|
||||
cfg.crcFlag = getCrcFlag();
|
||||
cfg.mode = getTransmissionMode();
|
||||
cfg.direction = getDirection();
|
||||
getTransactionSeqNum(cfg.seqNum);
|
||||
getSourceId(cfg.sourceId);
|
||||
getDestId(cfg.destId);
|
||||
}
|
@@ -23,45 +23,57 @@ struct PduHeaderFixedStruct {
|
||||
* This is a zero-copy implementation and #parseData needs to be called to ensure the data is
|
||||
* valid.
|
||||
*/
|
||||
class HeaderDeserializer : public RedirectableDataPointerIF, public PduHeaderIF {
|
||||
class HeaderReader : public RedirectableDataPointerIF, public PduHeaderIF {
|
||||
public:
|
||||
HeaderReader() = default;
|
||||
/**
|
||||
* Initialize a PDU header from raw data. This is a zero-copy implementation and #parseData
|
||||
* needs to be called to ensure the data is valid
|
||||
* @param pduBuf
|
||||
* @param maxSize
|
||||
*/
|
||||
HeaderDeserializer(const uint8_t* pduBuf, size_t maxSize);
|
||||
HeaderReader(const uint8_t* pduBuf, size_t maxSize);
|
||||
|
||||
/**
|
||||
* This needs to be called before accessing the PDU fields to avoid segmentation faults.
|
||||
* @return
|
||||
* - RETURN_OK on parse success
|
||||
* - RETURN_FAILED Invalid raw data
|
||||
* - returnvalue::OK on parse success
|
||||
* - returnvalue::FAILED Invalid raw data
|
||||
* - SerializeIF::BUFFER_TOO_SHORT if buffer is shorter than expected
|
||||
*/
|
||||
virtual ReturnValue_t parseData();
|
||||
size_t getHeaderSize() const;
|
||||
explicit operator bool() const;
|
||||
[[nodiscard]] bool isNull() const;
|
||||
|
||||
size_t getPduDataFieldLen() const override;
|
||||
size_t getWholePduSize() const override;
|
||||
/**
|
||||
* Fill the provided PDU configuration from the fields detected by this reader.
|
||||
* @param cfg
|
||||
*/
|
||||
void fillConfig(PduConfig& cfg) const;
|
||||
|
||||
cfdp::PduType getPduType() const override;
|
||||
cfdp::Direction getDirection() const override;
|
||||
cfdp::TransmissionModes getTransmissionMode() const override;
|
||||
bool getCrcFlag() const override;
|
||||
bool getLargeFileFlag() const override;
|
||||
cfdp::SegmentationControl getSegmentationControl() const override;
|
||||
cfdp::WidthInBytes getLenEntityIds() const override;
|
||||
cfdp::WidthInBytes getLenSeqNum() const override;
|
||||
cfdp::SegmentMetadataFlag getSegmentMetadataFlag() const override;
|
||||
bool hasSegmentMetadataFlag() const override;
|
||||
[[nodiscard]] virtual size_t getHeaderSize() const;
|
||||
|
||||
[[nodiscard]] size_t getPduDataFieldLen() const override;
|
||||
[[nodiscard]] size_t getWholePduSize() const override;
|
||||
|
||||
[[nodiscard]] cfdp::PduType getPduType() const override;
|
||||
[[nodiscard]] cfdp::Direction getDirection() const override;
|
||||
[[nodiscard]] cfdp::TransmissionModes getTransmissionMode() const override;
|
||||
[[nodiscard]] bool getCrcFlag() const override;
|
||||
[[nodiscard]] bool getLargeFileFlag() const override;
|
||||
[[nodiscard]] cfdp::SegmentationControl getSegmentationControl() const override;
|
||||
[[nodiscard]] cfdp::WidthInBytes getLenEntityIds() const override;
|
||||
[[nodiscard]] cfdp::WidthInBytes getLenSeqNum() const override;
|
||||
[[nodiscard]] cfdp::SegmentMetadataFlag getSegmentMetadataFlag() const override;
|
||||
[[nodiscard]] bool hasSegmentMetadataFlag() const override;
|
||||
|
||||
void getSourceId(cfdp::EntityId& sourceId) const override;
|
||||
void getDestId(cfdp::EntityId& destId) const override;
|
||||
void getTransactionSeqNum(cfdp::TransactionSeqNum& seqNum) const override;
|
||||
|
||||
ReturnValue_t deserResult = HasReturnvaluesIF::RETURN_OK;
|
||||
ReturnValue_t deserResult = returnvalue::OK;
|
||||
|
||||
[[nodiscard]] size_t getMaxSize() const;
|
||||
|
||||
/**
|
||||
* Can also be used to reset the pointer to a nullptr, but the getter functions will not
|
||||
@@ -71,16 +83,27 @@ class HeaderDeserializer : public RedirectableDataPointerIF, public PduHeaderIF
|
||||
* @param args
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t setData(uint8_t* dataPtr, size_t maxSize, void* args = nullptr) override;
|
||||
|
||||
size_t getMaxSize() const;
|
||||
ReturnValue_t setData(const uint8_t* dataPtr, size_t maxSize);
|
||||
|
||||
protected:
|
||||
PduHeaderFixedStruct* fixedHeader = nullptr;
|
||||
const uint8_t* rawPtr = nullptr;
|
||||
struct Pointers {
|
||||
PduHeaderFixedStruct* fixedHeader = nullptr;
|
||||
const uint8_t* rawPtr = nullptr;
|
||||
};
|
||||
|
||||
Pointers pointers;
|
||||
size_t maxSize = 0;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Can also be used to reset the pointer to a nullptr, but the getter functions will not
|
||||
* perform nullptr checks!
|
||||
* @param dataPtr
|
||||
* @param maxSize
|
||||
* @param args
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t setData(uint8_t* dataPtr, size_t maxSize, void* args) override;
|
||||
void assignVarLenField(cfdp::VarLenField* field, cfdp::WidthInBytes width, void* sourcePtr) const;
|
||||
void* sourceIdRaw = nullptr;
|
||||
void* seqNumRaw = nullptr;
|
@@ -1,117 +0,0 @@
|
||||
#include "HeaderSerializer.h"
|
||||
|
||||
#include "HeaderDeserializer.h"
|
||||
|
||||
HeaderSerializer::HeaderSerializer(PduConfig &pduConf, cfdp::PduType pduType,
|
||||
size_t initPduDataFieldLen,
|
||||
cfdp::SegmentMetadataFlag segmentMetadataFlag,
|
||||
cfdp::SegmentationControl segCtrl)
|
||||
: pduType(pduType),
|
||||
segmentMetadataFlag(segmentMetadataFlag),
|
||||
segmentationCtrl(segCtrl),
|
||||
pduDataFieldLen(initPduDataFieldLen),
|
||||
pduConf(pduConf) {}
|
||||
|
||||
ReturnValue_t HeaderSerializer::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
if (buffer == nullptr or size == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
if (maxSize < this->getSerializedSize()) {
|
||||
return BUFFER_TOO_SHORT;
|
||||
}
|
||||
**buffer = cfdp::VERSION_BITS | this->pduType << 4 | pduConf.direction << 3 | pduConf.mode << 2 |
|
||||
pduConf.crcFlag << 1 | pduConf.largeFile;
|
||||
*buffer += 1;
|
||||
**buffer = (pduDataFieldLen & 0xff00) >> 8;
|
||||
*buffer += 1;
|
||||
**buffer = pduDataFieldLen & 0x00ff;
|
||||
*buffer += 1;
|
||||
**buffer = segmentationCtrl << 7 | pduConf.sourceId.getWidth() << 4 | segmentMetadataFlag << 3 |
|
||||
pduConf.seqNum.getWidth();
|
||||
*buffer += 1;
|
||||
*size += 4;
|
||||
ReturnValue_t result = pduConf.sourceId.serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = pduConf.seqNum.serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = pduConf.destId.serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
size_t HeaderSerializer::getSerializedSize() const {
|
||||
size_t shit = pduConf.seqNum.getWidth() + pduConf.sourceId.getWidth() * 2 + 4;
|
||||
return shit;
|
||||
}
|
||||
|
||||
ReturnValue_t HeaderSerializer::deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) {
|
||||
// We could implement this, but I prefer dedicated classes
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
size_t HeaderSerializer::getWholePduSize() const {
|
||||
// Return size of header plus the PDU data field length
|
||||
return pduDataFieldLen + HeaderSerializer::getSerializedSize();
|
||||
}
|
||||
|
||||
size_t HeaderSerializer::getPduDataFieldLen() const { return pduDataFieldLen; }
|
||||
|
||||
void HeaderSerializer::setPduDataFieldLen(size_t pduDataFieldLen) {
|
||||
this->pduDataFieldLen = pduDataFieldLen;
|
||||
}
|
||||
|
||||
void HeaderSerializer::setPduType(cfdp::PduType pduType) { this->pduType = pduType; }
|
||||
|
||||
void HeaderSerializer::setSegmentMetadataFlag(cfdp::SegmentMetadataFlag segmentMetadataFlag) {
|
||||
this->segmentMetadataFlag = segmentMetadataFlag;
|
||||
}
|
||||
|
||||
cfdp::PduType HeaderSerializer::getPduType() const { return pduType; }
|
||||
|
||||
cfdp::Direction HeaderSerializer::getDirection() const { return pduConf.direction; }
|
||||
|
||||
cfdp::TransmissionModes HeaderSerializer::getTransmissionMode() const { return pduConf.mode; }
|
||||
|
||||
bool HeaderSerializer::getCrcFlag() const { return pduConf.crcFlag; }
|
||||
|
||||
bool HeaderSerializer::getLargeFileFlag() const { return pduConf.largeFile; }
|
||||
|
||||
cfdp::SegmentationControl HeaderSerializer::getSegmentationControl() const {
|
||||
return segmentationCtrl;
|
||||
}
|
||||
|
||||
cfdp::WidthInBytes HeaderSerializer::getLenEntityIds() const { return pduConf.sourceId.getWidth(); }
|
||||
|
||||
cfdp::WidthInBytes HeaderSerializer::getLenSeqNum() const { return pduConf.seqNum.getWidth(); }
|
||||
|
||||
cfdp::SegmentMetadataFlag HeaderSerializer::getSegmentMetadataFlag() const {
|
||||
return segmentMetadataFlag;
|
||||
}
|
||||
|
||||
void HeaderSerializer::getSourceId(cfdp::EntityId &sourceId) const { sourceId = pduConf.sourceId; }
|
||||
|
||||
void HeaderSerializer::getDestId(cfdp::EntityId &destId) const { destId = pduConf.destId; }
|
||||
|
||||
void HeaderSerializer::setSegmentationControl(cfdp::SegmentationControl segmentationControl) {
|
||||
this->segmentationCtrl = segmentationControl;
|
||||
}
|
||||
|
||||
void HeaderSerializer::getTransactionSeqNum(cfdp::TransactionSeqNum &seqNum) const {
|
||||
seqNum = pduConf.seqNum;
|
||||
}
|
||||
|
||||
bool HeaderSerializer::hasSegmentMetadataFlag() const {
|
||||
if (this->segmentMetadataFlag == cfdp::SegmentMetadataFlag::PRESENT) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
@@ -2,16 +2,16 @@
|
||||
|
||||
KeepAlivePduDeserializer::KeepAlivePduDeserializer(const uint8_t* pduBuf, size_t maxSize,
|
||||
cfdp::FileSize& progress)
|
||||
: FileDirectiveDeserializer(pduBuf, maxSize), progress(progress) {}
|
||||
: FileDirectiveReader(pduBuf, maxSize), progress(progress) {}
|
||||
|
||||
ReturnValue_t KeepAlivePduDeserializer::parseData() {
|
||||
ReturnValue_t result = FileDirectiveDeserializer::parseData();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
ReturnValue_t result = FileDirectiveReader::parseData();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
size_t currentIdx = FileDirectiveDeserializer::getHeaderSize();
|
||||
size_t remLen = FileDirectiveDeserializer::getWholePduSize() - currentIdx;
|
||||
const uint8_t* buffer = rawPtr + currentIdx;
|
||||
size_t currentIdx = FileDirectiveReader::getHeaderSize();
|
||||
size_t remLen = FileDirectiveReader::getWholePduSize() - currentIdx;
|
||||
const uint8_t* buffer = pointers.rawPtr + currentIdx;
|
||||
return progress.deSerialize(&buffer, &remLen, getEndianness());
|
||||
}
|
||||
|
||||
|
@@ -2,9 +2,9 @@
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_KEEPALIVEPDUDESERIALIZER_H_
|
||||
|
||||
#include "fsfw/cfdp/FileSize.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveDeserializer.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveReader.h"
|
||||
|
||||
class KeepAlivePduDeserializer : public FileDirectiveDeserializer {
|
||||
class KeepAlivePduDeserializer : public FileDirectiveReader {
|
||||
public:
|
||||
KeepAlivePduDeserializer(const uint8_t* pduBuf, size_t maxSize, cfdp::FileSize& progress);
|
||||
|
||||
|
@@ -1,12 +1,12 @@
|
||||
#include "KeepAlivePduSerializer.h"
|
||||
|
||||
KeepAlivePduSerializer::KeepAlivePduSerializer(PduConfig &conf, cfdp::FileSize &progress)
|
||||
: FileDirectiveSerializer(conf, cfdp::FileDirectives::KEEP_ALIVE, 4), progress(progress) {
|
||||
: FileDirectiveCreator(conf, cfdp::FileDirectives::KEEP_ALIVE, 4), progress(progress) {
|
||||
updateDirectiveFieldLen();
|
||||
}
|
||||
|
||||
size_t KeepAlivePduSerializer::getSerializedSize() const {
|
||||
return FileDirectiveSerializer::getWholePduSize();
|
||||
return FileDirectiveCreator::getWholePduSize();
|
||||
}
|
||||
|
||||
void KeepAlivePduSerializer::updateDirectiveFieldLen() {
|
||||
@@ -17,9 +17,8 @@ void KeepAlivePduSerializer::updateDirectiveFieldLen() {
|
||||
|
||||
ReturnValue_t KeepAlivePduSerializer::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result =
|
||||
FileDirectiveSerializer::serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
ReturnValue_t result = FileDirectiveCreator::serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
return progress.serialize(this->getLargeFileFlag(), buffer, size, maxSize, streamEndianness);
|
||||
|
@@ -2,9 +2,9 @@
|
||||
#define FSFW_SRC_FSFW_CFDP_PDU_KEEPALIVEPDUSERIALIZER_H_
|
||||
|
||||
#include "fsfw/cfdp/FileSize.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveSerializer.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveCreator.h"
|
||||
|
||||
class KeepAlivePduSerializer : public FileDirectiveSerializer {
|
||||
class KeepAlivePduSerializer : public FileDirectiveCreator {
|
||||
public:
|
||||
KeepAlivePduSerializer(PduConfig& conf, cfdp::FileSize& progress);
|
||||
|
||||
|
@@ -1,54 +1,57 @@
|
||||
#include "MetadataInfo.h"
|
||||
|
||||
MetadataInfo::MetadataInfo(bool closureRequested, cfdp::ChecksumType checksumType,
|
||||
cfdp::FileSize& fileSize, cfdp::Lv& sourceFileName,
|
||||
cfdp::Lv& destFileName)
|
||||
: closureRequested(closureRequested),
|
||||
checksumType(checksumType),
|
||||
fileSize(fileSize),
|
||||
sourceFileName(sourceFileName),
|
||||
destFileName(destFileName) {}
|
||||
cfdp::FileSize& fileSize, cfdp::StringLv& sourceFileName,
|
||||
cfdp::StringLv& destFileName)
|
||||
: MetadataInfo(fileSize, sourceFileName, destFileName) {
|
||||
this->closureRequested = closureRequested;
|
||||
this->checksumType = checksumType;
|
||||
}
|
||||
|
||||
void MetadataInfo::setOptionsArray(cfdp::Tlv** optionsArray, size_t* optionsLen,
|
||||
size_t* maxOptionsLen) {
|
||||
this->optionsArray = optionsArray;
|
||||
if (maxOptionsLen != nullptr) {
|
||||
this->maxOptionsLen = *maxOptionsLen;
|
||||
MetadataInfo::MetadataInfo(cfdp::FileSize& fileSize, cfdp::StringLv& sourceFileName,
|
||||
cfdp::StringLv& destFileName)
|
||||
: fileSize(fileSize), sourceFileName(sourceFileName), destFileName(destFileName) {}
|
||||
|
||||
void MetadataInfo::setOptionsArray(cfdp::Tlv** optionsArray_, std::optional<size_t> optionsLen_,
|
||||
std::optional<size_t> maxOptionsLen_) {
|
||||
this->optionsArray = optionsArray_;
|
||||
if (maxOptionsLen_) {
|
||||
this->maxOptionsLen = maxOptionsLen_.value();
|
||||
}
|
||||
if (optionsLen != nullptr) {
|
||||
this->optionsLen = *optionsLen;
|
||||
if (optionsLen_) {
|
||||
this->optionsLen = optionsLen_.value();
|
||||
}
|
||||
}
|
||||
|
||||
cfdp::ChecksumType MetadataInfo::getChecksumType() const { return checksumType; }
|
||||
|
||||
void MetadataInfo::setChecksumType(cfdp::ChecksumType checksumType) {
|
||||
this->checksumType = checksumType;
|
||||
void MetadataInfo::setChecksumType(cfdp::ChecksumType checksumType_) {
|
||||
checksumType = checksumType_;
|
||||
}
|
||||
|
||||
bool MetadataInfo::isClosureRequested() const { return closureRequested; }
|
||||
|
||||
void MetadataInfo::setClosureRequested(bool closureRequested) {
|
||||
this->closureRequested = closureRequested;
|
||||
void MetadataInfo::setClosureRequested(bool closureRequested_) {
|
||||
closureRequested = closureRequested_;
|
||||
}
|
||||
|
||||
cfdp::Lv& MetadataInfo::getDestFileName() { return destFileName; }
|
||||
cfdp::StringLv& MetadataInfo::getDestFileName() { return destFileName; }
|
||||
|
||||
cfdp::FileSize& MetadataInfo::getFileSize() { return fileSize; }
|
||||
|
||||
ReturnValue_t MetadataInfo::getOptions(cfdp::Tlv*** optionsArray, size_t* optionsLen,
|
||||
ReturnValue_t MetadataInfo::getOptions(cfdp::Tlv*** optionsArray_, size_t* optionsLen_,
|
||||
size_t* maxOptsLen) {
|
||||
if (optionsArray == nullptr or this->optionsArray == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
if (optionsArray_ == nullptr or optionsArray == nullptr) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
*optionsArray = this->optionsArray;
|
||||
if (optionsLen != nullptr) {
|
||||
*optionsLen = this->optionsLen;
|
||||
*optionsArray_ = optionsArray;
|
||||
if (optionsLen_ != nullptr) {
|
||||
*optionsLen_ = this->optionsLen;
|
||||
}
|
||||
if (maxOptsLen != nullptr) {
|
||||
*maxOptsLen = this->maxOptionsLen;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
bool MetadataInfo::hasOptions() const {
|
||||
@@ -81,18 +84,20 @@ size_t MetadataInfo::getSerializedSize(bool fssLarge) {
|
||||
return size;
|
||||
}
|
||||
|
||||
void MetadataInfo::setDestFileName(cfdp::Lv& destFileName) { this->destFileName = destFileName; }
|
||||
void MetadataInfo::setDestFileName(cfdp::StringLv& destFileName_) {
|
||||
this->destFileName = destFileName_;
|
||||
}
|
||||
|
||||
void MetadataInfo::setSourceFileName(cfdp::Lv& sourceFileName) {
|
||||
this->sourceFileName = sourceFileName;
|
||||
void MetadataInfo::setSourceFileName(cfdp::StringLv& sourceFileName_) {
|
||||
this->sourceFileName = sourceFileName_;
|
||||
}
|
||||
|
||||
size_t MetadataInfo::getMaxOptionsLen() const { return maxOptionsLen; }
|
||||
|
||||
void MetadataInfo::setMaxOptionsLen(size_t maxOptionsLen) { this->maxOptionsLen = maxOptionsLen; }
|
||||
void MetadataInfo::setMaxOptionsLen(size_t maxOptionsLen_) { this->maxOptionsLen = maxOptionsLen_; }
|
||||
|
||||
size_t MetadataInfo::getOptionsLen() const { return optionsLen; }
|
||||
|
||||
void MetadataInfo::setOptionsLen(size_t optionsLen) { this->optionsLen = optionsLen; }
|
||||
void MetadataInfo::setOptionsLen(size_t optionsLen_) { this->optionsLen = optionsLen_; }
|
||||
|
||||
cfdp::Lv& MetadataInfo::getSourceFileName() { return sourceFileName; }
|
||||
cfdp::StringLv& MetadataInfo::getSourceFileName() { return sourceFileName; }
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user