Compare commits

..

21 Commits

Author SHA1 Message Date
7426e10f82 clocks suck a little less 2023-01-26 11:33:40 +01:00
uli
123c81777a clocks suck 2023-01-26 00:01:40 +01:00
6d85fa155e cleaning up unittest build 2023-01-20 16:05:04 +01:00
e6af6200ae updating CI 2023-01-19 17:32:23 +01:00
5ca3e83934 working on rtems CI build 2023-01-19 16:46:43 +01:00
6adabb059a fixing rtems cmake config 2023-01-19 16:27:10 +01:00
5d0a5cd201 exiting qemu nonzero when tests fail 2023-01-19 14:47:40 +01:00
adb8483bb0 unittests for rtems working 2023-01-19 14:24:33 +01:00
fdfdce2fb0 compiling, crashing when run 2023-01-18 00:25:25 +01:00
90efb132d0 fixing rebase error 2023-01-16 12:41:23 +01:00
fe9804d922 format 2023-01-16 12:35:14 +01:00
a0eae66c35 checking if this helps docker build 2023-01-16 12:32:16 +01:00
e131480d5f two errors found by valgrind 2023-01-16 12:32:15 +01:00
90bafbb6de typos in Jenkinsfile 2023-01-16 12:31:54 +01:00
47d85fb61c finished freertos unittests, valgrind not happy yet 2023-01-16 12:31:53 +01:00
39dad5f45b unittests running but failing 2023-01-16 12:31:53 +01:00
a993c4e0d4 adding linux ci and fixing problems 2023-01-16 12:31:53 +01:00
fe9cc20d00 make get const 2023-01-16 12:31:53 +01:00
552a12a6ad updates for source sequence counter 2023-01-16 12:31:47 +01:00
13639feec6 FreeRTOS unittests building (but not running) 2023-01-16 12:30:36 +01:00
654de0f586 WIP 2023-01-16 12:30:36 +01:00
403 changed files with 3407 additions and 8018 deletions

View File

@@ -4,5 +4,4 @@ IndentWidth: 2
---
Language: Cpp
ColumnLimit: 100
ReflowComments: true
---

4
.gitignore vendored
View File

@@ -1,8 +1,8 @@
# PyCharm and CLion
.idea/*
/.idea/*
!/.idea/runConfigurations
!/.idea/cmake.xml
# !/.idea/codeStyles
!/.idea/codeStyles
# Eclipse
.cproject

8
.idea/cmake.xml generated
View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CMakeSharedSettings">
<configurations>
<configuration PROFILE_NAME="Debug Test" ENABLED="true" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DFSFW_OSAL=host -DFSFW_BUILD_TESTS=ON" NO_GENERATOR="true" />
</configurations>
</component>
</project>

14
.idea/codeStyles/Project.xml generated Normal file
View File

@@ -0,0 +1,14 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<clangFormatSettings>
<option name="ENABLED" value="true" />
</clangFormatSettings>
<codeStyleSettings language="CMake">
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="0" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
</code_scheme>
</component>

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View File

@@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

View File

@@ -8,90 +8,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
# [unreleased]
## Fixes
- FreshDeviceHandlerBase did not initialize the fdirInstance
- The `PusTmCreator` API only accepted 255 bytes of source data. It can now accept source
data with a size limited only by the size of `size_t`.
- Important bugfix in CFDP PDU header format: The entity length field and the transaction sequence
number fields stored the actual length of the field instead of the length minus 1 like specified
in the CFDP standard.
- PUS Health Service: Size check for set health command.
Perform operation completion for announce health command.
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/746
- Linux OSAL `getUptime` fix: Check validity of `/proc/uptime` file before reading uptime.
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/745
- Small tweak for version getter
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/744
## Added
- add CFDP subsystem ID
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/742
- `PusTmZcWriter` now exposes API to set message counter field.
- Relative timeshift in the PUS time service.
- CFDP support for PDU checksums
## Changed
- Improved File System Abstraction to be more in line with normal filesystems.
- CFDP implementation was improved, has now even less dependencies on other FSFW components
and allows one inserted packet per state machine call.
- The PUS time service now dumps the time before setting a new time and after having set the
time.
- HK generation is now countdown based.
- Bump ETL version to 20.35.14
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/748
- Renamed `PCDU_2` subsystem ID to `POWER_SWITCH_IF`.
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/743
- Add new `PowerSwitchIF::SWITCH_UNKNOWN` returnvalue.
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/743
- Assert that `FixedArrayList` is larger than 0 at compile time.
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/740
- Health functions are virtual now.
- PUS Service Base request queue depth and maximum number of handled packets per cycle is now
configurable.
## Added
- `EventManager`: Add function to print all listeners.
## Changed
- `EventManager`: Queue depth is configurable now
# [v6.0.0] 2023-02-10
# [v6.0.0]
## Fixes
- Mode Service: Add allowed subservice
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/739
- `CService200ModeManagement`: Various bugfixes which lead to now execution complete being generated
on mode announcements, duplicate mode reply generated on announce commands, and the mode read
subservice not working properly.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/736
- Memory leak fixes for the TCP/IP TMTC bridge.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/737
- `Service9TimeManagement`: Fix the time dump at the `SET_TIME` subservice: Include clock timeval
seconds instead of uptime.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/726
- HAL MGM3100 Handler: Use axis specific gain/scaling factors. Previously,
only the X scaling factor was used.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/724
- HAL MGM3100 Handler: Z value was previously calculated with bytes of the X value.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/733
- DHB `setNormalDatapoolEntriesInvalid`: The default implementation did not set the validity
to false correctly because the `read` and `write` calls were missing.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/728
- PUS TMTC creator module: Sequence flags were set to continuation segment (0b00) instead
of the correct unsegmented flags (0b11) as specified in the standard.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/727
- TC Scheduler Service 11: Add size and CRC check for contained TC.
Bug: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/issues/719
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/720
- Only delete health table entry in `HealthHelper` destructor if
health table was set.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/710
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/710/files
- I2C Bugfixes: Do not keep iterator as member and fix some incorrect handling with the iterator.
Also properly reset the reply size for successfull transfers and erroneous transfers.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/700
@@ -101,84 +25,22 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- `TcpTmTcServer.cpp`: The server was actually not able to handle
CCSDS packets which were clumped together. This has been fixed now.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/673
- `CServiceHealthCommanding`: Add announce all health info implementation
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/725
- various fixes related to linux Unittests and memory leaks
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/715
- small fix to allow teardown handling
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/713
- fix compiler warning for fixed array list copy ctor
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/704
- missing include
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/703
- defaultconfig did not build anymore
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/702
- hotfix
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/699
- small fix for helper
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/698
- missing retval conv
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/697
- DHB Countdown Bug
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/693
- doc corrections
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/687
- better error printout
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/686
- include correction
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/683
- better warning for missing include paths
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/676
- Service 11 regression
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/670
## Added
- `CServiceHealthCommanding`: Add announce all health info implementation
PR: https://egit.irs.uni-stuttgart.de/eive/fsfw/pulls/122
- Empty constructor for `CdsShortTimeStamper` which does not do an object manager registration.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/730
- `Service9TimeManagement`: Add `DUMP_TIME` (129) subservice.
- `TcpTmTcServer`: Allow setting the `SO_REUSEADDR` and `SO_REUSEPORT`
option on the TCP server. CTOR prototype has changed and expects an explicit
TCP configuration struct to be passed.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/722
- `DleParser` helper class to parse DLE encoded packets from a byte stream.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/711
- `UioMapper` is able to resolve symlinks now.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/709
- Add new `UnsignedByteField` class
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/660
- publish documentation for development and master branch
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/681
- Add Linux HAL options
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/663
- Expand SerializeIF
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/656
- PUS Service 11: Additional Safety Check
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/666
- improvements for auto-formatter script
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/665
- provide a weak print char impl
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/674
## Removed
- now that doc server is up, remove markdown files
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/688
- remove bsp specific code
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/679
## Changes
- `CService201HealthCommanding` renamed to `CServiceHealthCommanding`,
service ID customizable now. `CServiceHealthCommanding` expects configuration struct
`HealthServiceCfg` now
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/725
- `AcceptsTelemetryIF`: `getReportReceptionQueue` is const now
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/712
- Moved some container returnvalues to dedicated header and namespace
so they can be used without template specification.
to they can be used without template specification.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/707
- Remove default secondary header argument for
`uint16_t getTcSpacePacketIdFromApid(uint16_t apid, bool secondaryHeaderFlag)` and
@@ -208,41 +70,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- `DeviceHandlerBase`: New signature of `handleDeviceTm` which expects
a `const SerializeIF&` and additional helper variant which expects `const uint8_t*`
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/671
- Move some generic `StorageManagerIF` implementations from `LocalPool` to
interface itself so it can be re-used more easily. Also add new
abstract function `bool hasDataAtId(store_address_t storeId) const`.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/685
- Improvements for `AcceptsTelemetryIF` and `AcceptsTelecommandsIF`:
- Make functions `const` where it makes sense
- Add `const char* getName const` abstract function
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/684
- Generic TMTC Bridge Update
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/734
- comment tweak to event parser can read everything
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/732
- CMakeLists file updates
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/731
- improve srv20 error messages
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/723
- I2C Linux: remove duplicate printout
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/718
- printout handling improvements
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/717
- vec getter, reset for content
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/716
- updates for source sequence counter
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/714
- SP reader getPacketData is const now
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/708
- refactoring of serial drivers for linux
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/705
- Local Pool Update Remove Add Data Ignore Fault Argument
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/701
- Switch to new documentation server
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/694
- Windows Tweaks
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/691
- Refactor Local Pool API
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/667
- group MGM data in local pool vectors
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/664
- Move some generic `StorageManagerIF` implementations from `LocalPool` to
interface itself so it can be re-used more easily. Also add new
abstract function `bool hasDataAtId(store_address_t storeId) const`.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/685
## CFDP
@@ -262,7 +101,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
implementation without an extra component
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/682
# [v5.0.0] 2022-07-25
# [v5.0.0] 25.07.2022
## Changes

View File

@@ -13,7 +13,7 @@ list(APPEND CMAKE_MODULE_PATH
# Version file handling #
# ##############################################################################
set(FSFW_VERSION_IF_GIT_FAILS 6)
set(FSFW_VERSION_IF_GIT_FAILS 5)
set(FSFW_SUBVERSION_IF_GIT_FAILS 0)
set(FSFW_REVISION_IF_GIT_FAILS 0)
@@ -72,7 +72,7 @@ set(FSFW_ETL_LIB_MAJOR_VERSION
20
CACHE STRING "ETL library major version requirement")
set(FSFW_ETL_LIB_VERSION
${FSFW_ETL_LIB_MAJOR_VERSION}.36.0
${FSFW_ETL_LIB_MAJOR_VERSION}.28.0
CACHE STRING "ETL library exact version requirement")
set(FSFW_ETL_LINK_TARGET etl::etl)
@@ -80,7 +80,7 @@ set(FSFW_CATCH2_LIB_MAJOR_VERSION
3
CACHE STRING "Catch2 library major version requirement")
set(FSFW_CATCH2_LIB_VERSION
v${FSFW_CATCH2_LIB_MAJOR_VERSION}.3.2
v${FSFW_CATCH2_LIB_MAJOR_VERSION}.1.0
CACHE STRING "Catch2 library exact version requirement")
# Keep this off by default for now. See PR:
@@ -140,7 +140,7 @@ option(FSFW_ADD_SGP4_PROPAGATOR "Add SGP4 propagator code" OFF)
set(FSFW_TEST_TGT fsfw-tests)
set(FSFW_DUMMY_TGT fsfw-dummy)
add_library(${LIB_FSFW_NAME} src/fsfw/cfdp/handler/PduPacketIF.h)
add_library(${LIB_FSFW_NAME})
if(IPO_SUPPORTED AND FSFW_ENABLE_IPO)
set_property(TARGET ${LIB_FSFW_NAME} PROPERTY INTERPROCEDURAL_OPTIMIZATION
@@ -158,7 +158,7 @@ if(FSFW_BUILD_TESTS)
if(NOT Catch2_FOUND)
message(
STATUS
"${MSG_PREFIX} Catch2 installation not found. Downloading Catch2 library with FetchContent."
"${MSG_PREFIX} Catch2 installation not found. Downloading Catch2 library with FetchContent"
)
include(FetchContent)
@@ -174,11 +174,29 @@ if(FSFW_BUILD_TESTS)
configure_file(unittests/testcfg/FSFWConfig.h.in FSFWConfig.h)
configure_file(unittests/testcfg/TestsConfig.h.in tests/TestsConfig.h)
if(FSFW_OSAL MATCHES "freertos")
message(STATUS "${MSG_PREFIX} Downloading FreeRTOS with FetchContent")
include(FetchContent)
set(FreeRTOS_PORT posix)
FetchContent_Declare(
FreeRTOS
GIT_REPOSITORY https://egit.irs.uni-stuttgart.de/fsfw/FreeRTOS-LTS
GIT_TAG develop
GIT_SUBMODULES FreeRTOS/FreeRTOS-Kernel)
FetchContent_MakeAvailable(FreeRTOS)
set(LIB_OS_NAME FreeRTOS)
target_include_directories(FreeRTOS PUBLIC unittests/testcfg/freertos)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(FreeRTOS PRIVATE ${CMAKE_THREAD_LIBS_INIT})
endif()
project(${FSFW_TEST_TGT} CXX C)
add_executable(
${FSFW_TEST_TGT}
unittests/cfdp/PduSenderMock.cpp unittests/cfdp/PduSenderMock.h
unittests/cfdp/handler/OwnedPduPacket.h)
add_executable(${FSFW_TEST_TGT})
if(IPO_SUPPORTED AND FSFW_ENABLE_IPO)
set_property(TARGET ${FSFW_TEST_TGT} PROPERTY INTERPROCEDURAL_OPTIMIZATION
TRUE)
@@ -204,8 +222,8 @@ find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET)
if(NOT ${FSFW_ETL_LIB_NAME}_FOUND)
message(
STATUS
"${MSG_PREFIX} ETL installation not found. Downloading ETL with FetchContent."
)
"${MSG_PREFIX} No ETL installation was found with find_package. Installing and providing "
"etl with FindPackage")
include(FetchContent)
FetchContent_Declare(
@@ -229,6 +247,7 @@ if(FSFW_FETCH_CONTENT_TARGETS)
# GitHub issue: https://github.com/catchorg/Catch2/issues/2417
set_target_properties(Catch2 PROPERTIES DEBUG_POSTFIX "")
endif()
endif()
set(FSFW_CORE_INC_PATH "inc")
@@ -363,6 +382,9 @@ if(FSFW_BUILD_TESTS)
endif()
target_link_libraries(${FSFW_TEST_TGT} PRIVATE Catch2::Catch2
${LIB_FSFW_NAME})
if(FSFW_OSAL MATCHES "freertos")
target_link_libraries(${FSFW_TEST_TGT} PRIVATE FreeRTOS)
endif()
endif()
# The project CMakeLists file has to set the FSFW_CONFIG_PATH and add it. If

View File

@@ -5,7 +5,7 @@ RUN apt-get --yes upgrade
#tzdata is a dependency, won't install otherwise
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get --yes install gcc g++ cmake make lcov git valgrind nano iputils-ping python3 pip doxygen graphviz rsync
RUN apt-get --yes install gcc g++ cmake make lcov git valgrind nano iputils-ping python3 pip doxygen graphviz rsync wget qemu-system-arm
RUN python3 -m pip install sphinx breathe
@@ -21,8 +21,12 @@ RUN git clone https://github.com/ETLCPP/etl.git && \
cmake -B build . && \
cmake --install build/
RUN wget -qO- https://buggy.irs.uni-stuttgart.de/rtems_releases/rtems6-12.2.1.tar.bz2 | tar -xj -C /opt/
ENV PATH="$PATH:/opt/rtems/6/bin"
#ssh needs a valid user to work
RUN adduser --uid 114 jenkins
RUN adduser -q --uid 114 jenkins
#add documentation server to known hosts
RUN echo "|1|/LzCV4BuTmTb2wKnD146l9fTKgQ=|NJJtVjvWbtRt8OYqFgcYRnMQyVw= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNL8ssTonYtgiR/6RRlSIK9WU1ywOcJmxFTLcEblAwH7oifZzmYq3XRfwXrgfMpylEfMFYfCU8JRqtmi19xc21A=" >> /etc/ssh/ssh_known_hosts

109
automation/Jenkinsfile vendored
View File

@@ -2,86 +2,61 @@ pipeline {
environment {
BUILDDIR_HOST = 'cmake-build-tests-host'
BUILDDIR_LINUX = 'cmake-build-tests-linux'
BUILDDIR_FREERTOS = 'cmake-build-tests-freertos'
BUILDDIR_RTEMS = 'cmake-build-tests-rtems'
DOCDDIR = 'cmake-build-documentation'
}
agent {
docker {
image 'fsfw-ci:d6'
image 'fsfw-ci:d7'
args '--network host --sysctl fs.mqueue.msg_max=100'
}
}
stages {
stage('Host') {
stages{
stage('Clean') {
steps {
sh 'rm -rf $BUILDDIR_HOST'
}
}
stage('Configure') {
steps {
dir(BUILDDIR_HOST) {
sh 'cmake -DFSFW_OSAL=host -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
}
}
}
stage('Build') {
steps {
dir(BUILDDIR_HOST) {
sh 'cmake --build . -j4'
}
}
}
stage('Unittests') {
steps {
dir(BUILDDIR_HOST) {
sh 'cmake --build . -- fsfw-tests_coverage -j4'
}
}
}
stage('Valgrind') {
steps {
dir(BUILDDIR_HOST) {
sh 'valgrind --leak-check=full --error-exitcode=1 ./fsfw-tests'
}
}
steps {
sh 'rm -rf $BUILDDIR_HOST'
dir(BUILDDIR_HOST) {
sh 'cmake -DFSFW_OSAL=host -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
sh 'cmake --build . -j4'
sh 'cmake --build . -- fsfw-tests_coverage -j4'
sh 'valgrind --leak-check=full --error-exitcode=1 ./fsfw-tests'
}
}
}
stage('Linux') {
stages{
stage('Clean') {
steps {
sh 'rm -rf $BUILDDIR_LINUX'
}
steps {
sh 'rm -rf $BUILDDIR_LINUX'
dir(BUILDDIR_LINUX) {
sh 'cmake -DFSFW_OSAL=linux -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
sh 'cmake --build . -j4'
sh 'cmake --build . -- fsfw-tests_coverage -j4'
sh 'valgrind --leak-check=full --error-exitcode=1 ./fsfw-tests'
}
stage('Configure') {
steps {
dir(BUILDDIR_LINUX) {
sh 'cmake -DFSFW_OSAL=linux -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
}
}
}
}
stage('FreeRTOS') {
steps {
sh 'rm -rf $BUILDDIR_FREERTOS'
dir(BUILDDIR_FREERTOS) {
sh 'cmake -DFSFW_OSAL=freertos -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
sh 'cmake --build . -j4'
sh 'cmake --build . -- fsfw-tests_coverage -j4'
//sh 'valgrind --leak-check=full --error-exitcode=1 ./fsfw-tests'
}
stage('Build') {
steps {
dir(BUILDDIR_LINUX) {
sh 'cmake --build . -j4'
}
}
}
stage('Unittests') {
steps {
dir(BUILDDIR_LINUX) {
sh 'cmake --build . -- fsfw-tests_coverage -j4'
}
}
}
stage('Valgrind') {
steps {
dir(BUILDDIR_LINUX) {
sh 'valgrind --leak-check=full --error-exitcode=1 ./fsfw-tests'
}
}
}
}
stage('rtems') {
steps {
sh 'rm -rf $BUILDDIR_RTEMS'
dir(BUILDDIR_RTEMS) {
sh 'cmake -DFSFW_OSAL=rtems -DFSFW_BUILD_TESTS=ON -DFSFW_TESTS_GEN_COV=OFF -DFSFW_CICD_BUILD=ON -DCMAKE_TOOLCHAIN_FILE=../unittests/testcfg/rtems/cmake/aarch64-rtems6-toolchain.cmake ..'
sh 'cmake --build . -j4'
sh 'qemu-system-aarch64 -no-reboot -nographic -serial mon:stdio -semihosting -machine virt,gic-version=3 -cpu cortex-a72 -m 4000 -kernel fsfw-tests'
}
}
}
@@ -97,7 +72,7 @@ pipeline {
sh 'rsync -r --delete docs/sphinx/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/development'
}
}
dir(BUILDDIR_LINUX) {
dir(BUILDDIR) {
sshagent(credentials: ['documentation-buildfix']) {
sh 'rsync -r --delete fsfw-tests_coverage/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/coverage/development'
}
@@ -116,7 +91,7 @@ pipeline {
sh 'rsync -r --delete docs/sphinx/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/master'
}
}
dir(BUILDDIR_LINUX) {
dir(BUILDDIR) {
sshagent(credentials: ['documentation-buildfix']) {
sh 'rsync -r --delete fsfw-tests_coverage/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/coverage/master'
}

View File

@@ -51,10 +51,7 @@ exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
html_theme = "alabaster"
html_theme_options = {
"extra_nav_links": {
"Impressum": "https://www.uni-stuttgart.de/impressum",
"Datenschutz": "https://info.irs.uni-stuttgart.de/datenschutz/datenschutzWebmit.html",
}
"extra_nav_links": {"Impressum" : "https://www.uni-stuttgart.de/impressum", "Datenschutz": "https://info.irs.uni-stuttgart.de/datenschutz/datenschutzWebmit.html"}
}

View File

@@ -1,110 +0,0 @@
#! /bin/python
import argparse
import json
import urllib.request
import re
from pathlib import Path
def main() -> None:
parser = argparse.ArgumentParser(
description="List undocumented PRs"
)
parser.add_argument("-v", "--version", type=str, required=True)
args = parser.parse_args()
match = re.search("([0-9]+\.[0-9]+\.[0-9]+)", args.version)
if not match:
print("invalid version")
exit(1)
version = "v" + match.group(1)
print("looking for milestone for " + version + " ...")
with urllib.request.urlopen("https://egit.irs.uni-stuttgart.de/api/v1/repos/fsfw/fsfw/milestones?name=" + version) as milestone_json:
milestones = json.load(milestone_json)
if (len(milestones) == 0):
print("did not find any milestone")
exit(1)
if (len(milestones) > 1):
print("found multiple milestons")
milestone_title = milestones[0]['title']
milestone = str(milestones[0]['id'])
print("Using Milestone \""+ milestone_title + "\" with id " + milestone)
milestone_prs = []
page = 1
last_count = 1;
while last_count != 0:
with urllib.request.urlopen("https://egit.irs.uni-stuttgart.de/api/v1/repos/fsfw/fsfw/pulls?state=closed&milestone=" + str(milestone) + "&limit=100&page=" + str(page)) as pull_requests_json:
pull_requests = json.load(pull_requests_json)
for pr in pull_requests:
milestone_prs.append({'number': str(pr['number']), 'title' : pr['title']})
page += 1
last_count = len(pull_requests)
print("Found " + str(len(milestone_prs)) + " closed PRs in Milestone")
print("looking for CHANGELOG.md ...")
path = Path(".")
files = list(path.glob("CHANGELOG.md"))
if (len(files) != 1):
files = list(path.glob("../CHANGELOG.md"))
if (len(files) != 1):
print("did not find CHANGELOG.md. Run script in either root directory or scripts subfolder.")
exit(1)
print("Scanning CHANGELOG.md ...")
changelog_prs = []
with open(files[0]) as changelog:
line = changelog.readline()
while (line):
#print("line: " + line)
match = re.search("\#.+(v[0-9]+\.[0-9]+\.[0-9]+)", line)
if (match):
if match.group(1) == version:
#print("found version")
line = changelog.readline()
continue
else:
#print("done with " + match.group(1))
break
match = re.search("PR: https://egit\.irs\.uni-stuttgart\.de/fsfw/fsfw/pulls/([0-9]+)", line)
if match:
changelog_prs.append(match.group(1))
line = changelog.readline()
print("Found " + str(len(changelog_prs)) + " PRs in CHANGELOG.md")
print("")
copy_array = changelog_prs.copy()
print("PRs in CHANGELOG.md that are not in Milestone:")
for pr in milestone_prs:
if pr['number'] in copy_array:
copy_array.remove(pr['number'])
for pr in copy_array:
print("https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/" + pr)
print("")
print("PRs in milestone that are not in CHANGELOG.md:")
for pr in milestone_prs:
if pr['number'] not in changelog_prs:
print("- " + pr['title'] + "\n PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/" + pr['number'])
main()

View File

@@ -32,7 +32,6 @@ add_subdirectory(timemanager)
add_subdirectory(tmtcpacket)
add_subdirectory(tmtcservices)
add_subdirectory(filesystem)
add_subdirectory(util)
# Optional

View File

@@ -59,24 +59,17 @@ void ActionHelper::setQueueToUse(MessageQueueIF* queue) { queueToUse = queue; }
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
store_address_t dataAddress) {
bool hasAdditionalData = false;
const uint8_t* dataPtr = nullptr;
size_t size = 0;
ReturnValue_t result;
if (dataAddress != store_address_t::invalid()) {
hasAdditionalData = true;
result = ipcStore->getData(dataAddress, &dataPtr, &size);
if (result != returnvalue::OK) {
CommandMessage reply;
ActionMessage::setStepReply(&reply, actionId, 0, result);
queueToUse->sendMessage(commandedBy, &reply);
return;
}
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
if (result != returnvalue::OK) {
CommandMessage reply;
ActionMessage::setStepReply(&reply, actionId, 0, result);
queueToUse->sendMessage(commandedBy, &reply);
return;
}
result = owner->executeAction(actionId, commandedBy, dataPtr, size);
if (hasAdditionalData) {
ipcStore->deleteData(dataAddress);
}
ipcStore->deleteData(dataAddress);
if (result == HasActionsIF::EXECUTION_FINISHED) {
CommandMessage reply;
ActionMessage::setCompletionReply(&reply, actionId, true, result);

View File

@@ -16,8 +16,8 @@ class CommandActionHelper {
public:
explicit CommandActionHelper(CommandsActionsIF* owner);
virtual ~CommandActionHelper();
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId,
const uint8_t* data = nullptr, uint32_t size = 0);
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId, const uint8_t* data,
uint32_t size);
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId, SerializeIF* data);
ReturnValue_t initialize();
ReturnValue_t handleReply(CommandMessage* reply);

View File

@@ -2,9 +2,7 @@
#define FSFW_CFDP_H
#include "cfdp/definitions.h"
#include "cfdp/handler/DestHandler.h"
#include "cfdp/handler/FaultHandlerBase.h"
#include "cfdp/helpers.h"
#include "cfdp/tlv/Lv.h"
#include "cfdp/tlv/StringLv.h"
#include "cfdp/tlv/Tlv.h"

View File

@@ -4,7 +4,7 @@
#include <utility>
#include <vector>
#include "fsfw/cfdp/pdu/HeaderReader.h"
#include "fsfw/cfdp/pdu/PduHeaderReader.h"
#include "fsfw/returnvalues/returnvalue.h"
#include "fsfw/tcdistribution/CfdpPacketChecker.h"
#include "fsfw/tcdistribution/TcDistributorBase.h"

View File

@@ -4,9 +4,8 @@ CfdpMessage::CfdpMessage() = default;
CfdpMessage::~CfdpMessage() = default;
void CfdpMessage::setPutRequest(CommandMessage *message, store_address_t putRequest) {
message->setCommand(PUT_REQUEST);
message->setParameter(putRequest.raw);
void CfdpMessage::setCommand(CommandMessage *message, store_address_t cfdpPacket) {
message->setParameter(cfdpPacket.raw);
}
store_address_t CfdpMessage::getStoreId(const CommandMessage *message) {

View File

@@ -11,11 +11,9 @@ class CfdpMessage {
public:
static const uint8_t MESSAGE_ID = messagetypes::CFDP;
static const Command_t PUT_REQUEST = MAKE_COMMAND_ID(1);
static const Command_t CANCEL_REQUEST = MAKE_COMMAND_ID(1);
virtual ~CfdpMessage();
static void setPutRequest(CommandMessage* message, store_address_t putRequest);
static void setCommand(CommandMessage* message, store_address_t cfdpPacket);
static store_address_t getStoreId(const CommandMessage* message);

View File

@@ -8,14 +8,11 @@
namespace cfdp {
/**
* Helper type for the CFDP File Size Sensitive (FSS) fields.
*/
struct Fss : public SerializeIF {
struct FileSize : public SerializeIF {
public:
Fss() = default;
FileSize() = default;
explicit Fss(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; }

View File

@@ -3,8 +3,8 @@
#include "fsfw/serialize/SerializeAdapter.h"
#include "fsfw/serviceinterface.h"
cfdp::VarLenField::VarLenField(cfdp::WidthInBytes width, uint64_t value) : VarLenField() {
ReturnValue_t result = this->setValueAndWidth(width, value);
cfdp::VarLenField::VarLenField(cfdp::WidthInBytes width, size_t value) : VarLenField() {
ReturnValue_t result = this->setValue(width, value);
if (result != returnvalue::OK) {
#if FSFW_DISABLE_PRINTOUT == 0
#if FSFW_CPP_OSTREAM_ENABLED == 1
@@ -20,8 +20,8 @@ cfdp::VarLenField::VarLenField() : width(cfdp::WidthInBytes::ONE_BYTE) { value.o
cfdp::WidthInBytes cfdp::VarLenField::getWidth() const { return width; }
ReturnValue_t cfdp::VarLenField::setValueAndWidth(cfdp::WidthInBytes width_, uint64_t value_) {
switch (width_) {
ReturnValue_t cfdp::VarLenField::setValue(cfdp::WidthInBytes widthInBytes, size_t value_) {
switch (widthInBytes) {
case (cfdp::WidthInBytes::ONE_BYTE): {
if (value_ > UINT8_MAX) {
return returnvalue::FAILED;
@@ -43,18 +43,15 @@ ReturnValue_t cfdp::VarLenField::setValueAndWidth(cfdp::WidthInBytes width_, uin
this->value.fourBytes = value_;
break;
}
case (cfdp::WidthInBytes::EIGHT_BYTES): {
this->value.eightBytes = value_;
}
default: {
break;
}
}
this->width = width_;
this->width = widthInBytes;
return returnvalue::OK;
}
uint64_t cfdp::VarLenField::getValue() const {
size_t cfdp::VarLenField::getValue() const {
switch (width) {
case (cfdp::WidthInBytes::ONE_BYTE): {
return value.oneByte;
@@ -65,9 +62,6 @@ uint64_t cfdp::VarLenField::getValue() const {
case (cfdp::WidthInBytes::FOUR_BYTES): {
return value.fourBytes;
}
case (cfdp::WidthInBytes::EIGHT_BYTES): {
return value.eightBytes;
}
}
return 0;
}
@@ -90,10 +84,6 @@ ReturnValue_t cfdp::VarLenField::serialize(uint8_t **buffer, size_t *size, size_
case (cfdp::WidthInBytes::FOUR_BYTES): {
return SerializeAdapter::serialize(&value.fourBytes, buffer, size, maxSize, streamEndianness);
}
case (cfdp::WidthInBytes::EIGHT_BYTES): {
return SerializeAdapter::serialize(&value.eightBytes, buffer, size, maxSize,
streamEndianness);
}
default: {
return returnvalue::FAILED;
}
@@ -108,16 +98,11 @@ ReturnValue_t cfdp::VarLenField::deSerialize(cfdp::WidthInBytes width_, const ui
return deSerialize(buffer, size, streamEndianness);
}
ReturnValue_t cfdp::VarLenField::setValue(uint64_t value_) {
return setValueAndWidth(getWidth(), value_);
}
ReturnValue_t cfdp::VarLenField::deSerialize(const uint8_t **buffer, size_t *size,
Endianness streamEndianness) {
switch (width) {
case (cfdp::WidthInBytes::ONE_BYTE): {
value.oneByte = **buffer;
*buffer += 1;
*size += 1;
return returnvalue::OK;
}
@@ -127,9 +112,6 @@ ReturnValue_t cfdp::VarLenField::deSerialize(const uint8_t **buffer, size_t *siz
case (cfdp::WidthInBytes::FOUR_BYTES): {
return SerializeAdapter::deSerialize(&value.fourBytes, buffer, size, streamEndianness);
}
case (cfdp::WidthInBytes::EIGHT_BYTES): {
return SerializeAdapter::deSerialize(&value.eightBytes, buffer, size, streamEndianness);
}
default: {
return returnvalue::FAILED;
}
@@ -153,5 +135,3 @@ bool cfdp::VarLenField::operator==(const cfdp::VarLenField &other) const {
bool cfdp::VarLenField::operator!=(const cfdp::VarLenField &other) const {
return not(*this == other);
}
void cfdp::VarLenField::setWidth(cfdp::WidthInBytes width_) { this->width = width_; }

View File

@@ -25,15 +25,13 @@ class VarLenField : public SerializeIF {
template <typename T>
explicit VarLenField(UnsignedByteField<T> byteField);
VarLenField(cfdp::WidthInBytes width, uint64_t value);
VarLenField(cfdp::WidthInBytes width, size_t value);
bool operator==(const VarLenField &other) const;
bool operator!=(const VarLenField &other) const;
bool operator<(const VarLenField &other) const;
ReturnValue_t setValueAndWidth(cfdp::WidthInBytes width, uint64_t value);
void setWidth(cfdp::WidthInBytes width);
ReturnValue_t setValue(uint64_t value);
ReturnValue_t setValue(cfdp::WidthInBytes, size_t value);
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
Endianness streamEndianness) const override;
@@ -44,7 +42,7 @@ class VarLenField : public SerializeIF {
Endianness streamEndianness);
[[nodiscard]] cfdp::WidthInBytes getWidth() const;
[[nodiscard]] uint64_t getValue() const;
[[nodiscard]] size_t getValue() const;
#if FSFW_CPP_OSTREAM_ENABLED == 1
friend std::ostream &operator<<(std::ostream &os, const VarLenField &id) {
@@ -53,9 +51,8 @@ class VarLenField : public SerializeIF {
return os;
}
#endif
private:
using SerializeIF::deSerialize; // we overloaded above, so this is needed to uncofuse the
// compiler
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
Endianness streamEndianness) override;
@@ -67,7 +64,7 @@ template <typename T>
cfdp::VarLenField::VarLenField(UnsignedByteField<T> byteField)
: width(static_cast<cfdp::WidthInBytes>(sizeof(T))) {
static_assert((sizeof(T) % 2) == 0);
setValueAndWidth(width, byteField.getValue());
setValue(width, byteField.getValue());
}
struct EntityId : public VarLenField {
@@ -76,32 +73,6 @@ struct EntityId : public VarLenField {
template <typename T>
explicit EntityId(UnsignedByteField<T> byteField) : VarLenField(byteField) {}
EntityId(cfdp::WidthInBytes width, size_t entityId) : VarLenField(width, entityId) {}
ReturnValue_t serializeAsLv(uint8_t **buffer, size_t *size, size_t maxSize) const {
if (buffer == nullptr or size == nullptr) {
return returnvalue::FAILED;
}
if (*size + 1 + getWidth() > maxSize) {
return SerializeIF::BUFFER_TOO_SHORT;
}
**buffer = getWidth();
*buffer += 1;
*size += 1;
return serialize(buffer, size, maxSize, SerializeIF::Endianness::NETWORK);
}
ReturnValue_t deSerializeFromLv(const uint8_t **buffer, size_t *deserLen) {
if (buffer == nullptr or deserLen == nullptr) {
return returnvalue::FAILED;
}
if (*deserLen < 2) {
return SerializeIF::STREAM_TOO_SHORT;
}
auto width = static_cast<WidthInBytes>(**buffer);
*buffer += 1;
*deserLen -= 1;
return VarLenField::deSerialize(width, buffer, deserLen, SerializeIF::Endianness::NETWORK);
}
};
struct TransactionSeqNum : public VarLenField {

View File

@@ -17,7 +17,7 @@ static constexpr char CFDP_VERSION_2_NAME[] = "CCSDS 727.0-B-5";
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_BASE;
static constexpr uint8_t CFDP_CLASS_ID = CLASS_ID::CFDP;
static constexpr ReturnValue_t INVALID_TLV_TYPE = returnvalue::makeCode(CFDP_CLASS_ID, 1);
static constexpr ReturnValue_t INVALID_DIRECTIVE_FIELD = returnvalue::makeCode(CFDP_CLASS_ID, 2);
@@ -38,7 +38,6 @@ static constexpr ReturnValue_t FILESTORE_REQUIRES_SECOND_FILE =
static constexpr ReturnValue_t FILESTORE_RESPONSE_CANT_PARSE_FS_MESSAGE =
returnvalue::makeCode(CFDP_CLASS_ID, 9);
static constexpr ReturnValue_t INVALID_PDU_FORMAT = returnvalue::makeCode(CFDP_CLASS_ID, 10);
static constexpr ReturnValue_t PDU_CHECKSUM_FAILURE = returnvalue::makeCode(CFDP_CLASS_ID, 11);
//! Checksum types according to the SANA Checksum Types registry
//! https://sanaregistry.org/r/checksum_identifiers/
@@ -69,7 +68,6 @@ enum WidthInBytes : uint8_t {
ONE_BYTE = 1,
TWO_BYTES = 2,
FOUR_BYTES = 4,
EIGHT_BYTES = 8
};
enum FileDirective : uint8_t {
@@ -144,20 +142,6 @@ enum RecordContinuationState {
CONTAINS_START_AND_END = 0b11
};
enum class ProxyOpMessageType : uint8_t {
PUT_REQUEST = 0x00,
MSG_TO_USR = 0x01,
FS_REQUEST = 0x02,
FAULT_HANDLER_OVERRIDE = 0x03,
TRANSMISSION_MODE = 0x04,
FLOW_LABEL = 0x05,
SEG_CTRL = 0x06,
PUT_RESPONSE = 0x07,
FS_RESPONSE = 0x08,
PUT_CANCEL = 0x09,
CLOSURE = 0x0b
};
} // namespace cfdp
#endif /* FSFW_SRC_FSFW_CFDP_PDU_DEFINITIONS_H_ */

View File

@@ -1,4 +1 @@
target_sources(
${LIB_FSFW_NAME}
PRIVATE SourceHandler.cpp DestHandler.cpp PutRequest.cpp
ReservedMessageParser.cpp FaultHandlerBase.cpp UserBase.cpp)
target_sources(${LIB_FSFW_NAME} PRIVATE FaultHandlerBase.cpp UserBase.cpp)

View File

@@ -1,512 +0,0 @@
#include "DestHandler.h"
#include <etl/crc32.h>
#include <utility>
#include "fsfw/FSFW.h"
#include "fsfw/cfdp/pdu/EofPduReader.h"
#include "fsfw/cfdp/pdu/FileDataReader.h"
#include "fsfw/cfdp/pdu/FinishedPduCreator.h"
#include "fsfw/cfdp/pdu/HeaderReader.h"
#include "fsfw/objectmanager.h"
#include "fsfw/tmtcservices/TmTcMessage.h"
using namespace returnvalue;
cfdp::DestHandler::DestHandler(PduSenderIF& pduSender, size_t pduBufSize, DestHandlerParams params,
FsfwParams fsfwParams)
: pduBuf(pduBufSize),
pduSender(pduSender),
tlvVec(params.maxTlvsInOnePdu),
msgToUserVec(params.maxTlvsInOnePdu),
transactionParams(params.maxFilenameLen),
destParams(std::move(params)),
fsfwParams(fsfwParams) {
transactionParams.pduConf.direction = cfdp::Direction::TOWARDS_SENDER;
}
const cfdp::DestHandler::FsmResult& cfdp::DestHandler::stateMachineNoPacket() {
return stateMachine(std::nullopt);
}
const cfdp::DestHandler::FsmResult& cfdp::DestHandler::stateMachine(
const std::optional<std::reference_wrapper<PduPacketIF>> optPduPacket) {
ReturnValue_t result;
uint8_t errorIdx = 0;
fsmRes.resetOfIteration();
if (fsmRes.step == TransactionStep::IDLE) {
if (!optPduPacket.has_value()) {
return fsmRes;
}
PduPacketIF& pduPacket = *optPduPacket;
if (pduPacket.getPduType() == FILE_DATA or
(pduPacket.getPduType() == FILE_DIRECTIVE and *pduPacket.getFileDirective() != METADATA)) {
fsmRes.result = DEST_NON_METADATA_PDU_AS_FIRST_PDU;
return fsmRes;
}
result = handleMetadataPdu(pduPacket);
checkAndHandleError(result, errorIdx);
return updateFsmRes(errorIdx);
}
if (fsmRes.state == CfdpState::BUSY_CLASS_1_NACKED) {
if (fsmRes.step == TransactionStep::RECEIVING_FILE_DATA_PDUS) {
if (!optPduPacket.has_value()) {
return fsmRes;
}
PduPacketIF& pduPacket = *optPduPacket;
if (pduPacket.getPduType() == FILE_DATA) {
result = handleFileDataPdu(pduPacket);
checkAndHandleError(result, errorIdx);
} else if (pduPacket.getPduType() == FILE_DIRECTIVE and
*pduPacket.getFileDirective() == EOF_DIRECTIVE) {
// TODO: Support for check timer missing
result = handleEofPdu(pduPacket);
checkAndHandleError(result, errorIdx);
}
}
}
if (fsmRes.step == TransactionStep::TRANSFER_COMPLETION) {
result = handleTransferCompletion();
checkAndHandleError(result, errorIdx);
}
if (fsmRes.step == TransactionStep::SENDING_FINISHED_PDU) {
result = sendFinishedPdu();
checkAndHandleError(result, errorIdx);
finish();
return updateFsmRes(errorIdx);
}
if (fsmRes.state == CfdpState::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 updateFsmRes(errorIdx);
}
ReturnValue_t cfdp::DestHandler::handleMetadataPdu(const PduPacketIF& pduPacket) {
// Process metadata PDU
cfdp::StringLv sourceFileName;
cfdp::StringLv destFileName;
MetadataGenericInfo metadataInfo(transactionParams.fileSize);
size_t pduSize = 0;
auto rawPdu = pduPacket.getRawPduData(pduSize);
MetadataPduReader reader(rawPdu, pduSize, metadataInfo, tlvVec.data(), tlvVec.size());
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(result, rawPdu, pduSize);
}
return startTransaction(reader);
}
ReturnValue_t cfdp::DestHandler::handleFileDataPdu(const PduPacketIF& info) {
size_t pduSize = 0;
const auto rawPdu = info.getRawPduData(pduSize);
// Process file data PDU
FileDataInfo fdInfo;
FileDataReader reader(rawPdu, pduSize, fdInfo);
ReturnValue_t result = reader.parseData();
if (result != OK) {
return result;
}
size_t fileSegmentLen = 0;
const uint8_t* fileData = fdInfo.getFileData(&fileSegmentLen);
if (destParams.cfg.indicCfg.fileSegmentRecvIndicRequired) {
FileSegmentRecvdParams segParams;
segParams.offset = fdInfo.getOffset().value();
segParams.id = transactionParams.transactionId;
segParams.length = fileSegmentLen;
segParams.recContState = fdInfo.getRecordContinuationState();
size_t segmentMetadatLen = 0;
auto* segMetadata = fdInfo.getSegmentMetadata(&segmentMetadatLen);
segParams.segmentMetadata = {segMetadata, segmentMetadatLen};
destParams.user.fileSegmentRecvdIndication(segParams);
}
// sif::printDebug("Writing %d bytes at offset %d\n", fileSegmentLen, fdInfo.getOffset().value());
result = destParams.user.vfs.writeToFile(transactionParams.destName.data(),
fdInfo.getOffset().value(), fileData, fileSegmentLen);
if (result != returnvalue::OK) {
// TODO: Proper Error handling
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "cfdp::DestHandler: VFS file write error with code 0x" << std::hex << std::setw(2)
<< result << std::endl;
#endif
transactionParams.vfsErrorCount++;
if (transactionParams.vfsErrorCount < 3) {
// TODO: Provide execution step as parameter
fsfwParams.eventReporter->forwardEvent(events::FILESTORE_ERROR,
static_cast<uint8_t>(fsmRes.step), result);
}
return result;
}
transactionParams.deliveryStatus = FileDeliveryStatus::RETAINED_IN_FILESTORE;
transactionParams.vfsErrorCount = 0;
if (fdInfo.getOffset().value() + fileSegmentLen > transactionParams.progress) {
transactionParams.progress = fdInfo.getOffset().value() + fileSegmentLen;
}
return result;
}
ReturnValue_t cfdp::DestHandler::handleEofPdu(const cfdp::PduPacketIF& info) {
size_t pduSize = 0;
const auto rawPdu = info.getRawPduData(pduSize);
// Process EOF PDU
EofInfo eofInfo(nullptr);
EofPduReader reader(rawPdu, pduSize, eofInfo);
ReturnValue_t result = reader.parseData();
if (result != OK) {
return result;
}
// TODO: Error handling
if (eofInfo.getConditionCode() == ConditionCode::NO_ERROR) {
transactionParams.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 > transactionParams.progress) {
// TODO: File size error
}
transactionParams.fileSize.setFileSize(fileSizeFromEof, std::nullopt);
}
if (destParams.cfg.indicCfg.eofRecvIndicRequired) {
destParams.user.eofRecvIndication(getTransactionId());
}
if (fsmRes.step == TransactionStep::RECEIVING_FILE_DATA_PDUS) {
if (fsmRes.state == CfdpState::BUSY_CLASS_1_NACKED) {
fsmRes.step = TransactionStep::TRANSFER_COMPLETION;
} else if (fsmRes.state == CfdpState::BUSY_CLASS_2_ACKED) {
fsmRes.step = TransactionStep::SENDING_ACK_PDU;
}
}
return returnvalue::OK;
}
ReturnValue_t cfdp::DestHandler::handleMetadataParseError(ReturnValue_t result,
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
sif::printWarning("cfdp::DestHandler: parsing metadata PDU failed with code %04x\n", result);
#endif
PduHeaderReader headerReader(rawData, maxSize);
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 destParams.remoteCfgTable.getRemoteCfg(destId, &remoteCfg)) {
// TODO: No remote config for dest ID. I consider this a configuration error, which is not
// covered by the standard.
// 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(const MetadataPduReader& reader) {
if (fsmRes.state != CfdpState::IDLE) {
// According to standard, discard metadata PDU if we are busy
return OK;
}
ReturnValue_t result = OK;
size_t sourceNameSize = 0;
if (not reader.getSourceFileName().isEmpty()) {
const uint8_t* sourceNamePtr = reader.getSourceFileName().getValue(&sourceNameSize);
if (sourceNameSize + 1 > transactionParams.sourceName.size()) {
fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "source filename too large");
return FAILED;
}
std::memcpy(transactionParams.sourceName.data(), sourceNamePtr, sourceNameSize);
transactionParams.sourceName[sourceNameSize] = '\0';
}
size_t destNameSize = 0;
if (not reader.getDestFileName().isEmpty()) {
const uint8_t* destNamePtr = reader.getDestFileName().getValue(&destNameSize);
if (destNameSize + 1 > transactionParams.destName.size()) {
fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "dest filename too large");
return FAILED;
}
std::memcpy(transactionParams.destName.data(), destNamePtr, destNameSize);
transactionParams.destName[destNameSize] = '\0';
}
transactionParams.metadataOnly = true;
// If both dest name size and source name size are 0, we are dealing with a metadata only PDU,
// so there is no need to create a file or truncate an existing file
if (destNameSize > 0 and sourceNameSize > 0) {
transactionParams.metadataOnly = false;
// handling to allow only specifying target directory. Example:
// Source path /test/hello.txt, dest path /tmp -> dest path /tmp/hello.txt
bool isDirectory = false;
result = destParams.user.vfs.isDirectory(transactionParams.destName.data(), isDirectory);
if (result == returnvalue::OK && isDirectory) {
result = tryBuildingAbsoluteDestName(destNameSize);
if (result != OK) {
return result;
}
}
if (destParams.user.vfs.fileExists(transactionParams.destName.data())) {
result = destParams.user.vfs.truncateFile(transactionParams.destName.data());
if (result != returnvalue::OK) {
fileErrorHandler(events::FILESTORE_ERROR, result, "file truncation error");
return FAILED;
// TODO: Relevant for filestore rejection error?
}
} else {
result = destParams.user.vfs.createFile(transactionParams.destName.data());
if (result != OK) {
fileErrorHandler(events::FILESTORE_ERROR, result, "file creation error");
return FAILED;
// TODO: Relevant for filestore rejection error?
}
}
}
EntityId sourceId;
reader.getSourceId(sourceId);
if (not destParams.remoteCfgTable.getRemoteCfg(sourceId, &transactionParams.remoteCfg)) {
// TODO: Warning, event etc.
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "cfdp::DestHandler" << __func__
<< ": No remote configuration found for destination ID "
<< transactionParams.pduConf.sourceId.getValue() << std::endl;
#endif
return FAILED;
}
if (reader.getTransmissionMode() == TransmissionMode::UNACKNOWLEDGED) {
fsmRes.state = CfdpState::BUSY_CLASS_1_NACKED;
} else if (reader.getTransmissionMode() == TransmissionMode::ACKNOWLEDGED) {
fsmRes.state = CfdpState::BUSY_CLASS_2_ACKED;
}
if (transactionParams.metadataOnly) {
fsmRes.step = TransactionStep::TRANSFER_COMPLETION;
} else {
// Kind of ugly, make FSM working on packet per packet basis..
fsmRes.step = TransactionStep::TRANSACTION_START;
fsmRes.step = TransactionStep::RECEIVING_FILE_DATA_PDUS;
}
auto& info = reader.getGenericInfo();
transactionParams.checksumType = info.getChecksumType();
transactionParams.closureRequested = info.isClosureRequested();
reader.fillConfig(transactionParams.pduConf);
transactionParams.pduConf.crcFlag = transactionParams.remoteCfg->crcOnTransmission;
transactionParams.pduConf.direction = Direction::TOWARDS_SENDER;
transactionParams.transactionId.entityId = transactionParams.pduConf.sourceId;
transactionParams.transactionId.seqNum = transactionParams.pduConf.seqNum;
transactionParams.fileSize = info.getFileSize();
MetadataRecvdParams params(transactionParams.transactionId, transactionParams.pduConf.sourceId,
transactionParams.fileSize);
params.destFileName = transactionParams.destName.data();
params.sourceFileName = transactionParams.sourceName.data();
params.numberOfMsgsToUser = 0;
for (uint32_t tlvIdx = 0; tlvIdx < reader.getNumberOfParsedOptions(); tlvIdx++) {
if (tlvVec[tlvIdx].getType() == TlvType::MSG_TO_USER) {
msgToUserVec[params.numberOfMsgsToUser] =
MessageToUserTlv(tlvVec[tlvIdx].getValue(), tlvVec[tlvIdx].getLengthField());
params.numberOfMsgsToUser++;
}
}
params.msgsToUserArray = msgToUserVec.data();
destParams.user.metadataRecvdIndication(params);
return result;
}
cfdp::CfdpState cfdp::DestHandler::getCfdpState() const { return fsmRes.state; }
ReturnValue_t cfdp::DestHandler::handleTransferCompletion() {
ReturnValue_t result;
if (transactionParams.checksumType != ChecksumType::NULL_CHECKSUM) {
result = checksumVerification();
if (result != OK) {
// TODO: Warning / error handling?
}
} else {
transactionParams.conditionCode = ConditionCode::NO_ERROR;
}
result = noticeOfCompletion();
if (result != OK) {
}
if (fsmRes.state == CfdpState::BUSY_CLASS_1_NACKED) {
if (transactionParams.closureRequested) {
fsmRes.step = TransactionStep::SENDING_FINISHED_PDU;
} else {
finish();
}
} else if (fsmRes.state == CfdpState::BUSY_CLASS_2_ACKED) {
fsmRes.step = TransactionStep::SENDING_FINISHED_PDU;
}
return OK;
}
ReturnValue_t cfdp::DestHandler::tryBuildingAbsoluteDestName(size_t destNameSize) {
// A path may only have a maximum of 256 characters in CFDP, so this buffer should be sufficient
// for all use-cases.
char baseNameBuf[512]{};
size_t baseNameLen = 0;
const ReturnValue_t result = destParams.user.vfs.getBaseFilename(
transactionParams.sourceName.data(), baseNameBuf, sizeof(baseNameBuf), baseNameLen);
if (result != returnvalue::OK or baseNameLen == 0) {
fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "error retrieving source base name");
return FAILED;
}
// Destination name + slash + base name + null termination
if (destNameSize + 1 + baseNameLen + 1 > transactionParams.destName.size()) {
fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0,
"dest filename too large after adding source base name");
return FAILED;
}
transactionParams.destName[destNameSize++] = '/';
std::memcpy(transactionParams.destName.data() + destNameSize, baseNameBuf, baseNameLen);
destNameSize += baseNameLen;
transactionParams.destName[destNameSize++] = '\0';
return OK;
}
void cfdp::DestHandler::fileErrorHandler(Event event, ReturnValue_t result,
const char* info) const {
fsfwParams.eventReporter->forwardEvent(event, static_cast<uint8_t>(fsmRes.step), result);
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "cfdp::DestHandler: " << info << std::endl;
#endif
}
void cfdp::DestHandler::finish() {
transactionParams.reset();
fsmRes.state = CfdpState::IDLE;
fsmRes.step = TransactionStep::IDLE;
}
ReturnValue_t cfdp::DestHandler::checksumVerification() {
std::array<uint8_t, 1024> buf{};
etl::crc32 crcCalc;
uint64_t currentOffset = 0;
while (currentOffset < transactionParams.fileSize.value()) {
uint64_t lenToRead;
if (currentOffset + buf.size() > transactionParams.fileSize.value()) {
lenToRead = transactionParams.fileSize.value() - currentOffset;
} else {
lenToRead = buf.size();
}
if (lenToRead > 0) {
size_t readLen = 0;
const auto result =
destParams.user.vfs.readFromFile(transactionParams.destName.data(), currentOffset,
lenToRead, buf.data(), readLen, buf.size());
if (result != OK) {
// TODO: I think this is a case for a filestore rejection, but it might sense to print
// a warning or trigger an event because this should generally not happen
return FAILED;
}
crcCalc.add(buf.begin(), buf.begin() + lenToRead);
}
currentOffset += lenToRead;
}
uint32_t value = crcCalc.value();
if (value == transactionParams.crc) {
transactionParams.conditionCode = ConditionCode::NO_ERROR;
transactionParams.deliveryCode = FileDeliveryCode::DATA_COMPLETE;
} else {
// TODO: Proper error handling
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "CRC check for file " << transactionParams.destName.data() << " failed"
<< std::endl;
#endif
transactionParams.conditionCode = ConditionCode::FILE_CHECKSUM_FAILURE;
}
return OK;
}
ReturnValue_t cfdp::DestHandler::noticeOfCompletion() {
if (destParams.cfg.indicCfg.transactionFinishedIndicRequired) {
TransactionFinishedParams params(
transactionParams.transactionId, transactionParams.conditionCode,
transactionParams.deliveryCode, transactionParams.deliveryStatus);
destParams.user.transactionFinishedIndication(params);
}
return OK;
}
ReturnValue_t cfdp::DestHandler::sendFinishedPdu() {
FinishedInfo info(transactionParams.conditionCode, transactionParams.deliveryCode,
transactionParams.deliveryStatus);
FinishPduCreator finishedPdu(transactionParams.pduConf, info);
size_t serLen = 0;
ReturnValue_t result =
finishedPdu.serialize(pduBuf.data(), serLen, finishedPdu.getSerializedSize());
checkAndHandleError(result, fsmRes.errors);
if (result != OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "cfdp::DestHandler::sendFinishedPdu: Serializing Finished PDU failed"
<< std::endl;
#endif
fsfwParams.eventReporter->forwardEvent(events::SERIALIZATION_ERROR, result, 0);
return result;
}
pduSender.sendPdu(PduType::FILE_DIRECTIVE, FileDirective::FINISH, pduBuf.data(), serLen);
if (result != OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "cfdp::DestHandler::sendFinishedPdu: Sending PDU failed" << std::endl;
#endif
fsfwParams.eventReporter->forwardEvent(events::PDU_SEND_ERROR, result, 0);
return result;
}
fsmRes.packetsSent++;
return OK;
}
cfdp::DestHandler::TransactionStep cfdp::DestHandler::getTransactionStep() const {
return fsmRes.step;
}
const cfdp::DestHandler::FsmResult& cfdp::DestHandler::updateFsmRes(uint8_t errors) {
fsmRes.errors = errors;
fsmRes.result = OK;
if (fsmRes.errors > 0) {
fsmRes.result = FAILED;
}
return fsmRes;
}
const cfdp::TransactionId& cfdp::DestHandler::getTransactionId() const {
return transactionParams.transactionId;
}
void cfdp::DestHandler::checkAndHandleError(ReturnValue_t result, uint8_t& errorIdx) {
if (result != OK and errorIdx < 3) {
fsmRes.errorCodes[errorIdx] = result;
errorIdx++;
}
}
void cfdp::DestHandler::setEventReporter(EventReportingProxyIF& reporter) {
fsfwParams.eventReporter = &reporter;
}
const cfdp::DestHandlerParams& cfdp::DestHandler::getDestHandlerParams() const {
return destParams;
}

View File

@@ -1,176 +0,0 @@
#ifndef FSFW_CFDP_CFDPDESTHANDLER_H
#define FSFW_CFDP_CFDPDESTHANDLER_H
#include <etl/list.h>
#include <etl/set.h>
#include <array>
#include <optional>
#include <utility>
#include "RemoteConfigTableIF.h"
#include "UserBase.h"
#include "defs.h"
#include "fsfw/cfdp/handler/PduPacketIF.h"
#include "fsfw/cfdp/handler/PduSenderIF.h"
#include "fsfw/cfdp/handler/mib.h"
#include "fsfw/cfdp/pdu/MetadataPduReader.h"
#include "fsfw/cfdp/pdu/PduConfig.h"
#include "fsfw/cfdp/tlv/MessageToUserTlv.h"
#include "fsfw/storagemanager/StorageManagerIF.h"
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
namespace cfdp {
template <size_t SIZE>
using LostSegmentsList = etl::set<etl::pair<uint64_t, uint64_t>, SIZE>;
using LostSegmentsListBase = etl::iset<etl::pair<uint64_t, uint64_t>>;
struct DestHandlerParams {
DestHandlerParams(LocalEntityCfg cfg, UserBase& user, RemoteConfigTableIF& remoteCfgTable,
// 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
// TODO: Actually, we can provide a better abstraction via interface, which
// allows using something like a bounded map. This simplifies
// the implementation significantly.
LostSegmentsListBase& lostSegmentsContainer)
: cfg(std::move(cfg)),
user(user),
remoteCfgTable(remoteCfgTable),
lostSegmentsContainer(lostSegmentsContainer) {}
LocalEntityCfg cfg;
UserBase& user;
RemoteConfigTableIF& remoteCfgTable;
LostSegmentsListBase& lostSegmentsContainer;
uint8_t maxTlvsInOnePdu = 20;
size_t maxFilenameLen = 255;
};
class DestHandler {
public:
enum class TransactionStep : uint8_t {
IDLE = 0,
TRANSACTION_START = 1,
RECEIVING_FILE_DATA_PDUS = 2,
SENDING_ACK_PDU = 3,
TRANSFER_COMPLETION = 4,
SENDING_FINISHED_PDU = 5
};
struct FsmResult {
uint32_t packetsSent = 0;
ReturnValue_t result = returnvalue::OK;
TransactionStep step = TransactionStep::IDLE;
CfdpState state = CfdpState::IDLE;
uint8_t errors = 0;
std::array<ReturnValue_t, 3> errorCodes = {};
void resetOfIteration() {
result = returnvalue::OK;
packetsSent = 0;
errors = 0;
errorCodes.fill(returnvalue::OK);
}
};
/**
* Will be returned if it is advisable to call the state machine operation call again
*/
ReturnValue_t PARTIAL_SUCCESS = returnvalue::makeCode(0, 2);
ReturnValue_t FAILURE = returnvalue::makeCode(0, 3);
explicit DestHandler(PduSenderIF& pduSender, size_t pduBufSize, DestHandlerParams handlerParams,
FsfwParams fsfwParams);
/**
* This is the core function to drive the destination handler. It is also used to insert
* packets into the destination handler.
*
* The state machine should either be called if packets with the appropriate destination ID
* are received and periodically to perform all CFDP related tasks, for example
* checking for timeouts or missed file segments.
*
* The function returns the number of sent PDU packets on success.
*/
const FsmResult& stateMachine(std::optional<std::reference_wrapper<PduPacketIF>> optPduPacket);
const FsmResult& stateMachineNoPacket();
void setEventReporter(EventReportingProxyIF& reporter);
[[nodiscard]] CfdpState getCfdpState() const;
[[nodiscard]] TransactionStep getTransactionStep() const;
[[nodiscard]] const TransactionId& getTransactionId() const;
[[nodiscard]] const DestHandlerParams& getDestHandlerParams() const;
private:
struct TransactionParams {
// Initialize char vectors with length + 1 for 0 termination
explicit TransactionParams(size_t maxFileNameLen)
: sourceName(maxFileNameLen + 1), destName(maxFileNameLen + 1) {}
void reset() {
pduConf = PduConfig();
transactionId = TransactionId();
std::fill(sourceName.begin(), sourceName.end(), '\0');
std::fill(destName.begin(), destName.end(), '\0');
fileSize.setFileSize(0, false);
conditionCode = ConditionCode::NO_ERROR;
deliveryCode = FileDeliveryCode::DATA_INCOMPLETE;
deliveryStatus = FileDeliveryStatus::DISCARDED_DELIBERATELY;
crc = 0;
progress = 0;
remoteCfg = nullptr;
metadataOnly = false;
closureRequested = false;
vfsErrorCount = 0;
checksumType = ChecksumType::NULL_CHECKSUM;
}
bool metadataOnly = false;
ChecksumType checksumType = ChecksumType::NULL_CHECKSUM;
bool closureRequested = false;
uint16_t vfsErrorCount = 0;
std::vector<char> sourceName;
std::vector<char> destName;
cfdp::Fss fileSize;
TransactionId transactionId;
PduConfig pduConf;
ConditionCode conditionCode = ConditionCode::NO_ERROR;
FileDeliveryCode deliveryCode = FileDeliveryCode::DATA_INCOMPLETE;
FileDeliveryStatus deliveryStatus = FileDeliveryStatus::DISCARDED_DELIBERATELY;
uint32_t crc = 0;
uint64_t progress = 0;
RemoteEntityCfg* remoteCfg = nullptr;
};
std::vector<uint8_t> pduBuf;
PduSenderIF& pduSender;
std::vector<cfdp::Tlv> tlvVec;
std::vector<MessageToUserTlv> msgToUserVec;
TransactionParams transactionParams;
DestHandlerParams destParams;
cfdp::FsfwParams fsfwParams;
FsmResult fsmRes;
ReturnValue_t startTransaction(const MetadataPduReader& reader);
ReturnValue_t handleMetadataPdu(const PduPacketIF& pduPacket);
ReturnValue_t handleFileDataPdu(const PduPacketIF& info);
ReturnValue_t handleEofPdu(const PduPacketIF& info);
ReturnValue_t handleMetadataParseError(ReturnValue_t result, const uint8_t* rawData,
size_t maxSize);
ReturnValue_t handleTransferCompletion();
ReturnValue_t tryBuildingAbsoluteDestName(size_t destNameSize);
ReturnValue_t sendFinishedPdu();
ReturnValue_t noticeOfCompletion();
ReturnValue_t checksumVerification();
void fileErrorHandler(Event event, ReturnValue_t result, const char* info) const;
const FsmResult& updateFsmRes(uint8_t errors);
void checkAndHandleError(ReturnValue_t result, uint8_t& errorIdx);
void finish();
};
} // namespace cfdp
#endif // FSFW_CFDP_CFDPDESTHANDLER_H

View File

@@ -1,18 +0,0 @@
#pragma once
#include <optional>
#include "fsfw/cfdp/definitions.h"
namespace cfdp {
class PduPacketIF {
public:
virtual ~PduPacketIF() = default;
[[nodiscard]] virtual cfdp::PduType getPduType() const = 0;
[[nodiscard]] virtual std::optional<cfdp::FileDirective> getFileDirective() const = 0;
[[nodiscard]] virtual const uint8_t* getRawPduData(size_t& pduLen) const = 0;
};
} // namespace cfdp

View File

@@ -1,17 +0,0 @@
#pragma once
#include <optional>
#include "fsfw/cfdp/definitions.h"
namespace cfdp {
class PduSenderIF {
public:
virtual ~PduSenderIF() = default;
virtual ReturnValue_t sendPdu(cfdp::PduType pduType,
std::optional<cfdp::FileDirective> fileDirective,
const uint8_t* pdu, size_t pduSize) = 0;
};
} // namespace cfdp

View File

@@ -1,201 +0,0 @@
#include "PutRequest.h"
using namespace returnvalue;
cfdp::PutRequest::PutRequest(cfdp::EntityId destId, const uint8_t *msgsToUser,
size_t msgsToUserTotalSize, const uint8_t *fsRequests,
size_t fsRequestsSize)
: destId(std::move(destId)),
metadataOnly(true),
msgsToUsersTotalSize(msgsToUserTotalSize),
msgsToUserStartPtr(msgsToUser),
fsRequestsTotalSize(fsRequestsSize),
fsRequestStartPtr(fsRequests) {}
cfdp::PutRequest::PutRequest(cfdp::EntityId destId, cfdp::StringLv &sourceName,
cfdp::StringLv &destName)
: destId(std::move(destId)), sourceName(std::move(sourceName)), destName(std::move(destName)) {}
[[nodiscard]] bool cfdp::PutRequest::isMetadataOnly() const { return metadataOnly; }
ReturnValue_t cfdp::PutRequest::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
SerializeIF::Endianness streamEndianness) const {
if (buffer == nullptr or size == nullptr) {
return FAILED;
}
if (*size + getSerializedSize() > maxSize) {
return SerializeIF::BUFFER_TOO_SHORT;
}
ReturnValue_t result = destId.serializeAsLv(buffer, size, maxSize);
if (result != OK) {
return result;
}
result = SerializeAdapter::serialize(&metadataOnly, buffer, size, maxSize, streamEndianness);
if (result != OK) {
return result;
}
if (!metadataOnly) {
result = sourceName.serialize(buffer, size, maxSize, streamEndianness);
if (result != OK) {
return result;
}
result = destName.serialize(buffer, size, maxSize, streamEndianness);
if (result != OK) {
return result;
}
result =
SerializeAdapter::serialize(&hasTransmissionMode, buffer, size, maxSize, streamEndianness);
if (result != OK) {
return result;
}
result =
SerializeAdapter::serialize(&transmissionMode, buffer, size, maxSize, streamEndianness);
if (result != OK) {
return result;
}
result =
SerializeAdapter::serialize(&hasClosureRequested, buffer, size, maxSize, streamEndianness);
if (result != OK) {
return result;
}
result =
SerializeAdapter::serialize(&closureRequested, buffer, size, maxSize, streamEndianness);
if (result != OK) {
return result;
}
}
result =
SerializeAdapter::serialize(&msgsToUsersTotalSize, buffer, size, maxSize, streamEndianness);
if (result != OK) {
return result;
}
std::memcpy(*buffer, msgsToUserStartPtr, msgsToUsersTotalSize);
*buffer += msgsToUsersTotalSize;
*size += msgsToUsersTotalSize;
result =
SerializeAdapter::serialize(&fsRequestsTotalSize, buffer, size, maxSize, streamEndianness);
if (result != OK) {
return result;
}
std::memcpy(*buffer, fsRequestStartPtr, fsRequestsTotalSize);
*buffer += fsRequestsTotalSize;
*size += fsRequestsTotalSize;
return OK;
}
ReturnValue_t cfdp::PutRequest::deSerialize(const uint8_t **buffer, size_t *size,
SerializeIF::Endianness streamEndianness) {
if (buffer == nullptr or size == nullptr) {
return FAILED;
}
ReturnValue_t result = destId.deSerializeFromLv(buffer, size);
if (result != OK) {
return result;
}
result = SerializeAdapter::deSerialize(&metadataOnly, buffer, size, streamEndianness);
if (result != OK) {
return result;
}
if (!metadataOnly) {
result = sourceName.deSerialize(buffer, size, streamEndianness);
if (result != OK) {
return result;
}
result = destName.deSerialize(buffer, size, streamEndianness);
if (result != OK) {
return result;
}
result = SerializeAdapter::deSerialize(&hasTransmissionMode, buffer, size, streamEndianness);
if (result != OK) {
return result;
}
result = SerializeAdapter::deSerialize(&transmissionMode, buffer, size, streamEndianness);
if (result != OK) {
return result;
}
result = SerializeAdapter::deSerialize(&hasClosureRequested, buffer, size, streamEndianness);
if (result != OK) {
return result;
}
result = SerializeAdapter::deSerialize(&closureRequested, buffer, size, streamEndianness);
if (result != OK) {
return result;
}
}
result = SerializeAdapter::deSerialize(&msgsToUsersTotalSize, buffer, size, streamEndianness);
if (result != OK) {
return result;
}
msgsToUserStartPtr = *buffer;
*buffer += msgsToUsersTotalSize;
*size += msgsToUsersTotalSize;
result = SerializeAdapter::deSerialize(&fsRequestsTotalSize, buffer, size, streamEndianness);
if (result != OK) {
return result;
}
fsRequestStartPtr = *buffer;
*buffer += fsRequestsTotalSize;
*size += fsRequestsTotalSize;
return OK;
}
size_t cfdp::PutRequest::getSerializedSize() const {
// Entity ID LV (1 leading size byte) and the metadata only flag.
size_t baseSize = 1 + destId.getSerializedSize() + 1;
if (!metadataOnly) {
baseSize += sourceName.getSerializedSize() + destName.getSerializedSize() + 4;
}
baseSize += sizeof(msgsToUsersTotalSize) + msgsToUsersTotalSize + sizeof(fsRequestsTotalSize) +
fsRequestsTotalSize;
return baseSize;
}
void cfdp::PutRequest::setSourceAndDestName(cfdp::StringLv &sourceName_,
cfdp::StringLv &destName_) {
metadataOnly = false;
this->sourceName = std::move(sourceName_);
this->destName = std::move(destName_);
}
const cfdp::StringLv &cfdp::PutRequest::getSourceName() const { return sourceName; }
const cfdp::StringLv &cfdp::PutRequest::getDestName() const { return destName; }
const cfdp::EntityId &cfdp::PutRequest::getDestId() const { return destId; }
void cfdp::PutRequest::setDestId(cfdp::EntityId id) { destId = std::move(id); }
void cfdp::PutRequest::setTransmissionMode(cfdp::TransmissionMode transmissionMode_) {
this->transmissionMode = transmissionMode_;
hasTransmissionMode = true;
}
void cfdp::PutRequest::clearTransmissionMode() { hasTransmissionMode = false; }
void cfdp::PutRequest::clearClosureRequest() { hasClosureRequested = false; }
void cfdp::PutRequest::setClosureRequest(bool closureRequested_) {
this->closureRequested = closureRequested_;
hasClosureRequested = true;
}
const uint8_t *cfdp::PutRequest::getMessagesToUser(size_t &totalSize) {
totalSize = this->msgsToUsersTotalSize;
return msgsToUserStartPtr;
}
bool cfdp::PutRequest::getClosureRequested(bool &closureRequested_) const {
if (hasClosureRequested) {
closureRequested_ = this->closureRequested;
}
return hasClosureRequested;
}
bool cfdp::PutRequest::getTransmissionMode(cfdp::TransmissionMode &mode) const {
if (hasTransmissionMode) {
mode = static_cast<cfdp::TransmissionMode>(this->transmissionMode);
}
return hasTransmissionMode;
}

View File

@@ -1,82 +0,0 @@
#pragma once
#include <optional>
#include <vector>
#include "fsfw/cfdp/VarLenFields.h"
#include "fsfw/cfdp/tlv/FilestoreRequestTlv.h"
#include "fsfw/cfdp/tlv/MessageToUserTlv.h"
namespace cfdp {
class PutRequest : public SerializeIF {
public:
/**
* Metadata only constructor.
* @param destId
* @param msgsToUser
* @param msgsToUserTotalSize
* @param fsRequests
* @param fsRequestsSize
*/
PutRequest(EntityId destId, const uint8_t* msgsToUser, size_t msgsToUserTotalSize,
const uint8_t* fsRequests, size_t fsRequestsSize);
/**
* Put request to initiate file transfers. By default, the transmission mode and closure requested
* parameter are not present, thereby being derived from the remote configuration for a
* particular destination ID.
* @param destId
* @param sourceName
* @param destName
*/
PutRequest(EntityId destId, cfdp::StringLv& sourceName, cfdp::StringLv& destName);
/**
* Default constructor for deserialization.
*/
PutRequest() = default;
[[nodiscard]] ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
Endianness streamEndianness) const override;
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) override;
[[nodiscard]] size_t getSerializedSize() const override;
void setSourceAndDestName(cfdp::StringLv& sourceName, cfdp::StringLv& destName);
[[nodiscard]] const cfdp::StringLv& getSourceName() const;
[[nodiscard]] const cfdp::StringLv& getDestName() const;
void setTransmissionMode(cfdp::TransmissionMode transmissionMode);
void clearTransmissionMode();
void setClosureRequest(bool closureRequested);
void clearClosureRequest();
const uint8_t* getMessagesToUser(size_t& msgSize);
[[nodiscard]] bool isMetadataOnly() const;
bool getTransmissionMode(TransmissionMode& mode) const;
bool getClosureRequested(bool& closureRequested) const;
[[nodiscard]] const EntityId& getDestId() const;
void setDestId(EntityId id);
private:
EntityId destId;
uint8_t metadataOnly = true;
// Transaction parameters. Omitted if the put request is metadata only.
cfdp::StringLv sourceName;
cfdp::StringLv destName;
bool hasTransmissionMode = false;
uint8_t transmissionMode = TransmissionMode::UNACKNOWLEDGED;
bool hasClosureRequested = false;
uint8_t closureRequested = false;
// Metadata
size_t msgsToUsersTotalSize = 0;
const uint8_t* msgsToUserStartPtr = nullptr;
size_t fsRequestsTotalSize = 0;
const uint8_t* fsRequestStartPtr = nullptr;
};
} // namespace cfdp

View File

@@ -16,7 +16,7 @@ class RemoteConfigTableIF {
*/
class OneRemoteConfigProvider : public RemoteConfigTableIF {
public:
explicit OneRemoteConfigProvider(RemoteEntityCfg& cfg) : cfg(cfg) {}
explicit OneRemoteConfigProvider(RemoteEntityCfg cfg) : cfg(std::move(cfg)) {}
bool getRemoteCfg(const EntityId& remoteId, cfdp::RemoteEntityCfg** cfg_) override {
if (remoteId != cfg.remoteId) {
@@ -27,7 +27,7 @@ class OneRemoteConfigProvider : public RemoteConfigTableIF {
}
private:
RemoteEntityCfg& cfg;
RemoteEntityCfg cfg;
};
} // namespace cfdp

View File

@@ -1,71 +0,0 @@
#include "ReservedMessageParser.h"
#include "fsfw/cfdp/CfdpMessage.h"
#include "fsfw/cfdp/handler/PutRequest.h"
#include "fsfw/cfdp/tlv/MessageToUserTlv.h"
#include "fsfw/ipc/CommandMessage.h"
#include "fsfw/ipc/QueueFactory.h"
using namespace returnvalue;
cfdp::ReservedMessageParser::ReservedMessageParser(StorageManagerIF& ipcStore,
MessageQueueIF& msgQueue,
MessageQueueId_t userDestination)
: msgQueue(msgQueue), ipcStore(ipcStore), userDestination(userDestination) {}
ReturnValue_t cfdp::ReservedMessageParser::parse(const MessageToUserTlv* msgsToUserArray,
size_t numMsgToUser) const {
ReturnValue_t result = returnvalue::OK;
cfdp::StringLv sourceFileName;
cfdp::StringLv destFileName;
PutRequest putRequest;
const uint8_t* currentPtr = nullptr;
size_t deserSize = 0;
bool needToSendPutRequest = false;
for (size_t idx = 0; idx < numMsgToUser; idx++) {
uint8_t messageType = 0;
if (not msgsToUserArray[idx].isReservedCfdpMessage(messageType, &currentPtr, deserSize)) {
continue;
}
if (messageType == static_cast<uint8_t>(ProxyOpMessageType::PUT_REQUEST)) {
EntityId entityIdLv;
result = entityIdLv.deSerializeFromLv(&currentPtr, &deserSize);
if (result != returnvalue::OK) {
return result;
}
putRequest.setDestId(entityIdLv);
result =
sourceFileName.deSerialize(&currentPtr, &deserSize, SerializeIF::Endianness::NETWORK);
if (result != OK) {
return result;
}
result = destFileName.deSerialize(&currentPtr, &deserSize, SerializeIF::Endianness::NETWORK);
if (result != OK) {
return result;
}
putRequest.setSourceAndDestName(sourceFileName, destFileName);
needToSendPutRequest = true;
}
}
if (needToSendPutRequest) {
store_address_t storeId;
uint8_t* dataPtr;
result = ipcStore.getFreeElement(&storeId, putRequest.getSerializedSize(), &dataPtr);
if (result != OK) {
return result;
}
size_t serLen = 0;
result = putRequest.serialize(&dataPtr, &serLen, putRequest.getSerializedSize(),
SerializeIF::Endianness::MACHINE);
if (result != OK) {
return result;
}
CommandMessage msg;
CfdpMessage::setPutRequest(&msg, storeId);
result = msgQueue.sendMessage(userDestination, &msg);
if (result != OK) {
return result;
}
}
return OK;
}

View File

@@ -1,27 +0,0 @@
#pragma once
#include "fsfw/cfdp/tlv/MessageToUserTlv.h"
#include "fsfw/ipc/MessageQueueIF.h"
#include "fsfw/storagemanager/StorageManagerIF.h"
namespace cfdp {
/**
* This class parses messages to user for special CFDP messages and converts them to appropriate
* CFDP requests sent via the IPC store where applicable. It also provides an API to retrieve
* custom messages which are not special CFDP messages from a provided bytestream.
*/
class ReservedMessageParser {
public:
ReservedMessageParser(StorageManagerIF& ipcStore, MessageQueueIF& msgQueue,
MessageQueueId_t userDestination);
ReturnValue_t parse(const MessageToUserTlv* msgsToUserArray, size_t numMsgsToUser) const;
private:
MessageQueueIF& msgQueue;
StorageManagerIF& ipcStore;
MessageQueueId_t userDestination;
};
} // namespace cfdp

View File

@@ -1,358 +0,0 @@
#include "SourceHandler.h"
#include <etl/crc32.h>
#include <array>
#include "fsfw/cfdp/pdu/EofPduCreator.h"
#include "fsfw/cfdp/pdu/FileDataCreator.h"
#include "fsfw/cfdp/pdu/MetadataPduCreator.h"
#include "fsfw/filesystem/HasFileSystemIF.h"
#include "fsfw/globalfunctions/arrayprinter.h"
#include "fsfw/objectmanager.h"
#include "fsfw/serviceinterface.h"
#include "fsfw/tasks/TaskFactory.h"
#include "fsfw/tmtcservices/TmTcMessage.h"
using namespace returnvalue;
cfdp::SourceHandler::SourceHandler(PduSenderIF& pduSender, size_t pduBufferSize,
SourceHandlerParams params, FsfwParams fsfwParams)
: pduSender(pduSender),
pduBuf(pduBufferSize),
sourceParams(std::move(params)),
fsfwParams(fsfwParams) {
// The entity ID portion of the transaction ID will always remain fixed.
transactionParams.id.entityId = sourceParams.cfg.localId;
transactionParams.pduConf.sourceId = sourceParams.cfg.localId;
if (sourceParams.seqCountProvider.bitWidth() == 8) {
transactionParams.pduConf.seqNum.setWidth(cfdp::WidthInBytes::ONE_BYTE);
} else if (sourceParams.seqCountProvider.bitWidth() == 16) {
transactionParams.pduConf.seqNum.setWidth(cfdp::WidthInBytes::TWO_BYTES);
} else if (sourceParams.seqCountProvider.bitWidth() == 32) {
transactionParams.pduConf.seqNum.setWidth(cfdp::WidthInBytes::FOUR_BYTES);
} else if (sourceParams.seqCountProvider.bitWidth() == 64) {
transactionParams.pduConf.seqNum.setWidth(cfdp::WidthInBytes::EIGHT_BYTES);
} else {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "cfdp::SourceHandler: Seq count provider bit width "
<< sourceParams.seqCountProvider.bitWidth() << " not allowed" << std::endl;
#else
sif::printError("cfdp::SourceHandler: Seq count provider bit width %d not allowed\n",
sourceParams.seqCountProvider.bitWidth());
#endif
// Yeah, what am I supposed to do here? Can't throw an exception in the FSFW..
transactionParams.pduConf.seqNum.setWidth(cfdp::WidthInBytes::ONE_BYTE);
}
transactionParams.pduConf.seqNum.setValue(0);
}
cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() {
ReturnValue_t result;
if (step == TransactionStep::IDLE) {
step = TransactionStep::TRANSACTION_START;
}
if (step == TransactionStep::TRANSACTION_START) {
sourceParams.user.transactionIndication(transactionParams.id);
result = checksumGeneration();
if (result != OK) {
addError(result);
}
step = TransactionStep::SENDING_METADATA;
}
if (step == TransactionStep::SENDING_METADATA) {
result = prepareAndSendMetadataPdu();
if (result != OK) {
addError(result);
}
// fsmResult.callStatus = CallStatus::CALL_AGAIN;
return fsmResult;
}
if (step == TransactionStep::SENDING_FILE_DATA) {
bool noFdPdu = false;
result = prepareAndSendNextFileDataPdu(noFdPdu);
if (result == OK and !noFdPdu) {
// fsmResult.callStatus = CallStatus::CALL_AGAIN;
return fsmResult;
}
}
if (step == TransactionStep::SENDING_EOF) {
result = prepareAndSendEofPdu();
if (result != OK) {
addError(result);
}
if (sourceParams.cfg.indicCfg.eofSentIndicRequired) {
sourceParams.user.eofSentIndication(transactionParams.id);
}
if (transactionParams.closureRequested) {
step = TransactionStep::WAIT_FOR_FINISH;
// fsmResult.callStatus = CallStatus::CALL_AFTER_DELAY;
} else {
step = TransactionStep::NOTICE_OF_COMPLETION;
// fsmResult.callStatus = CallStatus::CALL_AGAIN;
}
return fsmResult;
}
if (step == TransactionStep::WAIT_FOR_FINISH) {
// TODO: In case this is a request with closure, wait for finish.
// Done, issue notice of completion
step = TransactionStep::NOTICE_OF_COMPLETION;
}
if (step == TransactionStep::NOTICE_OF_COMPLETION) {
noticeOfCompletion();
reset();
}
return fsmResult;
}
const cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::stateMachineNoPacket() {
return stateMachine(std::nullopt);
}
const cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::stateMachine(
std::optional<std::reference_wrapper<PduPacketIF>> optPduPacket) {
fsmResult.packetsSent = 0;
fsmResult.errors = 0;
if (state == cfdp::CfdpState::IDLE) {
return fsmResult;
}
if (state == cfdp::CfdpState::BUSY_CLASS_1_NACKED) {
return fsmNacked();
}
return fsmResult;
}
ReturnValue_t cfdp::SourceHandler::checksumGeneration() {
if (transactionParams.fileSize.value() == 0) {
// NULL checksum for empty file.
transactionParams.crc = 0;
return OK;
}
std::array<uint8_t, 1024> buf{};
etl::crc32 crcCalc;
uint64_t currentOffset = 0;
while (currentOffset < transactionParams.fileSize.value()) {
uint64_t lenToRead;
if (currentOffset + buf.size() > transactionParams.fileSize.value()) {
lenToRead = transactionParams.fileSize.value() - currentOffset;
} else {
lenToRead = buf.size();
}
if (lenToRead > 0) {
size_t readLen = 0;
auto result =
sourceParams.user.vfs.readFromFile(transactionParams.sourceName.data(), currentOffset,
lenToRead, buf.data(), readLen, buf.size());
if (result != OK) {
addError(result);
return FAILED;
}
crcCalc.add(buf.begin(), buf.begin() + lenToRead);
}
currentOffset += lenToRead;
}
transactionParams.crc = crcCalc.value();
return OK;
}
ReturnValue_t cfdp::SourceHandler::transactionStart(PutRequest& putRequest, RemoteEntityCfg& cfg) {
if (state != CfdpState::IDLE) {
return SOURCE_TRANSACTION_PENDING;
}
if (cfg.remoteId != putRequest.getDestId()) {
return WRONG_REMOTE_CFG_ENTITY_ID;
}
if (putRequest.getSourceName().getValueLen() == 0) {
return SOURCE_NAME_EMPTY;
}
if (putRequest.getDestName().getValueLen() == 0) {
return DEST_NAME_EMPTY;
}
const char* srcNamePtr = putRequest.getSourceName().getCString(transactionParams.sourceNameSize);
const char* destNamePtr = putRequest.getDestName().getCString(transactionParams.destNameSize);
std::strncpy(transactionParams.sourceName.data(), srcNamePtr, transactionParams.sourceNameSize);
std::strncpy(transactionParams.destName.data(), destNamePtr, transactionParams.destNameSize);
// Add 0 termination. The source and dest name size can not be larger than UINT8_MAX, so this
// operation is safe.
transactionParams.sourceName[transactionParams.sourceNameSize] = '\0';
transactionParams.destName[transactionParams.destNameSize] = '\0';
if (!sourceParams.user.vfs.fileExists(transactionParams.sourceName.data())) {
return FILE_DOES_NOT_EXIST;
}
if (cfg.maxFileSegmentLen > fileBuf.size() or cfg.maxFileSegmentLen == 0) {
return FILE_SEGMENT_LEN_INVALID;
}
// If transmission mode is not set, use default transmission mode for the remote entity.
if (not putRequest.getTransmissionMode(transactionParams.pduConf.mode)) {
transactionParams.pduConf.mode = cfg.defaultTransmissionMode;
}
// If closure request field is not set, use default option for the remote entity.
if (not putRequest.getClosureRequested(transactionParams.closureRequested)) {
transactionParams.closureRequested = cfg.closureRequested;
}
const EntityId& destId = putRequest.getDestId();
// The width of the source and destination ID must be the same. Use the larger ID value to
// ensure the width is large enough for both IDs
if (destId.getWidth() > transactionParams.pduConf.sourceId.getWidth()) {
transactionParams.pduConf.destId = destId;
transactionParams.pduConf.sourceId.setWidth(destId.getWidth());
} else {
transactionParams.pduConf.destId.setValueAndWidth(transactionParams.pduConf.sourceId.getWidth(),
destId.getValue());
}
// Only used for PDU forwarding, file is sent to file receiver regularly here.
transactionParams.pduConf.direction = Direction::TOWARDS_RECEIVER;
transactionParams.pduConf.seqNum.setValue(sourceParams.seqCountProvider.getAndIncrement());
transactionParams.id.seqNum = transactionParams.pduConf.seqNum;
if (transactionParams.pduConf.mode == TransmissionMode::ACKNOWLEDGED) {
state = cfdp::CfdpState::BUSY_CLASS_2_ACKED;
} else if (transactionParams.pduConf.mode == TransmissionMode::UNACKNOWLEDGED) {
state = cfdp::CfdpState::BUSY_CLASS_1_NACKED;
}
step = TransactionStep::IDLE;
uint64_t fileSize = 0;
sourceParams.user.vfs.getFileSize(transactionParams.sourceName.data(), fileSize);
transactionParams.pduConf.largeFile = false;
if (fileSize > UINT32_MAX) {
transactionParams.pduConf.largeFile = true;
}
if (fileSize == 0) {
transactionParams.checksumType = ChecksumType::NULL_CHECKSUM;
} else {
transactionParams.checksumType = ChecksumType::CRC_32;
}
transactionParams.fileSize.setFileSize(fileSize, transactionParams.pduConf.largeFile);
transactionParams.progress = 0;
transactionParams.remoteCfg = cfg;
return OK;
}
ReturnValue_t cfdp::SourceHandler::prepareAndSendMetadataPdu() {
cfdp::StringLv sourceName(transactionParams.sourceName.data(), transactionParams.sourceNameSize);
cfdp::StringLv destName(transactionParams.destName.data(), transactionParams.destNameSize);
auto metadataInfo =
MetadataGenericInfo(transactionParams.closureRequested, transactionParams.checksumType,
transactionParams.fileSize);
auto metadataPdu =
MetadataPduCreator(transactionParams.pduConf, metadataInfo, sourceName, destName, nullptr, 0);
ReturnValue_t result =
sendGenericPdu(PduType::FILE_DIRECTIVE, FileDirective::METADATA, metadataPdu);
if (result != OK) {
return result;
}
// Advance FSM if everything works
step = TransactionStep::SENDING_FILE_DATA;
return OK;
}
ReturnValue_t cfdp::SourceHandler::prepareAndSendNextFileDataPdu(bool& noFileDataPdu) {
cfdp::Fss offset(transactionParams.progress);
uint64_t lenToRead;
uint64_t fileSize = transactionParams.fileSize.value();
noFileDataPdu = false;
if (fileSize == 0) {
// We are done, no need to send file data PDUs for an empty file.
step = TransactionStep::SENDING_EOF;
noFileDataPdu = true;
return OK;
}
if (fileSize < transactionParams.remoteCfg.maxFileSegmentLen) {
lenToRead = transactionParams.fileSize.value();
} else {
if (transactionParams.progress + transactionParams.remoteCfg.maxFileSegmentLen > fileSize) {
lenToRead = fileSize - transactionParams.progress;
} else {
lenToRead = transactionParams.remoteCfg.maxFileSegmentLen;
}
}
FileOpParams fileParams(transactionParams.sourceName.data(), lenToRead);
fileParams.offset = transactionParams.progress;
size_t readLen = 0;
ReturnValue_t result = sourceParams.user.vfs.readFromFile(
transactionParams.sourceName.data(), transactionParams.progress, lenToRead, fileBuf.data(),
readLen, fileBuf.size());
if (result != returnvalue::OK) {
addError(result);
return result;
}
auto fileDataInfo = FileDataInfo(offset, fileBuf.data(), lenToRead);
auto fileDataPdu = FileDataCreator(transactionParams.pduConf, fileDataInfo);
result = sendGenericPdu(PduType::FILE_DATA, std::nullopt, fileDataPdu);
if (result != OK) {
return result;
}
transactionParams.progress += lenToRead;
if (transactionParams.progress >= fileSize) {
// Advance FSM after all file data PDUs were sent.
step = TransactionStep::SENDING_EOF;
}
return OK;
}
ReturnValue_t cfdp::SourceHandler::prepareAndSendEofPdu() {
auto eofInfo =
EofInfo(ConditionCode::NO_ERROR, transactionParams.crc, transactionParams.fileSize);
auto eofPdu = EofPduCreator(transactionParams.pduConf, eofInfo);
ReturnValue_t result =
sendGenericPdu(PduType::FILE_DIRECTIVE, FileDirective::EOF_DIRECTIVE, eofPdu);
if (result != OK) {
return result;
}
return OK;
}
ReturnValue_t cfdp::SourceHandler::initialize() { return OK; }
ReturnValue_t cfdp::SourceHandler::sendGenericPdu(PduType pduType,
std::optional<FileDirective> fileDirective,
const SerializeIF& pdu) {
store_address_t storeId;
if (pdu.getSerializedSize() > pduBuf.size()) {
addError(PDU_BUFFER_TOO_SMALL);
return PDU_BUFFER_TOO_SMALL;
}
size_t serializedLen = 0;
ReturnValue_t result = pdu.serializeBe(pduBuf.data(), serializedLen, pdu.getSerializedSize());
if (result != OK) {
addError(result);
return result;
}
pduSender.sendPdu(pduType, fileDirective, pduBuf.data(), serializedLen);
fsmResult.packetsSent += 1;
return result;
}
ReturnValue_t cfdp::SourceHandler::noticeOfCompletion() {
if (sourceParams.cfg.indicCfg.transactionFinishedIndicRequired) {
// TODO: This could still be improved by caching the Finished PDU parameters.
FileDeliveryStatus deliveryStatus = FileDeliveryStatus::FILE_STATUS_UNREPORTED;
if (transactionParams.closureRequested) {
deliveryStatus = FileDeliveryStatus::RETAINED_IN_FILESTORE;
}
cfdp::TransactionFinishedParams params(transactionParams.id, ConditionCode::NO_ERROR,
FileDeliveryCode::DATA_COMPLETE, deliveryStatus);
sourceParams.user.transactionFinishedIndication(params);
}
return OK;
}
ReturnValue_t cfdp::SourceHandler::reset() {
step = TransactionStep::IDLE;
state = cfdp::CfdpState::IDLE;
// fsmResult.callStatus = CallStatus::DONE;
transactionParams.reset();
return OK;
}
cfdp::CfdpState cfdp::SourceHandler::getState() const { return state; }
cfdp::SourceHandler::TransactionStep cfdp::SourceHandler::getStep() const { return step; }
void cfdp::SourceHandler::addError(ReturnValue_t error) {
if (fsmResult.errors < fsmResult.errorCodes.size()) {
fsmResult.errorCodes[fsmResult.errors] = error;
fsmResult.errors++;
fsmResult.result = error;
}
}

View File

@@ -1,118 +0,0 @@
#ifndef FSFW_CFDP_CFDPSOURCEHANDLER_H
#define FSFW_CFDP_CFDPSOURCEHANDLER_H
#include <cstdint>
#include <vector>
#include "PduPacketIF.h"
#include "PduSenderIF.h"
#include "UserBase.h"
#include "defs.h"
#include "fsfw/cfdp/Fss.h"
#include "fsfw/cfdp/handler/PutRequest.h"
#include "fsfw/cfdp/handler/mib.h"
#include "fsfw/events/EventReportingProxyIF.h"
#include "fsfw/storagemanager/StorageManagerIF.h"
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
#include "fsfw/util/ProvidesSeqCountIF.h"
namespace cfdp {
struct SourceHandlerParams {
SourceHandlerParams(LocalEntityCfg cfg, UserBase& user, ProvidesSeqCountIF& seqCountProvider)
: cfg(std::move(cfg)), user(user), seqCountProvider(seqCountProvider) {}
LocalEntityCfg cfg;
UserBase& user;
ProvidesSeqCountIF& seqCountProvider;
};
class SourceHandler {
public:
enum class TransactionStep : uint8_t {
IDLE = 0,
TRANSACTION_START = 1,
SENDING_METADATA = 3,
SENDING_FILE_DATA = 4,
SENDING_EOF = 5,
WAIT_FOR_ACK = 6,
WAIT_FOR_FINISH = 7,
NOTICE_OF_COMPLETION = 8
};
struct FsmResult {
public:
ReturnValue_t result = returnvalue::OK;
uint32_t packetsSent = 0;
// CallStatus callStatus = CallStatus::CALL_AFTER_DELAY;
CfdpState state = CfdpState::IDLE;
uint8_t errors = 0;
std::array<ReturnValue_t, 3> errorCodes = {};
};
SourceHandler(PduSenderIF& pduSender, size_t pduBufferSize, SourceHandlerParams params,
FsfwParams fsfwParams);
[[nodiscard]] CfdpState getState() const;
[[nodiscard]] TransactionStep getStep() const;
/**
* Pass a put request to the source handler, which might initiate a CFDP transaction and start
* the state machine
* @return
*/
ReturnValue_t transactionStart(PutRequest& putRequest, RemoteEntityCfg& cfg);
const FsmResult& stateMachine(std::optional<std::reference_wrapper<PduPacketIF>> optPduPacket);
const FsmResult& stateMachineNoPacket();
ReturnValue_t initialize();
private:
struct TransactionParams {
uint32_t crc{};
std::array<char, UINT8_MAX + 1> sourceName{};
size_t sourceNameSize = 0;
std::array<char, UINT8_MAX + 1> destName{};
size_t destNameSize = 0;
cfdp::Fss fileSize;
size_t progress = 0;
bool closureRequested = false;
ChecksumType checksumType = ChecksumType::NULL_CHECKSUM;
RemoteEntityCfg remoteCfg;
PduConfig pduConf;
cfdp::TransactionId id{};
void reset() {
sourceNameSize = 0;
destNameSize = 0;
fileSize.setFileSize(0, false);
progress = 0;
closureRequested = false;
}
} transactionParams;
PduSenderIF& pduSender;
std::vector<uint8_t> pduBuf;
cfdp::CfdpState state = cfdp::CfdpState::IDLE;
TransactionStep step = TransactionStep::IDLE;
std::array<uint8_t, 4096> fileBuf{};
SourceHandlerParams sourceParams;
cfdp::FsfwParams fsfwParams;
FsmResult fsmResult;
FsmResult& fsmNacked();
ReturnValue_t checksumGeneration();
ReturnValue_t prepareAndSendMetadataPdu();
ReturnValue_t prepareAndSendNextFileDataPdu(bool& noFileDataPdu);
ReturnValue_t prepareAndSendEofPdu();
ReturnValue_t noticeOfCompletion();
ReturnValue_t reset();
[[nodiscard]] ReturnValue_t sendGenericPdu(PduType pduType,
std::optional<FileDirective> fileDirective,
const SerializeIF& pdu);
void addError(ReturnValue_t error);
};
} // namespace cfdp
#endif // FSFW_CFDP_CFDPSOURCEHANDLER_H

View File

@@ -6,7 +6,6 @@
#include <vector>
#include "StatusReportIF.h"
#include "fsfw/cfdp/Fss.h"
#include "fsfw/cfdp/VarLenFields.h"
#include "fsfw/cfdp/tlv/FilestoreResponseTlv.h"
#include "fsfw/cfdp/tlv/MessageToUserTlv.h"
@@ -28,14 +27,14 @@ struct TransactionFinishedParams {
};
struct MetadataRecvdParams {
MetadataRecvdParams(const TransactionId& id, const EntityId& sourceId, Fss fileSize)
: id(id), sourceId(sourceId), fileSize(std::move(fileSize)) {}
MetadataRecvdParams(const TransactionId& id, const EntityId& sourceId)
: id(id), sourceId(sourceId) {}
const TransactionId& id;
const EntityId& sourceId;
Fss fileSize{};
uint64_t fileSize = 0;
const char* sourceFileName = "";
const char* destFileName = "";
size_t numberOfMsgsToUser = 0;
size_t msgsToUserLen = 0;
const MessageToUserTlv* msgsToUserArray = nullptr;
};
@@ -66,7 +65,6 @@ struct FileSegmentRecvdParams {
*/
class UserBase {
friend class DestHandler;
friend class SourceHandler;
public:
explicit UserBase(HasFileSystemIF& vfs);

View File

@@ -1,41 +1,9 @@
#pragma once
#include <etl/list.h>
#include "fsfw/storagemanager/StorageManagerIF.h"
#include "fsfw/storagemanager/storeAddress.h"
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
#ifndef FSFW_CFDP_HANDLER_DEFS_H
#define FSFW_CFDP_HANDLER_DEFS_H
namespace cfdp {
enum class CfdpState { IDLE, BUSY_CLASS_1_NACKED, BUSY_CLASS_2_ACKED, SUSPENDED };
static constexpr uint8_t SSID = SUBSYSTEM_ID::CFDP;
static constexpr uint8_t CID = CLASS_ID::CFDP_HANDLER;
enum class CfdpStates { IDLE, BUSY_CLASS_1_NACKED, BUSY_CLASS_2_ACKED, SUSPENDED };
struct FsfwParams {
FsfwParams(EventReportingProxyIF* eventReporter) : eventReporter(eventReporter) {}
EventReportingProxyIF* eventReporter = nullptr;
};
namespace events {
static constexpr Event PDU_SEND_ERROR = event::makeEvent(SSID, 1, severity::LOW);
static constexpr Event SERIALIZATION_ERROR = event::makeEvent(SSID, 2, severity::LOW);
static constexpr Event FILESTORE_ERROR = event::makeEvent(SSID, 3, severity::LOW);
//! [EXPORT] : [COMMENT] P1: Transaction step ID, P2: 0 for source file name, 1 for dest file name
static constexpr Event FILENAME_TOO_LARGE_ERROR = event::makeEvent(SSID, 4, severity::LOW);
//! [EXPORT] : [COMMENT] CFDP request handling failed. P2: Returncode.
static constexpr Event HANDLING_CFDP_REQUEST_FAILED = event::makeEvent(SSID, 5, severity::LOW);
} // namespace events
static constexpr ReturnValue_t SOURCE_TRANSACTION_PENDING = returnvalue::makeCode(CID, 0);
static constexpr ReturnValue_t FILE_DOES_NOT_EXIST = returnvalue::makeCode(CID, 1);
static constexpr ReturnValue_t FILE_SEGMENT_LEN_INVALID = returnvalue::makeCode(CID, 2);
static constexpr ReturnValue_t SOURCE_NAME_EMPTY = returnvalue::makeCode(CID, 3);
static constexpr ReturnValue_t DEST_NAME_EMPTY = returnvalue::makeCode(CID, 4);
static constexpr ReturnValue_t WRONG_REMOTE_CFG_ENTITY_ID = returnvalue::makeCode(CID, 5);
static constexpr ReturnValue_t TARGET_MSG_QUEUE_FULL = returnvalue::makeCode(CID, 6);
static constexpr ReturnValue_t TM_STORE_FULL = returnvalue::makeCode(CID, 7);
static constexpr ReturnValue_t DEST_NON_METADATA_PDU_AS_FIRST_PDU = returnvalue::makeCode(CID, 8);
static constexpr ReturnValue_t PDU_BUFFER_TOO_SMALL = returnvalue::makeCode(CID, 9);
} // namespace cfdp
}
#endif // FSFW_CFDP_HANDLER_DEFS_H

View File

@@ -27,15 +27,14 @@ struct LocalEntityCfg {
};
struct RemoteEntityCfg {
RemoteEntityCfg() = default;
explicit RemoteEntityCfg(EntityId id) : remoteId(std::move(id)) {}
EntityId remoteId;
size_t maxFileSegmentLen = 1024;
size_t maxFileSegmentLen = 2048;
bool closureRequested = false;
bool crcOnTransmission = false;
TransmissionMode defaultTransmissionMode = TransmissionMode::UNACKNOWLEDGED;
ChecksumType defaultChecksum = ChecksumType::NULL_CHECKSUM;
uint8_t version = CFDP_VERSION_2;
const uint8_t version = CFDP_VERSION_2;
};
} // namespace cfdp

View File

@@ -1,7 +1,5 @@
#include "AckPduCreator.h"
#include "fsfw/globalfunctions/CRC.h"
AckPduCreator::AckPduCreator(AckInfo &ackInfo, PduConfig &pduConf)
: FileDirectiveCreator(pduConf, cfdp::FileDirective::ACK, 2), ackInfo(ackInfo) {}
@@ -9,7 +7,6 @@ size_t AckPduCreator::getSerializedSize() const { return FileDirectiveCreator::g
ReturnValue_t AckPduCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
Endianness streamEndianness) const {
const uint8_t *start = *buffer;
ReturnValue_t result = FileDirectiveCreator::serialize(buffer, size, maxSize, streamEndianness);
if (result != returnvalue::OK) {
return result;
@@ -32,10 +29,5 @@ ReturnValue_t AckPduCreator::serialize(uint8_t **buffer, size_t *size, size_t ma
**buffer = ackedConditionCode << 4 | transactionStatus;
*buffer += 1;
*size += 1;
if (getCrcFlag()) {
uint16_t crc = CRC::crc16ccitt(start, getWholePduSize() - 2);
result = SerializeAdapter::serialize(&crc, buffer, size, maxSize, streamEndianness);
}
return returnvalue::OK;
}

View File

@@ -17,7 +17,7 @@ target_sources(
FinishedInfo.cpp
FinishedPduCreator.cpp
FinishedPduReader.cpp
MetadataGenericInfo.cpp
MetadataInfo.cpp
MetadataPduCreator.cpp
MetadataPduReader.cpp
KeepAlivePduCreator.cpp

View File

@@ -1,13 +1,8 @@
#include "EofInfo.h"
#include <utility>
EofInfo::EofInfo(cfdp::ConditionCode conditionCode, uint32_t checksum, cfdp::Fss fileSize,
EofInfo::EofInfo(cfdp::ConditionCode conditionCode, uint32_t checksum, cfdp::FileSize fileSize,
EntityIdTlv* faultLoc)
: conditionCode(conditionCode),
checksum(checksum),
fileSize(std::move(fileSize)),
faultLoc(faultLoc) {}
: conditionCode(conditionCode), checksum(checksum), fileSize(fileSize), faultLoc(faultLoc) {}
EofInfo::EofInfo(EntityIdTlv* faultLoc)
: conditionCode(cfdp::ConditionCode::NO_CONDITION_FIELD),
@@ -21,15 +16,15 @@ cfdp::ConditionCode EofInfo::getConditionCode() const { return conditionCode; }
EntityIdTlv* EofInfo::getFaultLoc() const { return faultLoc; }
cfdp::Fss& EofInfo::getFileSize() { return fileSize; }
cfdp::FileSize& EofInfo::getFileSize() { return fileSize; }
void EofInfo::setChecksum(uint32_t checksum_) { this->checksum = checksum_; }
void EofInfo::setChecksum(uint32_t checksum) { this->checksum = checksum; }
void EofInfo::setConditionCode(cfdp::ConditionCode conditionCode_) {
this->conditionCode = conditionCode_;
void EofInfo::setConditionCode(cfdp::ConditionCode conditionCode) {
this->conditionCode = conditionCode;
}
void EofInfo::setFaultLoc(EntityIdTlv* faultLoc_) { this->faultLoc = faultLoc_; }
void EofInfo::setFaultLoc(EntityIdTlv* faultLoc) { this->faultLoc = faultLoc; }
size_t EofInfo::getSerializedSize(bool fssLarge) {
// Condition code + spare + 4 byte checksum
@@ -47,6 +42,6 @@ size_t EofInfo::getSerializedSize(bool fssLarge) {
return size;
}
ReturnValue_t EofInfo::setFileSize(size_t fileSize_, bool isLarge) {
return this->fileSize.setFileSize(fileSize_, isLarge);
ReturnValue_t EofInfo::setFileSize(size_t fileSize, bool isLarge) {
return this->fileSize.setFileSize(fileSize, isLarge);
}

View File

@@ -1,14 +1,14 @@
#ifndef FSFW_SRC_FSFW_CFDP_PDU_EOFINFO_H_
#define FSFW_SRC_FSFW_CFDP_PDU_EOFINFO_H_
#include "../Fss.h"
#include "../FileSize.h"
#include "../definitions.h"
#include "fsfw/cfdp/tlv/EntityIdTlv.h"
struct EofInfo {
public:
explicit EofInfo(EntityIdTlv* faultLoc = nullptr);
EofInfo(cfdp::ConditionCode conditionCode, uint32_t checksum, cfdp::Fss fileSize,
EofInfo(cfdp::ConditionCode conditionCode, uint32_t checksum, cfdp::FileSize fileSize,
EntityIdTlv* faultLoc = nullptr);
size_t getSerializedSize(bool fssLarge = false);
@@ -17,7 +17,7 @@ struct EofInfo {
[[nodiscard]] cfdp::ConditionCode getConditionCode() const;
[[nodiscard]] EntityIdTlv* getFaultLoc() const;
cfdp::Fss& getFileSize();
cfdp::FileSize& getFileSize();
void setChecksum(uint32_t checksum);
void setConditionCode(cfdp::ConditionCode conditionCode);
void setFaultLoc(EntityIdTlv* faultLoc);
@@ -26,7 +26,7 @@ struct EofInfo {
private:
cfdp::ConditionCode conditionCode;
uint32_t checksum;
cfdp::Fss fileSize;
cfdp::FileSize fileSize;
EntityIdTlv* faultLoc = nullptr;
};

View File

@@ -1,7 +1,6 @@
#include "EofPduCreator.h"
#include "fsfw/FSFW.h"
#include "fsfw/globalfunctions/CRC.h"
EofPduCreator::EofPduCreator(PduConfig &conf, EofInfo &info)
: FileDirectiveCreator(conf, cfdp::FileDirective::EOF_DIRECTIVE, 9), info(info) {
@@ -12,7 +11,6 @@ size_t EofPduCreator::getSerializedSize() const { return FileDirectiveCreator::g
ReturnValue_t EofPduCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
Endianness streamEndianness) const {
const uint8_t *start = *buffer;
ReturnValue_t result = FileDirectiveCreator::serialize(buffer, size, maxSize, streamEndianness);
if (result != returnvalue::OK) {
return result;
@@ -38,9 +36,5 @@ ReturnValue_t EofPduCreator::serialize(uint8_t **buffer, size_t *size, size_t ma
if (info.getFaultLoc() != nullptr and info.getConditionCode() != cfdp::ConditionCode::NO_ERROR) {
result = info.getFaultLoc()->serialize(buffer, size, maxSize, streamEndianness);
}
if (getCrcFlag()) {
uint16_t crc = CRC::crc16ccitt(start, getWholePduSize() - 2);
result = SerializeAdapter::serialize(&crc, buffer, size, maxSize, streamEndianness);
}
return result;
}

View File

@@ -2,8 +2,6 @@
#include <cstring>
#include "fsfw/globalfunctions/CRC.h"
FileDataCreator::FileDataCreator(PduConfig& conf, FileDataInfo& info)
: HeaderCreator(conf, cfdp::PduType::FILE_DATA, 0, info.getSegmentMetadataFlag()), info(info) {
update();
@@ -20,7 +18,6 @@ ReturnValue_t FileDataCreator::serialize(uint8_t** buffer, size_t* size, size_t
if (buffer == nullptr or size == nullptr) {
return returnvalue::FAILED;
}
const uint8_t* start = *buffer;
if (*size + getSerializedSize() > maxSize) {
return SerializeIF::BUFFER_TOO_SHORT;
}
@@ -40,7 +37,7 @@ ReturnValue_t FileDataCreator::serialize(uint8_t** buffer, size_t* size, size_t
*buffer += segmentMetadataLen;
*size += segmentMetadataLen;
}
cfdp::Fss& offset = info.getOffset();
cfdp::FileSize& offset = info.getOffset();
result = offset.serialize(this->getLargeFileFlag(), buffer, size, maxSize, streamEndianness);
if (result != returnvalue::OK) {
return result;
@@ -53,11 +50,6 @@ ReturnValue_t FileDataCreator::serialize(uint8_t** buffer, size_t* size, size_t
std::memcpy(*buffer, readOnlyPtr, fileSize);
*buffer += fileSize;
*size += fileSize;
if (getCrcFlag()) {
uint16_t crc = CRC::crc16ccitt(start, getWholePduSize() - 2);
result = SerializeAdapter::serialize(&crc, buffer, size, maxSize, streamEndianness);
}
return returnvalue::OK;
}

View File

@@ -1,9 +1,9 @@
#include "FileDataInfo.h"
#include <utility>
FileDataInfo::FileDataInfo(cfdp::FileSize &offset, const uint8_t *fileData, size_t fileSize)
: offset(offset), fileData(fileData), fileSize(fileSize) {}
FileDataInfo::FileDataInfo(cfdp::Fss offset, const uint8_t *fileData, size_t fileSize)
: offset(std::move(offset)), fileData(fileData), fileSize(fileSize) {}
FileDataInfo::FileDataInfo(cfdp::FileSize &offset) : offset(offset) {}
void FileDataInfo::setSegmentMetadataFlag(bool enable) {
if (enable) {
@@ -71,7 +71,7 @@ const uint8_t *FileDataInfo::getSegmentMetadata(size_t *segmentMetadataLen_) {
return segmentMetadata;
}
cfdp::Fss &FileDataInfo::getOffset() { return offset; }
cfdp::FileSize &FileDataInfo::getOffset() { return offset; }
void FileDataInfo::setRecordContinuationState(cfdp::RecordContinuationState recContState) {
this->recContState = recContState;

View File

@@ -1,17 +1,17 @@
#ifndef FSFW_SRC_FSFW_CFDP_PDU_FILEDATAINFO_H_
#define FSFW_SRC_FSFW_CFDP_PDU_FILEDATAINFO_H_
#include <fsfw/cfdp/Fss.h>
#include <fsfw/cfdp/FileSize.h>
#include <fsfw/cfdp/definitions.h>
class FileDataInfo {
public:
FileDataInfo() = default;
FileDataInfo(cfdp::Fss offset, const uint8_t* fileData, size_t fileSize);
explicit FileDataInfo(cfdp::FileSize& offset);
FileDataInfo(cfdp::FileSize& offset, const uint8_t* fileData, size_t fileSize);
[[nodiscard]] size_t getSerializedSize(bool largeFile = false) const;
cfdp::Fss& getOffset();
cfdp::FileSize& getOffset();
const uint8_t* getFileData(size_t* fileSize = nullptr) const;
void setFileData(const uint8_t* fileData, size_t fileSize);
@@ -33,7 +33,7 @@ class FileDataInfo {
private:
cfdp::SegmentMetadataFlag segmentMetadataFlag = cfdp::SegmentMetadataFlag::NOT_PRESENT;
cfdp::SegmentationControl segCtrl = cfdp::SegmentationControl::NO_RECORD_BOUNDARIES_PRESERVATION;
cfdp::Fss offset;
cfdp::FileSize& offset;
const uint8_t* fileData = nullptr;
size_t fileSize = 0;
cfdp::RecordContinuationState recContState = cfdp::RecordContinuationState::NO_START_NO_END;

View File

@@ -8,9 +8,6 @@ ReturnValue_t FileDataReader::parseData() {
if (result != returnvalue::OK) {
return result;
}
if (not performCrcCheckIfApplicable()) {
return cfdp::PDU_CHECKSUM_FAILURE;
}
size_t currentIdx = PduHeaderReader::getHeaderSize();
const uint8_t* buf = pointers.rawPtr + currentIdx;
size_t remSize = PduHeaderReader::getWholePduSize() - currentIdx;
@@ -37,9 +34,6 @@ ReturnValue_t FileDataReader::parseData() {
if (result != returnvalue::OK) {
return result;
}
if (getCrcFlag()) {
remSize -= 2;
}
if (remSize > 0) {
info.setFileData(buf, remSize);
}

View File

@@ -3,7 +3,7 @@
#include "../definitions.h"
#include "FileDataInfo.h"
#include "HeaderReader.h"
#include "PduHeaderReader.h"
class FileDataReader : public PduHeaderReader {
public:

View File

@@ -1,7 +1,5 @@
#include "FileDirectiveReader.h"
#include "fsfw/globalfunctions/CRC.h"
FileDirectiveReader::FileDirectiveReader(const uint8_t *pduBuf, size_t maxSize)
: PduHeaderReader(pduBuf, maxSize) {}
@@ -12,10 +10,6 @@ ReturnValue_t FileDirectiveReader::parseData() {
if (result != returnvalue::OK) {
return result;
}
if (not performCrcCheckIfApplicable()) {
return cfdp::PDU_CHECKSUM_FAILURE;
}
if (this->getPduDataFieldLen() < 1) {
return cfdp::INVALID_PDU_DATAFIELD_LEN;
}

View File

@@ -2,7 +2,7 @@
#define FSFW_SRC_FSFW_CFDP_PDU_FILEDIRECTIVEDESERIALIZER_H_
#include "../definitions.h"
#include "fsfw/cfdp/pdu/HeaderReader.h"
#include "fsfw/cfdp/pdu/PduHeaderReader.h"
/**
* @brief This class is used to deserialize a PDU file directive header from raw memory.

View File

@@ -1,7 +1,5 @@
#include "FinishedPduCreator.h"
#include "fsfw/globalfunctions/CRC.h"
FinishPduCreator::FinishPduCreator(PduConfig &conf, FinishedInfo &finishInfo)
: FileDirectiveCreator(conf, cfdp::FileDirective::FINISH, 0), finishInfo(finishInfo) {
updateDirectiveFieldLen();
@@ -15,7 +13,6 @@ void FinishPduCreator::updateDirectiveFieldLen() {
ReturnValue_t FinishPduCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
Endianness streamEndianness) const {
const uint8_t *start = *buffer;
ReturnValue_t result = FileDirectiveCreator::serialize(buffer, size, maxSize, streamEndianness);
if (result != returnvalue::OK) {
return result;
@@ -43,9 +40,5 @@ ReturnValue_t FinishPduCreator::serialize(uint8_t **buffer, size_t *size, size_t
if (finishInfo.getFaultLocation(&entityId) == returnvalue::OK) {
result = entityId->serialize(buffer, size, maxSize, streamEndianness);
}
if (getCrcFlag()) {
uint16_t crc = CRC::crc16ccitt(start, getWholePduSize() - 2);
result = SerializeAdapter::serialize(&crc, buffer, size, maxSize, streamEndianness);
}
return result;
}

View File

@@ -24,8 +24,8 @@ ReturnValue_t HeaderCreator::serialize(uint8_t **buffer, size_t *size, size_t ma
*buffer += 1;
**buffer = pduDataFieldLen & 0x00ff;
*buffer += 1;
**buffer = segmentationCtrl << 7 | ((pduConf.sourceId.getWidth() - 1) << 4) |
segmentMetadataFlag << 3 | (pduConf.seqNum.getWidth() - 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);

View File

@@ -1,10 +1,8 @@
#include "HeaderReader.h"
#include <fsfw/serialize/SerializeAdapter.h>
#include <cstring>
#include "fsfw/globalfunctions/CRC.h"
#include "PduHeaderReader.h"
PduHeaderReader::PduHeaderReader(const uint8_t *pduBuf, size_t maxSize) {
setReadOnlyData(pduBuf, maxSize);
@@ -19,29 +17,28 @@ ReturnValue_t PduHeaderReader::parseData() {
}
pointers.fixedHeader =
reinterpret_cast<PduHeaderFixedStruct *>(const_cast<uint8_t *>(pointers.rawPtr));
sourceIdRaw = &pointers.fixedHeader->variableFieldsStart;
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);
if (getWholePduSize() > PduHeaderReader::getHeaderSize()) {
pointers.dataFieldStart = static_cast<const uint8_t *>(destIdRaw) + widthEntityIds;
pointers.dataFieldStart = reinterpret_cast<const uint8_t *>(destIdRaw) + widthEntityIds;
} else {
pointers.dataFieldStart = nullptr;
}
return returnvalue::OK;
}
ReturnValue_t PduHeaderReader::setData(uint8_t *dataPtr, size_t maxSize, void *args) {
ReturnValue_t PduHeaderReader::setData(uint8_t *dataPtr, size_t maxSize_, void *args) {
if (dataPtr == nullptr) {
return returnvalue::FAILED;
}
if (maxSize < 7) {
if (maxSize_ < 7) {
return SerializeIF::STREAM_TOO_SHORT;
}
pointers.rawPtr = dataPtr;
this->maxSize = maxSize;
maxSize = maxSize_;
return returnvalue::OK;
}
@@ -81,11 +78,11 @@ cfdp::SegmentationControl PduHeaderReader::getSegmentationControl() const {
}
cfdp::WidthInBytes PduHeaderReader::getLenEntityIds() const {
return static_cast<cfdp::WidthInBytes>(((pointers.fixedHeader->fourthByte >> 4) & 0b111) + 1);
return static_cast<cfdp::WidthInBytes>((pointers.fixedHeader->fourthByte >> 4) & 0x07);
}
cfdp::WidthInBytes PduHeaderReader::getLenSeqNum() const {
return static_cast<cfdp::WidthInBytes>((pointers.fixedHeader->fourthByte & 0b111) + 1);
return static_cast<cfdp::WidthInBytes>(pointers.fixedHeader->fourthByte & 0x07);
}
cfdp::SegmentMetadataFlag PduHeaderReader::getSegmentMetadataFlag() const {
@@ -106,11 +103,11 @@ void PduHeaderReader::getTransactionSeqNum(cfdp::TransactionSeqNum &seqNum) cons
}
void PduHeaderReader::assignVarLenField(cfdp::VarLenField *field, cfdp::WidthInBytes width,
void *sourcePtr) {
void *sourcePtr) const {
switch (width) {
case (cfdp::WidthInBytes::ONE_BYTE): {
auto *fieldTyped = static_cast<uint8_t *>(sourcePtr);
field->setValueAndWidth(width, *fieldTyped);
field->setValue(width, *fieldTyped);
break;
}
case (cfdp::WidthInBytes::TWO_BYTES): {
@@ -118,7 +115,7 @@ void PduHeaderReader::assignVarLenField(cfdp::VarLenField *field, cfdp::WidthInB
size_t deserSize = 0;
SerializeAdapter::deSerialize(&fieldTyped, static_cast<uint8_t *>(sourcePtr), &deserSize,
SerializeIF::Endianness::NETWORK);
field->setValueAndWidth(width, fieldTyped);
field->setValue(width, fieldTyped);
break;
}
case (cfdp::WidthInBytes::FOUR_BYTES): {
@@ -126,15 +123,7 @@ void PduHeaderReader::assignVarLenField(cfdp::VarLenField *field, cfdp::WidthInB
size_t deserSize = 0;
SerializeAdapter::deSerialize(&fieldTyped, static_cast<uint8_t *>(sourcePtr), &deserSize,
SerializeIF::Endianness::NETWORK);
field->setValueAndWidth(width, fieldTyped);
break;
}
case (cfdp::WidthInBytes::EIGHT_BYTES): {
uint64_t fieldTyped = 0;
size_t deserSize = 0;
SerializeAdapter::deSerialize(&fieldTyped, static_cast<uint8_t *>(sourcePtr), &deserSize,
SerializeIF::Endianness::NETWORK);
field->setValueAndWidth(width, fieldTyped);
field->setValue(width, fieldTyped);
break;
}
}
@@ -169,12 +158,3 @@ void PduHeaderReader::fillConfig(PduConfig &cfg) const {
}
const uint8_t *PduHeaderReader::getPduDataField() const { return pointers.dataFieldStart; }
bool PduHeaderReader::performCrcCheckIfApplicable() const {
if (getCrcFlag()) {
if (CRC::crc16ccitt(pointers.rawPtr, getWholePduSize()) != 0) {
return false;
}
}
return true;
}

View File

@@ -1,8 +1,6 @@
#include "KeepAlivePduCreator.h"
#include "fsfw/globalfunctions/CRC.h"
KeepAlivePduCreator::KeepAlivePduCreator(PduConfig &conf, cfdp::Fss &progress)
KeepAlivePduCreator::KeepAlivePduCreator(PduConfig &conf, cfdp::FileSize &progress)
: FileDirectiveCreator(conf, cfdp::FileDirective::KEEP_ALIVE, 4), progress(progress) {
updateDirectiveFieldLen();
}
@@ -19,18 +17,9 @@ void KeepAlivePduCreator::updateDirectiveFieldLen() {
ReturnValue_t KeepAlivePduCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
Endianness streamEndianness) const {
const uint8_t *start = *buffer;
ReturnValue_t result = FileDirectiveCreator::serialize(buffer, size, maxSize, streamEndianness);
if (result != returnvalue::OK) {
return result;
}
result = progress.serialize(this->getLargeFileFlag(), buffer, size, maxSize, streamEndianness);
if (result != returnvalue::OK) {
return result;
}
if (getCrcFlag()) {
uint16_t crc = CRC::crc16ccitt(start, getWholePduSize() - 2);
result = SerializeAdapter::serialize(&crc, buffer, size, maxSize, streamEndianness);
}
return result;
return progress.serialize(this->getLargeFileFlag(), buffer, size, maxSize, streamEndianness);
}

View File

@@ -1,12 +1,12 @@
#ifndef FSFW_CFDP_PDU_KEEPALIVEPDUSERIALIZER_H_
#define FSFW_CFDP_PDU_KEEPALIVEPDUSERIALIZER_H_
#include "fsfw/cfdp/Fss.h"
#include "fsfw/cfdp/FileSize.h"
#include "fsfw/cfdp/pdu/FileDirectiveCreator.h"
class KeepAlivePduCreator : public FileDirectiveCreator {
public:
KeepAlivePduCreator(PduConfig& conf, cfdp::Fss& progress);
KeepAlivePduCreator(PduConfig& conf, cfdp::FileSize& progress);
void updateDirectiveFieldLen();
@@ -16,7 +16,7 @@ class KeepAlivePduCreator : public FileDirectiveCreator {
Endianness streamEndianness) const override;
private:
cfdp::Fss& progress;
cfdp::FileSize& progress;
};
#endif /* FSFW_CFDP_PDU_KEEPALIVEPDUSERIALIZER_H_ */

View File

@@ -1,6 +1,7 @@
#include "KeepAlivePduReader.h"
KeepAlivePduReader::KeepAlivePduReader(const uint8_t* pduBuf, size_t maxSize, cfdp::Fss& progress)
KeepAlivePduReader::KeepAlivePduReader(const uint8_t* pduBuf, size_t maxSize,
cfdp::FileSize& progress)
: FileDirectiveReader(pduBuf, maxSize), progress(progress) {}
ReturnValue_t KeepAlivePduReader::parseData() {
@@ -14,4 +15,4 @@ ReturnValue_t KeepAlivePduReader::parseData() {
return progress.deSerialize(&buffer, &remLen, getEndianness());
}
cfdp::Fss& KeepAlivePduReader::getProgress() { return progress; }
cfdp::FileSize& KeepAlivePduReader::getProgress() { return progress; }

View File

@@ -1,19 +1,19 @@
#ifndef FSFW_CFDP_PDU_KEEPALIVEREADER_H_
#define FSFW_CFDP_PDU_KEEPALIVEREADER_H_
#include "fsfw/cfdp/Fss.h"
#include "fsfw/cfdp/FileSize.h"
#include "fsfw/cfdp/pdu/FileDirectiveReader.h"
class KeepAlivePduReader : public FileDirectiveReader {
public:
KeepAlivePduReader(const uint8_t* pduBuf, size_t maxSize, cfdp::Fss& progress);
KeepAlivePduReader(const uint8_t* pduBuf, size_t maxSize, cfdp::FileSize& progress);
ReturnValue_t parseData() override;
cfdp::Fss& getProgress();
cfdp::FileSize& getProgress();
private:
cfdp::Fss& progress;
cfdp::FileSize& progress;
};
#endif /* FSFW_CFDP_PDU_KEEPALIVEPDUREADER_H_ */

View File

@@ -1,35 +0,0 @@
#include "MetadataGenericInfo.h"
MetadataGenericInfo::MetadataGenericInfo(bool closureRequested, cfdp::ChecksumType checksumType,
cfdp::Fss fileSize)
: MetadataGenericInfo(std::move(fileSize)) {
this->closureRequested = closureRequested;
this->checksumType = checksumType;
}
MetadataGenericInfo::MetadataGenericInfo(cfdp::Fss fileSize) : fileSize(std::move(fileSize)) {}
cfdp::ChecksumType MetadataGenericInfo::getChecksumType() const { return checksumType; }
void MetadataGenericInfo::setChecksumType(cfdp::ChecksumType checksumType_) {
checksumType = checksumType_;
}
bool MetadataGenericInfo::isClosureRequested() const { return closureRequested; }
void MetadataGenericInfo::setClosureRequested(bool closureRequested_) {
closureRequested = closureRequested_;
}
const cfdp::Fss& MetadataGenericInfo::getFileSize() const { return fileSize; }
size_t MetadataGenericInfo::getSerializedSize(bool fssLarge) {
// 1 byte + minimal FSS 4 bytes
size_t size = 5;
if (fssLarge) {
size += 4;
}
return size;
}
cfdp::Fss& MetadataGenericInfo::getMutFileSize() { return fileSize; }

View File

@@ -1,35 +0,0 @@
#ifndef FSFW_SRC_FSFW_CFDP_PDU_METADATAINFO_H_
#define FSFW_SRC_FSFW_CFDP_PDU_METADATAINFO_H_
#include <optional>
#include "fsfw/cfdp/Fss.h"
#include "fsfw/cfdp/definitions.h"
#include "fsfw/cfdp/tlv/Lv.h"
#include "fsfw/cfdp/tlv/StringLv.h"
#include "fsfw/cfdp/tlv/Tlv.h"
class MetadataGenericInfo {
public:
MetadataGenericInfo() = default;
explicit MetadataGenericInfo(cfdp::Fss fileSize);
MetadataGenericInfo(bool closureRequested, cfdp::ChecksumType checksumType, cfdp::Fss fileSize);
static size_t getSerializedSize(bool fssLarge = false);
[[nodiscard]] cfdp::ChecksumType getChecksumType() const;
void setChecksumType(cfdp::ChecksumType checksumType);
[[nodiscard]] bool isClosureRequested() const;
void setClosureRequested(bool closureRequested = false);
[[nodiscard]] const cfdp::Fss& getFileSize() const;
cfdp::Fss& getMutFileSize();
private:
bool closureRequested = false;
cfdp::ChecksumType checksumType = cfdp::ChecksumType::NULL_CHECKSUM;
cfdp::Fss fileSize;
};
#endif /* FSFW_SRC_FSFW_CFDP_PDU_METADATAINFO_H_ */

View File

@@ -0,0 +1,103 @@
#include "MetadataInfo.h"
MetadataInfo::MetadataInfo(bool closureRequested, cfdp::ChecksumType checksumType,
cfdp::FileSize& fileSize, cfdp::StringLv& sourceFileName,
cfdp::StringLv& destFileName)
: MetadataInfo(fileSize, sourceFileName, destFileName) {
this->closureRequested = closureRequested;
this->checksumType = checksumType;
}
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_) {
this->optionsLen = optionsLen_.value();
}
}
cfdp::ChecksumType MetadataInfo::getChecksumType() const { return checksumType; }
void MetadataInfo::setChecksumType(cfdp::ChecksumType checksumType_) {
checksumType = checksumType_;
}
bool MetadataInfo::isClosureRequested() const { return closureRequested; }
void MetadataInfo::setClosureRequested(bool closureRequested_) {
closureRequested = closureRequested_;
}
cfdp::StringLv& MetadataInfo::getDestFileName() { return destFileName; }
cfdp::FileSize& MetadataInfo::getFileSize() { return fileSize; }
ReturnValue_t MetadataInfo::getOptions(cfdp::Tlv*** optionsArray_, size_t* optionsLen_,
size_t* maxOptsLen) {
if (optionsArray_ == nullptr or optionsArray == nullptr) {
return returnvalue::FAILED;
}
*optionsArray_ = optionsArray;
if (optionsLen_ != nullptr) {
*optionsLen_ = this->optionsLen;
}
if (maxOptsLen != nullptr) {
*maxOptsLen = this->maxOptionsLen;
}
return returnvalue::OK;
}
bool MetadataInfo::hasOptions() const {
if (optionsArray != nullptr and optionsLen > 0) {
return true;
}
return false;
}
bool MetadataInfo::canHoldOptions() const {
if (optionsArray != nullptr and maxOptionsLen > 0) {
return true;
}
return false;
}
size_t MetadataInfo::getSerializedSize(bool fssLarge) {
// 1 byte + minimal FSS 4 bytes
size_t size = 5;
if (fssLarge) {
size += 4;
}
size += sourceFileName.getSerializedSize();
size += destFileName.getSerializedSize();
if (hasOptions()) {
for (size_t idx = 0; idx < optionsLen; idx++) {
size += optionsArray[idx]->getSerializedSize();
}
}
return size;
}
void MetadataInfo::setDestFileName(cfdp::StringLv& destFileName_) {
this->destFileName = destFileName_;
}
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_; }
size_t MetadataInfo::getOptionsLen() const { return optionsLen; }
void MetadataInfo::setOptionsLen(size_t optionsLen_) { this->optionsLen = optionsLen_; }
cfdp::StringLv& MetadataInfo::getSourceFileName() { return sourceFileName; }

View File

@@ -0,0 +1,55 @@
#ifndef FSFW_SRC_FSFW_CFDP_PDU_METADATAINFO_H_
#define FSFW_SRC_FSFW_CFDP_PDU_METADATAINFO_H_
#include <optional>
#include "fsfw/cfdp/FileSize.h"
#include "fsfw/cfdp/definitions.h"
#include "fsfw/cfdp/tlv/Lv.h"
#include "fsfw/cfdp/tlv/StringLv.h"
#include "fsfw/cfdp/tlv/Tlv.h"
class MetadataInfo {
public:
MetadataInfo(cfdp::FileSize& fileSize, cfdp::StringLv& sourceFileName,
cfdp::StringLv& destFileName);
MetadataInfo(bool closureRequested, cfdp::ChecksumType checksumType, cfdp::FileSize& fileSize,
cfdp::StringLv& sourceFileName, cfdp::StringLv& destFileName);
size_t getSerializedSize(bool fssLarge = false);
void setOptionsArray(cfdp::Tlv** optionsArray, std::optional<size_t> optionsLen,
std::optional<size_t> maxOptionsLen);
[[nodiscard]] cfdp::ChecksumType getChecksumType() const;
void setChecksumType(cfdp::ChecksumType checksumType);
[[nodiscard]] bool isClosureRequested() const;
void setClosureRequested(bool closureRequested = false);
void setDestFileName(cfdp::StringLv& destFileName);
void setSourceFileName(cfdp::StringLv& sourceFileName);
cfdp::StringLv& getDestFileName();
cfdp::StringLv& getSourceFileName();
cfdp::FileSize& getFileSize();
[[nodiscard]] bool hasOptions() const;
[[nodiscard]] bool canHoldOptions() const;
ReturnValue_t getOptions(cfdp::Tlv*** optionsArray, size_t* optionsLen, size_t* maxOptsLen);
void setOptionsLen(size_t optionsLen);
[[nodiscard]] size_t getOptionsLen() const;
void setMaxOptionsLen(size_t maxOptionsLen);
[[nodiscard]] size_t getMaxOptionsLen() const;
private:
bool closureRequested = false;
cfdp::ChecksumType checksumType = cfdp::ChecksumType::NULL_CHECKSUM;
cfdp::FileSize& fileSize;
cfdp::StringLv& sourceFileName;
cfdp::StringLv& destFileName;
cfdp::Tlv** optionsArray = nullptr;
size_t optionsLen = 0;
size_t maxOptionsLen = 0;
};
#endif /* FSFW_SRC_FSFW_CFDP_PDU_METADATAINFO_H_ */

View File

@@ -1,28 +1,12 @@
#include "MetadataPduCreator.h"
#include "fsfw/globalfunctions/CRC.h"
MetadataPduCreator::MetadataPduCreator(PduConfig &conf, MetadataGenericInfo &info,
cfdp::StringLv &srcFileName, cfdp::StringLv &destFileName,
cfdp::Tlv **optionsArray, size_t optionsLen)
: FileDirectiveCreator(conf, cfdp::FileDirective::METADATA, 5),
info(info),
srcFileName(srcFileName),
destFileName(destFileName),
optionsArray(optionsArray),
optionsLen(optionsLen) {
MetadataPduCreator::MetadataPduCreator(PduConfig &conf, MetadataInfo &info)
: FileDirectiveCreator(conf, cfdp::FileDirective::METADATA, 5), info(info) {
updateDirectiveFieldLen();
}
void MetadataPduCreator::updateDirectiveFieldLen() {
size_t dirFieldLen = MetadataGenericInfo::getSerializedSize(HeaderCreator::getLargeFileFlag()) +
srcFileName.getSerializedSize() + destFileName.getSerializedSize();
if (optionsLen > 0 and optionsArray != nullptr) {
for (size_t idx = 0; idx < optionsLen; idx++) {
dirFieldLen += optionsArray[idx]->getSerializedSize();
}
}
setDirectiveDataFieldLen(dirFieldLen);
setDirectiveDataFieldLen(info.getSerializedSize(getLargeFileFlag()));
}
size_t MetadataPduCreator::getSerializedSize() const {
@@ -31,7 +15,6 @@ size_t MetadataPduCreator::getSerializedSize() const {
ReturnValue_t MetadataPduCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
Endianness streamEndianness) const {
const uint8_t *start = *buffer;
ReturnValue_t result = FileDirectiveCreator::serialize(buffer, size, maxSize, streamEndianness);
if (result != returnvalue::OK) {
return result;
@@ -46,29 +29,25 @@ ReturnValue_t MetadataPduCreator::serialize(uint8_t **buffer, size_t *size, size
if (result != returnvalue::OK) {
return result;
}
result = srcFileName.serialize(buffer, size, maxSize, streamEndianness);
result = info.getSourceFileName().serialize(buffer, size, maxSize, streamEndianness);
if (result != returnvalue::OK) {
return result;
}
result = destFileName.serialize(buffer, size, maxSize, streamEndianness);
result = info.getDestFileName().serialize(buffer, size, maxSize, streamEndianness);
if (result != returnvalue::OK) {
return result;
}
if (optionsLen > 0 and optionsArray != nullptr) {
for (size_t idx = 0; idx < optionsLen; idx++) {
result = optionsArray[idx]->serialize(buffer, size, maxSize, streamEndianness);
if (info.hasOptions()) {
cfdp::Tlv **optsArray = nullptr;
size_t optsLen = 0;
info.getOptions(&optsArray, &optsLen, nullptr);
for (size_t idx = 0; idx < optsLen; idx++) {
result = optsArray[idx]->serialize(buffer, size, maxSize, streamEndianness);
if (result != returnvalue::OK) {
return result;
}
}
}
if (getCrcFlag()) {
uint16_t crc = CRC::crc16ccitt(start, getWholePduSize() - 2);
result = SerializeAdapter::serialize(&crc, buffer, size, maxSize, streamEndianness);
}
return result;
}
const cfdp::StringLv &MetadataPduCreator::getSourceFileName() const { return srcFileName; }
const cfdp::StringLv &MetadataPduCreator::getDestFileName() const { return destFileName; }

View File

@@ -2,30 +2,22 @@
#define FSFW_CFDP_PDU_METADATAPDUCREATOR_H_
#include "fsfw/cfdp/pdu/FileDirectiveCreator.h"
#include "fsfw/cfdp/pdu/MetadataGenericInfo.h"
#include "fsfw/cfdp/pdu/MetadataInfo.h"
class MetadataPduCreator : public FileDirectiveCreator {
public:
MetadataPduCreator(PduConfig& conf, MetadataGenericInfo& info, cfdp::StringLv& srcFileName,
cfdp::StringLv& destFileName, cfdp::Tlv** optionsArray, size_t optionsLen);
MetadataPduCreator(PduConfig& conf, MetadataInfo& info);
void updateDirectiveFieldLen();
[[nodiscard]] size_t getSerializedSize() const override;
const cfdp::StringLv& getSourceFileName() const;
const cfdp::StringLv& getDestFileName() const;
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
Endianness streamEndianness) const override;
using FileDirectiveCreator::serialize;
private:
MetadataGenericInfo& info;
cfdp::StringLv& srcFileName;
cfdp::StringLv& destFileName;
cfdp::Tlv** optionsArray;
size_t optionsLen;
MetadataInfo& info;
};
#endif /* FSFW_CFDP_PDU_METADATAPDUCREATOR_H_ */

View File

@@ -1,15 +1,9 @@
#include "MetadataPduReader.h"
MetadataPduReader::MetadataPduReader(const uint8_t* pduBuf, size_t maxSize,
MetadataGenericInfo& info, cfdp::Tlv* optionsArray,
size_t optArrayMaxSize)
: FileDirectiveReader(pduBuf, maxSize),
info(info),
optionArray(optionsArray),
optionArrayMaxSize(optArrayMaxSize) {}
MetadataPduReader::MetadataPduReader(const uint8_t* pduBuf, size_t maxSize, MetadataInfo& info)
: FileDirectiveReader(pduBuf, maxSize), info(info) {}
ReturnValue_t MetadataPduReader::parseData() {
parsedOptions = 0;
ReturnValue_t result = FileDirectiveReader::parseData();
if (result != returnvalue::OK) {
return result;
@@ -25,47 +19,39 @@ ReturnValue_t MetadataPduReader::parseData() {
remSize -= 1;
buf += 1;
auto endianness = getEndianness();
result = info.getMutFileSize().deSerialize(&buf, &remSize, endianness);
result = info.getFileSize().deSerialize(&buf, &remSize, endianness);
if (result != returnvalue::OK) {
return result;
}
result = srcFileName.deSerialize(&buf, &remSize, endianness);
result = info.getSourceFileName().deSerialize(&buf, &remSize, endianness);
if (result != returnvalue::OK) {
return result;
}
result = destFileName.deSerialize(&buf, &remSize, endianness);
result = info.getDestFileName().deSerialize(&buf, &remSize, endianness);
if (result != returnvalue::OK) {
return result;
}
if (getCrcFlag() && remSize == 2) {
return returnvalue::OK;
}
info.setOptionsLen(0);
if (remSize > 0) {
if (optionArrayMaxSize == 0 or optionArray == nullptr) {
if (not info.canHoldOptions()) {
return cfdp::METADATA_CANT_PARSE_OPTIONS;
}
cfdp::Tlv** optionsArray = nullptr;
size_t optsMaxLen = 0;
size_t optsIdx = 0;
info.getOptions(&optionsArray, nullptr, &optsMaxLen);
while (remSize > 0) {
if (optsIdx > optionArrayMaxSize) {
if (optsIdx > optsMaxLen) {
return cfdp::METADATA_CANT_PARSE_OPTIONS;
}
result = optionArray[optsIdx].deSerialize(&buf, &remSize, endianness);
result = optionsArray[optsIdx]->deSerialize(&buf, &remSize, endianness);
if (result != returnvalue::OK) {
return result;
}
optsIdx++;
}
parsedOptions = optsIdx;
info.setOptionsLen(optsIdx);
}
return result;
}
size_t MetadataPduReader::getNumberOfParsedOptions() const { return parsedOptions; }
const cfdp::StringLv& MetadataPduReader::getSourceFileName() const { return srcFileName; }
const cfdp::StringLv& MetadataPduReader::getDestFileName() const { return destFileName; }
const MetadataGenericInfo& MetadataPduReader::getGenericInfo() const { return info; }

View File

@@ -2,28 +2,16 @@
#define FSFW_CFDP_PDU_METADATAPDUREADER_H_
#include "fsfw/cfdp/pdu/FileDirectiveReader.h"
#include "fsfw/cfdp/pdu/MetadataGenericInfo.h"
#include "fsfw/cfdp/pdu/MetadataInfo.h"
class MetadataPduReader : public FileDirectiveReader {
public:
MetadataPduReader(const uint8_t* pduBuf, size_t maxSize, MetadataGenericInfo& info,
cfdp::Tlv* optionsArray, size_t optArrayMaxSize);
MetadataPduReader(const uint8_t* pduBuf, size_t maxSize, MetadataInfo& info);
ReturnValue_t parseData() override;
[[nodiscard]] const MetadataGenericInfo& getGenericInfo() const;
[[nodiscard]] const cfdp::StringLv& getSourceFileName() const;
[[nodiscard]] const cfdp::StringLv& getDestFileName() const;
[[nodiscard]] size_t getNumberOfParsedOptions() const;
private:
cfdp::StringLv srcFileName;
cfdp::StringLv destFileName;
MetadataGenericInfo& info;
cfdp::Tlv* optionArray;
size_t optionArrayMaxSize;
size_t parsedOptions = 0;
MetadataInfo& info;
};
#endif /* FSFW_CFDP_PDU_METADATAPDUREADER_H_ */

View File

@@ -1,6 +1,6 @@
#include "NakInfo.h"
NakInfo::NakInfo(cfdp::Fss startOfScope, cfdp::Fss endOfScope)
NakInfo::NakInfo(cfdp::FileSize startOfScope, cfdp::FileSize endOfScope)
: startOfScope(startOfScope), endOfScope(endOfScope) {}
size_t NakInfo::getSerializedSize(bool fssLarge) {
@@ -57,9 +57,9 @@ void NakInfo::setSegmentRequests(SegmentRequest* segmentRequests, size_t* segmen
}
}
cfdp::Fss& NakInfo::getStartOfScope() { return startOfScope; }
cfdp::FileSize& NakInfo::getStartOfScope() { return startOfScope; }
cfdp::Fss& NakInfo::getEndOfScope() { return endOfScope; }
cfdp::FileSize& NakInfo::getEndOfScope() { return endOfScope; }
size_t NakInfo::getSegmentRequestsLen() const { return segmentRequestsLen; }

View File

@@ -3,21 +3,21 @@
#include <utility>
#include "fsfw/cfdp/Fss.h"
#include "fsfw/cfdp/FileSize.h"
class NakInfo {
public:
using SegmentRequest = std::pair<cfdp::Fss, cfdp::Fss>;
using SegmentRequest = std::pair<cfdp::FileSize, cfdp::FileSize>;
NakInfo(cfdp::Fss startOfScope, cfdp::Fss endOfScope);
NakInfo(cfdp::FileSize startOfScope, cfdp::FileSize endOfScope);
void setSegmentRequests(SegmentRequest* segmentRequests, size_t* segmentRequestLen,
size_t* maxSegmentRequestLen);
size_t getSerializedSize(bool fssLarge = false);
cfdp::Fss& getStartOfScope();
cfdp::Fss& getEndOfScope();
cfdp::FileSize& getStartOfScope();
cfdp::FileSize& getEndOfScope();
bool hasSegmentRequests() const;
bool canHoldSegmentRequests() const;
@@ -31,8 +31,8 @@ class NakInfo {
void setSegmentRequestLen(size_t readLen);
private:
cfdp::Fss startOfScope;
cfdp::Fss endOfScope;
cfdp::FileSize startOfScope;
cfdp::FileSize endOfScope;
SegmentRequest* segmentRequests = nullptr;
size_t segmentRequestsLen = 0;
size_t maxSegmentRequestsLen = 0;

View File

@@ -1,7 +1,5 @@
#include "NakPduCreator.h"
#include "fsfw/globalfunctions/CRC.h"
NakPduCreator::NakPduCreator(PduConfig &pduConf, NakInfo &nakInfo)
: FileDirectiveCreator(pduConf, cfdp::FileDirective::NAK, 0), nakInfo(nakInfo) {
updateDirectiveFieldLen();
@@ -15,7 +13,6 @@ size_t NakPduCreator::getSerializedSize() const { return FileDirectiveCreator::g
ReturnValue_t NakPduCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
Endianness streamEndianness) const {
const uint8_t *start = *buffer;
ReturnValue_t result = FileDirectiveCreator::serialize(buffer, size, maxSize, streamEndianness);
if (result != returnvalue::OK) {
return result;
@@ -43,9 +40,5 @@ ReturnValue_t NakPduCreator::serialize(uint8_t **buffer, size_t *size, size_t ma
}
}
}
if (getCrcFlag()) {
uint16_t crc = CRC::crc16ccitt(start, getWholePduSize() - 2);
result = SerializeAdapter::serialize(&crc, buffer, size, maxSize, streamEndianness);
}
return result;
}

View File

@@ -4,7 +4,7 @@
#include <vector>
#include "NakInfo.h"
#include "fsfw/cfdp/Fss.h"
#include "fsfw/cfdp/FileSize.h"
#include "fsfw/cfdp/definitions.h"
#include "fsfw/cfdp/pdu/FileDirectiveCreator.h"

View File

@@ -71,11 +71,6 @@ class PduHeaderReader : public RedirectableDataPointerIF, public PduHeaderIF {
void getDestId(cfdp::EntityId& destId) const override;
void getTransactionSeqNum(cfdp::TransactionSeqNum& seqNum) const override;
/**
* Performs the CRC check on the whole PDU if the CRC flag is set.
*/
[[nodiscard]] bool performCrcCheckIfApplicable() const;
ReturnValue_t deserResult = returnvalue::OK;
[[nodiscard]] size_t getMaxSize() const;
@@ -110,8 +105,7 @@ class PduHeaderReader : public RedirectableDataPointerIF, public PduHeaderIF {
* @return
*/
ReturnValue_t setData(uint8_t* dataPtr, size_t maxSize, void* args) override;
static void assignVarLenField(cfdp::VarLenField* field, cfdp::WidthInBytes width,
void* sourcePtr);
void assignVarLenField(cfdp::VarLenField* field, cfdp::WidthInBytes width, void* sourcePtr) const;
void* sourceIdRaw = nullptr;
void* seqNumRaw = nullptr;
void* destIdRaw = nullptr;

View File

@@ -1,7 +1,5 @@
#include "PromptPduCreator.h"
#include "fsfw/globalfunctions/CRC.h"
PromptPduCreator::PromptPduCreator(PduConfig &conf, cfdp::PromptResponseRequired responseRequired)
: FileDirectiveCreator(conf, cfdp::FileDirective::PROMPT, 1),
responseRequired(responseRequired) {}
@@ -12,7 +10,6 @@ size_t PromptPduCreator::getSerializedSize() const {
ReturnValue_t PromptPduCreator::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
Endianness streamEndianness) const {
const uint8_t *start = *buffer;
ReturnValue_t result = FileDirectiveCreator::serialize(buffer, size, maxSize, streamEndianness);
if (result != returnvalue::OK) {
return result;
@@ -23,10 +20,5 @@ ReturnValue_t PromptPduCreator::serialize(uint8_t **buffer, size_t *size, size_t
**buffer = responseRequired << 7;
*buffer += 1;
*size += 1;
if (getCrcFlag()) {
uint16_t crc = CRC::crc16ccitt(start, getWholePduSize() - 2);
result = SerializeAdapter::serialize(&crc, buffer, size, maxSize, streamEndianness);
}
return result;
}

View File

@@ -8,5 +8,4 @@ target_sources(
StringLv.cpp
FlowLabelTlv.cpp
MessageToUserTlv.cpp
FaultHandlerOverrideTlv.cpp
ReservedMessageCreator.cpp)
FaultHandlerOverrideTlv.cpp)

View File

@@ -23,8 +23,6 @@ class EntityIdTlv : public TlvIF {
*/
ReturnValue_t deSerialize(cfdp::Tlv& tlv, Endianness endianness);
using SerializeIF::deSerialize; // we overloaded this function, so this is needed to unconfuse
// the compiler
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) override;

View File

@@ -29,8 +29,6 @@ class FilestoreResponseTlv : public cfdp::FilestoreTlvBase {
*/
ReturnValue_t deSerialize(const cfdp::Tlv& tlv, Endianness endianness);
using SerializeIF::deSerialize; // we overloaded this function, so this is needed to unconfuse
// the compiler
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) override;

View File

@@ -66,9 +66,9 @@ static constexpr uint8_t FSR_DENY_DIR_NOT_ALLOWED = 0b0010;
class FilestoreTlvBase : public TlvIF {
public:
explicit FilestoreTlvBase(cfdp::StringLv& firstFileName) : firstFileName(firstFileName) {};
explicit FilestoreTlvBase(cfdp::StringLv& firstFileName) : firstFileName(firstFileName){};
FilestoreTlvBase(FilestoreActionCode actionCode, cfdp::StringLv& firstFileName)
: actionCode(actionCode), firstFileName(firstFileName) {};
: actionCode(actionCode), firstFileName(firstFileName){};
ReturnValue_t commonSerialize(uint8_t** buffer, size_t* size, size_t maxSize,
Endianness streamEndianness, bool isResponse = false,

View File

@@ -14,6 +14,23 @@ cfdp::Lv::Lv(const std::vector<uint8_t>& data) : value(data.data(), data.size(),
cfdp::Lv::Lv() : value(static_cast<uint8_t*>(nullptr), 0, true) {}
cfdp::Lv::Lv(const Lv& other)
: value(other.value.getConstBuffer(), other.value.getSerializedSize() - 1, true) {
if (other.value.getSerializedSize() - 1 > 0) {
zeroLen = false;
}
}
cfdp::Lv& cfdp::Lv::operator=(const Lv& other) {
size_t otherSize = 0;
auto* otherVal = const_cast<uint8_t*>(other.getValue(&otherSize));
if (otherVal == nullptr or otherSize == 0) {
this->zeroLen = true;
}
this->value.setConstBuffer(otherVal, otherSize);
return *this;
}
ReturnValue_t cfdp::Lv::serialize(uint8_t** buffer, size_t* size, size_t maxSize,
Endianness streamEndianness) const {
if (maxSize < 1) {
@@ -32,8 +49,10 @@ ReturnValue_t cfdp::Lv::serialize(uint8_t** buffer, size_t* size, size_t maxSize
}
size_t cfdp::Lv::getSerializedSize() const {
if (zeroLen or value.getConstBuffer() == nullptr) {
if (zeroLen) {
return 1;
} else if (value.getConstBuffer() == nullptr) {
return 0;
}
return value.getSerializedSize();
}
@@ -66,34 +85,7 @@ ReturnValue_t cfdp::Lv::deSerialize(const uint8_t** buffer, size_t* size,
const uint8_t* cfdp::Lv::getValue(size_t* size) const {
if (size != nullptr) {
// Length without length field
*size = getSerializedSize() - 1;
*size = value.getSerializedSize() - 1;
}
return value.getConstBuffer();
}
cfdp::Lv::Lv(cfdp::Lv&& other) noexcept
: value(other.value.getConstBuffer(), other.value.getSerializedSize() - 1, true) {
if (other.value.getSerializedSize() - 1 > 0) {
zeroLen = false;
}
// Leave other class in intact state.
other.zeroLen = false;
other.value = SerialBufferAdapter<uint8_t>();
}
cfdp::Lv& cfdp::Lv::operator=(cfdp::Lv&& other) noexcept {
size_t otherSize = 0;
this->zeroLen = false;
auto* otherVal = const_cast<uint8_t*>(other.getValue(&otherSize));
if (otherVal == nullptr or otherSize == 0) {
this->zeroLen = true;
}
this->value.setConstBuffer(otherVal, otherSize);
// Leave other class in intact state.
other.zeroLen = false;
other.value = SerialBufferAdapter<uint8_t>();
return *this;
}
size_t cfdp::Lv::getValueLen() const { return getSerializedSize() - 1; }
bool cfdp::Lv::isEmpty() const { return zeroLen; }

View File

@@ -18,12 +18,8 @@ class Lv : public SerializeIF {
Lv(const uint8_t* value, size_t size);
Lv();
// Semantically, this class is a zero-copy helper, so the copy ctor and copy assigment do not
// really make sense here.
Lv(const Lv&) = delete;
Lv& operator=(const Lv&) = delete;
Lv(Lv&&) noexcept;
Lv& operator=(Lv&&) noexcept;
Lv(const Lv&);
Lv& operator=(const Lv&);
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
Endianness streamEndianness) const override;
@@ -40,8 +36,6 @@ class Lv : public SerializeIF {
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) override;
size_t getValueLen() const;
/**
* Get value field and its size.
* @param size Optionally retrieve size. Size will be the size of the actual value field
@@ -50,8 +44,6 @@ class Lv : public SerializeIF {
*/
const uint8_t* getValue(size_t* size) const;
bool isEmpty() const;
private:
bool zeroLen = true;
SerialBufferAdapter<uint8_t> value;

View File

@@ -7,22 +7,3 @@ MessageToUserTlv::MessageToUserTlv() : Tlv() {}
MessageToUserTlv::MessageToUserTlv(const std::vector<uint8_t>& data)
: Tlv(cfdp::TlvType::MSG_TO_USER, data.data(), data.size()) {}
MessageToUserTlv::MessageToUserTlv(const uint8_t* value, size_t size)
: Tlv(cfdp::TlvType::MSG_TO_USER, value, size) {}
bool MessageToUserTlv::isReservedCfdpMessage(uint8_t& messageType, const uint8_t** msgDataStart,
size_t& msgLen) const {
if (cfdp::Tlv::getLengthField() < 5) {
return false;
}
if (std::strncmp(reinterpret_cast<const char*>(getValue()), "cfdp", 4) == 0) {
messageType = getValue()[4];
if (msgDataStart != nullptr) {
*msgDataStart = getValue() + 5;
}
msgLen = cfdp::Tlv::getSerializedSize() - 5;
return true;
}
return false;
}

View File

@@ -9,12 +9,8 @@ class MessageToUserTlv : public cfdp::Tlv {
public:
MessageToUserTlv();
MessageToUserTlv(uint8_t* value, size_t size);
MessageToUserTlv(const uint8_t* value, size_t size);
explicit MessageToUserTlv(const std::vector<uint8_t>& data);
bool isReservedCfdpMessage(uint8_t& messageType, const uint8_t** msgDataStart,
size_t& msgLen) const;
private:
};

View File

@@ -1,39 +0,0 @@
#include "ReservedMessageCreator.h"
cfdp::ReservedMessageCreator::ReservedMessageCreator(uint8_t messageType, uint8_t *msgData,
size_t msgLen)
: messageType(messageType), msgData(msgData), msgSize(msgLen) {}
ReturnValue_t cfdp::ReservedMessageCreator::serialize(
uint8_t **buffer, size_t *size, size_t maxSize,
SerializeIF::Endianness streamEndianness) const {
if (*size + getSerializedSize() > maxSize) {
return SerializeIF::BUFFER_TOO_SHORT;
}
**buffer = TlvType::MSG_TO_USER;
*buffer += 1;
*size += 1;
**buffer = getSerializedSize() - 2;
*size += 1;
*buffer += 1;
std::memcpy(*buffer, MSG_HEADER, 4);
*buffer += 4;
*size += 4;
**buffer = messageType;
*buffer += 1;
*size += 1;
std::memcpy(*buffer, msgData, msgSize);
*buffer += msgSize;
*size += msgSize;
return returnvalue::OK;
}
size_t cfdp::ReservedMessageCreator::getSerializedSize() const {
// 2 bytes type and length, 4 bytes CFDP, 1 byte reserved message type, message data.
return 2 + 5 + msgSize;
}
ReturnValue_t cfdp::ReservedMessageCreator::deSerialize(const uint8_t **buffer, size_t *size,
SerializeIF::Endianness streamEndianness) {
return returnvalue::FAILED;
}

View File

@@ -1,24 +0,0 @@
#pragma once
#include "Tlv.h"
namespace cfdp {
class ReservedMessageCreator : public SerializeIF {
public:
static constexpr char MSG_HEADER[] = "cfdp";
ReservedMessageCreator(uint8_t messageType, uint8_t *msgData, size_t msgLen);
[[nodiscard]] 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(const uint8_t **buffer, size_t *size,
Endianness streamEndianness) override;
private:
uint8_t messageType;
uint8_t *msgData;
size_t msgSize;
};
} // namespace cfdp

View File

@@ -7,12 +7,3 @@ cfdp::StringLv::StringLv(const char* filename, size_t len)
: Lv(reinterpret_cast<const uint8_t*>(filename), len) {}
cfdp::StringLv::StringLv() : Lv() {}
const char* cfdp::StringLv::getCString(size_t& fileSize) const {
return reinterpret_cast<const char*>(getValue(&fileSize));
}
std::string cfdp::StringLv::getString() const {
size_t fileSize;
return {getCString(fileSize), fileSize};
}

View File

@@ -13,8 +13,6 @@ class StringLv : public Lv {
explicit StringLv(const std::string& fileName);
explicit StringLv(const char* filename, size_t len);
const char* getCString(size_t& fileSize) const;
std::string getString() const;
// Delete the move constructor to avoid passing in a temporary
StringLv(const std::string&&) = delete;
};

View File

@@ -54,7 +54,6 @@ ReturnValue_t cfdp::Tlv::deSerialize(const uint8_t **buffer, size_t *size,
return STREAM_TOO_SHORT;
}
rawData = *buffer;
uint8_t rawType = **buffer;
if (not checkType(rawType)) {
return INVALID_TLV_TYPE;
@@ -103,5 +102,3 @@ void cfdp::Tlv::setValue(uint8_t *value, size_t len) {
uint8_t cfdp::Tlv::getLengthField() const { return this->value.getSerializedSize() - 1; }
void cfdp::Tlv::setType(TlvType type) { this->type = type; }
const uint8_t *cfdp::Tlv::getRawData() const { return rawData; }

View File

@@ -47,7 +47,6 @@ class Tlv : public TlvIF {
void setValue(uint8_t *value, size_t len);
[[nodiscard]] const uint8_t *getValue() const;
[[nodiscard]] const uint8_t *getRawData() const;
void setType(TlvType type);
[[nodiscard]] TlvType getType() const override;
[[nodiscard]] uint8_t getLengthField() const override;
@@ -56,7 +55,6 @@ class Tlv : public TlvIF {
bool checkType(uint8_t rawType);
bool zeroLen = true;
const uint8_t *rawData = nullptr;
TlvType type = TlvType::INVALID_TLV;
SerialBufferAdapter<uint8_t> value;
};

View File

@@ -5,7 +5,7 @@
class TlvIF : public SerializeIF {
public:
virtual ~TlvIF() {};
virtual ~TlvIF(){};
virtual uint8_t getLengthField() const = 0;
virtual cfdp::TlvType getType() const = 0;

View File

@@ -12,7 +12,6 @@ template <typename T, size_t MAX_SIZE, typename count_t = uint8_t>
class FixedArrayList : public ArrayList<T, count_t> {
static_assert(MAX_SIZE <= std::numeric_limits<count_t>::max(),
"count_t is not large enough to hold MAX_SIZE");
static_assert(MAX_SIZE > 0, "MAX_SIZE is 0");
private:
T data[MAX_SIZE];

View File

@@ -155,8 +155,8 @@ class FixedMap : public SerializeIF {
uint32_t maxSize() const { return theMap.maxSize(); }
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
Endianness streamEndianness) const override {
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
Endianness streamEndianness) const {
ReturnValue_t result =
SerializeAdapter::serialize(&this->_size, buffer, size, maxSize, streamEndianness);
uint32_t i = 0;
@@ -170,7 +170,7 @@ class FixedMap : public SerializeIF {
return result;
}
size_t getSerializedSize() const override {
virtual size_t getSerializedSize() const {
uint32_t printSize = sizeof(_size);
uint32_t i = 0;
@@ -182,8 +182,8 @@ class FixedMap : public SerializeIF {
return printSize;
}
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) override {
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) {
ReturnValue_t result =
SerializeAdapter::deSerialize(&this->_size, buffer, size, streamEndianness);
if (this->_size > theMap.maxSize()) {

View File

@@ -1,6 +1,5 @@
#include "fsfw/container/SharedRingBuffer.h"
#include "SharedRingBuffer.h"
#include "fsfw/ipc/MutexFactory.h"
#include "fsfw/ipc/MutexGuard.h"
@@ -16,12 +15,7 @@ SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const
mutex = MutexFactory::instance()->createMutex();
}
SharedRingBuffer::~SharedRingBuffer() {
MutexFactory::instance()->deleteMutex(mutex);
if (receiveSizesFifo != nullptr) {
delete (receiveSizesFifo);
}
}
SharedRingBuffer::~SharedRingBuffer() { MutexFactory::instance()->deleteMutex(mutex); }
void SharedRingBuffer::setToUseReceiveSizeFIFO(size_t fifoDepth) { this->fifoDepth = fifoDepth; }
@@ -36,31 +30,18 @@ MutexIF* SharedRingBuffer::getMutexHandle() const { return mutex; }
ReturnValue_t SharedRingBuffer::initialize() {
if (fifoDepth > 0) {
receiveSizesFifo = new DynamicFIFO<size_t>(fifoDepth);
receiveSizesFIFO = new DynamicFIFO<size_t>(fifoDepth);
}
return SystemObject::initialize();
}
DynamicFIFO<size_t>* SharedRingBuffer::getReceiveSizesFifo() {
if (receiveSizesFifo == nullptr) {
DynamicFIFO<size_t>* SharedRingBuffer::getReceiveSizesFIFO() {
if (receiveSizesFIFO == nullptr) {
// Configuration error.
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "SharedRingBuffer::getReceiveSizesFIFO: Ring buffer"
<< " was not configured to have sizes FIFO, returning nullptr!" << std::endl;
#endif
}
return receiveSizesFifo;
return receiveSizesFIFO;
}
ReturnValue_t SharedRingBuffer::fifoEmpty(bool& empty, MutexIF::TimeoutType timeoutType,
uint32_t timeoutMs) {
if (receiveSizesFifo == nullptr) {
return returnvalue::FAILED;
}
MutexGuard mg(mutex, timeoutType, timeoutMs);
if (mg.getLockResult() != returnvalue::OK) {
return mg.getLockResult();
}
empty = receiveSizesFifo->empty();
return returnvalue::OK;
}

View File

@@ -20,7 +20,7 @@ class SharedRingBuffer : public SystemObject, public SimpleRingBuffer {
* This constructor allocates a new internal buffer with the supplied size.
* @param size
* @param overwriteOld
* If the ring buffer is overflowing at a write operation, the oldest data
* If the ring buffer is overflowing at a write operartion, the oldest data
* will be overwritten.
*/
SharedRingBuffer(object_id_t objectId, const size_t size, bool overwriteOld,
@@ -30,7 +30,7 @@ class SharedRingBuffer : public SystemObject, public SimpleRingBuffer {
* @param buffer
* @param size
* @param overwriteOld
* If the ring buffer is overflowing at a write operation, the oldest data
* If the ring buffer is overflowing at a write operartion, the oldest data
* will be overwritten.
*/
SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const size_t size, bool overwriteOld,
@@ -78,15 +78,13 @@ class SharedRingBuffer : public SystemObject, public SimpleRingBuffer {
* Do not forget to protect access with a lock if required!
* @return
*/
DynamicFIFO<size_t>* getReceiveSizesFifo();
ReturnValue_t fifoEmpty(bool& empty, MutexIF::TimeoutType timeoutType, uint32_t timeoutMs);
DynamicFIFO<size_t>* getReceiveSizesFIFO();
private:
MutexIF* mutex = nullptr;
size_t fifoDepth = 0;
DynamicFIFO<size_t>* receiveSizesFifo = nullptr;
DynamicFIFO<size_t>* receiveSizesFIFO = nullptr;
};
#endif /* FSFW_CONTAINER_SHAREDRINGBUFFER_H_ */
#endif /* FSFW_CONTAINER_SHAREDRINGBUFFER_H_ */

View File

@@ -4,31 +4,48 @@
#include "fsfw/ipc/QueueFactory.h"
#include "fsfw/objectmanager/ObjectManager.h"
#include "fsfw/subsystem/SubsystemBase.h"
#include "fsfw/subsystem/helper.h"
ControllerBase::ControllerBase(object_id_t setObjectId, size_t commandQueueDepth)
ControllerBase::ControllerBase(object_id_t setObjectId, object_id_t parentId,
size_t commandQueueDepth)
: SystemObject(setObjectId),
parentId(parentId),
mode(MODE_OFF),
submode(SUBMODE_NONE),
modeHelper(this),
healthHelper(this, setObjectId) {
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
commandQueue = QueueFactory::instance()->createMessageQueue(
commandQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
commandQueue = QueueFactory::instance()->createMessageQueue(commandQueueDepth);
}
ControllerBase::~ControllerBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
ReturnValue_t ControllerBase::initialize() {
ReturnValue_t result = modeHelper.initialize();
ReturnValue_t result = SystemObject::initialize();
if (result != returnvalue::OK) {
return result;
}
result = healthHelper.initialize();
MessageQueueId_t parentQueue = 0;
if (parentId != objects::NO_OBJECT) {
auto* parent = ObjectManager::instance()->get<SubsystemBase>(parentId);
if (parent == nullptr) {
return returnvalue::FAILED;
}
parentQueue = parent->getCommandQueue();
parent->registerChild(getObjectId());
}
result = healthHelper.initialize(parentQueue);
if (result != returnvalue::OK) {
return result;
}
return SystemObject::initialize();
result = modeHelper.initialize(parentQueue);
if (result != returnvalue::OK) {
return result;
}
return returnvalue::OK;
}
MessageQueueId_t ControllerBase::getCommandQueue() const { return commandQueue->getId(); }
@@ -58,7 +75,7 @@ void ControllerBase::handleQueue() {
void ControllerBase::startTransition(Mode_t mode_, Submode_t submode_) {
changeHK(this->mode, this->submode, false);
triggerEvent(CHANGING_MODE, mode_, submode_);
triggerEvent(CHANGING_MODE, mode, submode);
mode = mode_;
submode = submode_;
modeHelper.modeChanged(mode, submode);
@@ -72,17 +89,18 @@ void ControllerBase::getMode(Mode_t* mode_, Submode_t* submode_) {
*submode_ = this->submode;
}
void ControllerBase::announceMode(bool recursive) { triggerEvent(MODE_INFO, mode, submode); }
void ControllerBase::modeChanged(Mode_t mode_, Submode_t submode_) {}
void ControllerBase::setToExternalControl() { healthHelper.setHealth(EXTERNAL_CONTROL); }
void ControllerBase::announceMode(bool recursive) { triggerEvent(MODE_INFO, mode, submode); }
ReturnValue_t ControllerBase::performOperation(uint8_t opCode) {
handleQueue();
performControlOperation(opCode);
performControlOperation();
return returnvalue::OK;
}
void ControllerBase::modeChanged(Mode_t mode_, Submode_t submode_) {}
ReturnValue_t ControllerBase::setHealth(HealthState health) {
switch (health) {
case HEALTHY:
@@ -100,13 +118,3 @@ void ControllerBase::setTaskIF(PeriodicTaskIF* task_) { executingTask = task_; }
void ControllerBase::changeHK(Mode_t mode_, Submode_t submode_, bool enable) {}
ReturnValue_t ControllerBase::initializeAfterTaskCreation() { return returnvalue::OK; }
const HasHealthIF* ControllerBase::getOptHealthIF() const { return this; }
const HasModesIF& ControllerBase::getModeIF() const { return *this; }
ModeTreeChildIF& ControllerBase::getModeTreeChildIF() { return *this; }
ReturnValue_t ControllerBase::connectModeTreeParent(HasModeTreeChildrenIF& parent) {
return modetree::connectModeTreeParent(parent, *this, &healthHelper, modeHelper);
}

View File

@@ -6,9 +6,6 @@
#include "fsfw/modes/HasModesIF.h"
#include "fsfw/modes/ModeHelper.h"
#include "fsfw/objectmanager/SystemObject.h"
#include "fsfw/subsystem/HasModeTreeChildrenIF.h"
#include "fsfw/subsystem/ModeTreeChildIF.h"
#include "fsfw/subsystem/ModeTreeConnectionIF.h"
#include "fsfw/tasks/ExecutableObjectIF.h"
#include "fsfw/tasks/PeriodicTaskIF.h"
@@ -21,18 +18,13 @@
class ControllerBase : public HasModesIF,
public HasHealthIF,
public ExecutableObjectIF,
public ModeTreeChildIF,
public ModeTreeConnectionIF,
public SystemObject {
public:
static const Mode_t MODE_NORMAL = 2;
ControllerBase(object_id_t setObjectId, size_t commandQueueDepth = 3);
ControllerBase(object_id_t setObjectId, object_id_t parentId, size_t commandQueueDepth = 3);
~ControllerBase() override;
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF &parent) override;
ModeTreeChildIF &getModeTreeChildIF() override;
/** SystemObject override */
ReturnValue_t initialize() override;
@@ -46,8 +38,6 @@ class ControllerBase : public HasModesIF,
ReturnValue_t performOperation(uint8_t opCode) override;
void setTaskIF(PeriodicTaskIF *task) override;
ReturnValue_t initializeAfterTaskCreation() override;
const HasHealthIF *getOptHealthIF() const override;
const HasModesIF &getModeIF() const override;
protected:
/**
@@ -61,11 +51,13 @@ class ControllerBase : public HasModesIF,
/**
* Periodic helper, implemented by child class.
*/
virtual void performControlOperation(uint8_t opCode) = 0;
virtual void performControlOperation() = 0;
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode) override = 0;
const object_id_t parentId;
Mode_t mode;
Submode_t submode;

View File

@@ -1,7 +1,8 @@
#include "fsfw/controller/ExtendedControllerBase.h"
ExtendedControllerBase::ExtendedControllerBase(object_id_t objectId, size_t commandQueueDepth)
: ControllerBase(objectId, commandQueueDepth),
ExtendedControllerBase::ExtendedControllerBase(object_id_t objectId, object_id_t parentId,
size_t commandQueueDepth)
: ControllerBase(objectId, parentId, commandQueueDepth),
poolManager(this, commandQueue),
actionHelper(this, commandQueue) {}
@@ -81,7 +82,7 @@ ReturnValue_t ExtendedControllerBase::initializeAfterTaskCreation() {
ReturnValue_t ExtendedControllerBase::performOperation(uint8_t opCode) {
handleQueue();
performControlOperation(opCode);
performControlOperation();
/* We do this after performing control operation because variables will be set changed
in this function. */
poolManager.performHkOperation();

View File

@@ -17,7 +17,7 @@ class ExtendedControllerBase : public ControllerBase,
public HasActionsIF,
public HasLocalDataPoolIF {
public:
ExtendedControllerBase(object_id_t objectId, size_t commandQueueDepth = 3);
ExtendedControllerBase(object_id_t objectId, object_id_t parentId, size_t commandQueueDepth = 3);
~ExtendedControllerBase() override;
/* SystemObjectIF overrides */
@@ -44,9 +44,9 @@ class ExtendedControllerBase : public ControllerBase,
/**
* Periodic helper from ControllerBase, implemented by child class.
*/
void performControlOperation(uint8_t opCode) override = 0;
void performControlOperation() override = 0;
// Handle the four messages mentioned above
/* Handle the four messages mentioned above */
void handleQueue() override;
/* HasActionsIF overrides */

View File

@@ -6,8 +6,6 @@
#include "fsfw/globalfunctions/constants.h"
#include "fsfw/globalfunctions/math/MatrixOperations.h"
#include "fsfw/globalfunctions/math/VectorOperations.h"
#include "fsfw/globalfunctions/sign.h"
#include "fsfw/serviceinterface.h"
void CoordinateTransformations::positionEcfToEci(const double* ecfPosition, double* eciPosition,
timeval* timeUTC) {
@@ -99,16 +97,7 @@ void CoordinateTransformations::ecfToEci(const double* ecfCoordinates, double* e
double CoordinateTransformations::getJuleanCenturiesTT(timeval timeUTC) {
timeval timeTT;
ReturnValue_t result = Clock::convertUTCToTT(timeUTC, &timeTT);
if (result != returnvalue::OK) {
// i think it is better to continue here than to abort
timeTT = timeUTC;
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "CoordinateTransformations::Conversion from UTC to TT failed. Continuing "
"calculations with UTC."
<< std::endl;
#endif
}
Clock::convertUTCToTT(timeUTC, &timeTT);
double jD2000TT;
Clock::convertTimevalToJD2000(timeTT, &jD2000TT);
@@ -218,61 +207,3 @@ void CoordinateTransformations::getTransMatrixECITOECF(timeval timeUTC, double T
MatrixOperations<double>::multiply(mTheta[0], Ttemp[0], Tfi[0], 3, 3, 3);
};
void CoordinateTransformations::cartesianFromLatLongAlt(const double lat, const double longi,
const double alt, double* cartesianOutput) {
/* @brief: cartesianFromLatLongAlt() - calculates cartesian coordinates in ECEF from latitude,
* longitude and altitude
* @param: lat geodetic latitude [rad]
* longi longitude [rad]
* alt altitude [m]
* cartesianOutput Cartesian Coordinates in ECEF (3x1)
* @source: Fundamentals of Spacecraft Attitude Determination and Control, P.34ff
* Landis Markley and John L. Crassidis*/
double radiusPolar = 6356752.314;
double radiusEqua = 6378137;
double eccentricity = sqrt(1 - pow(radiusPolar, 2) / pow(radiusEqua, 2));
double auxRadius = radiusEqua / sqrt(1 - pow(eccentricity, 2) * pow(sin(lat), 2));
cartesianOutput[0] = (auxRadius + alt) * cos(lat) * cos(longi);
cartesianOutput[1] = (auxRadius + alt) * cos(lat) * sin(longi);
cartesianOutput[2] = ((1 - pow(eccentricity, 2)) * auxRadius + alt) * sin(lat);
};
void CoordinateTransformations::latLongAltFromCartesian(const double* vector, double& latitude,
double& longitude, double& altitude) {
/* @brief: latLongAltFromCartesian() - calculates latitude, longitude and altitude from
* cartesian coordinates in ECEF
* @param: x x-value of position vector [m]
* y y-value of position vector [m]
* z z-value of position vector [m]
* latitude geodetic latitude [rad]
* longitude longitude [rad]
* altitude altitude [m]
* @source: Fundamentals of Spacecraft Attitude Determination and Control, P.35 f
* Landis Markley and John L. Crassidis*/
// From World Geodetic System the Earth Radii
double a = 6378137.0; // semimajor axis [m]
double b = 6356752.3142; // semiminor axis [m]
// Calculation
double e2 = 1 - pow(b, 2) / pow(a, 2);
double epsilon2 = pow(a, 2) / pow(b, 2) - 1;
double rho = sqrt(pow(vector[0], 2) + pow(vector[1], 2));
double p = std::abs(vector[2]) / epsilon2;
double s = pow(rho, 2) / (e2 * epsilon2);
double q = pow(p, 2) - pow(b, 2) + s;
double u = p / sqrt(q);
double v = pow(b, 2) * pow(u, 2) / q;
double P = 27 * v * s / q;
double Q = pow(sqrt(P + 1) + sqrt(P), 2. / 3.);
double t = (1 + Q + 1 / Q) / 6;
double c = sqrt(pow(u, 2) - 1 + 2 * t);
double w = (c - u) / 2;
double d = sign(vector[2]) * sqrt(q) * (w + sqrt(sqrt(pow(t, 2) + v) - u * w - t / 2 - 1. / 4.));
double N = a * sqrt(1 + epsilon2 * pow(d, 2) / pow(b, 2));
latitude = asin((epsilon2 + 1) * d / N);
altitude = rho * cos(latitude) + vector[2] * sin(latitude) - pow(a, 2) / N;
longitude = atan2(vector[1], vector[0]);
}

View File

@@ -23,12 +23,6 @@ class CoordinateTransformations {
static void getEarthRotationMatrix(timeval timeUTC, double matrix[][3]);
static void cartesianFromLatLongAlt(const double lat, const double longi, const double alt,
double* cartesianOutput);
static void latLongAltFromCartesian(const double* vector, double& latitude, double& longitude,
double& altitude);
private:
CoordinateTransformations();
static void ecfToEci(const double* ecfCoordinates, double* eciCoordinates,

View File

@@ -29,7 +29,7 @@ class Jgm3Model {
lastExecutionTime.tv_sec = 0;
lastExecutionTime.tv_usec = 0;
}
virtual ~Jgm3Model() {};
virtual ~Jgm3Model(){};
// double acsNavOrbit(double posECF[3],double velECF[3],timeval gpsTime);
@@ -70,10 +70,10 @@ class Jgm3Model {
W[n][m] = W[n][m] - (((n + m - 1) / (double)(n - m)) *
(pow(Earth::MEAN_RADIUS, 2) / pow(r, 2)) * W[n - 2][m]);
} // End of if(n!=(m+1))
} // End of if(n==m){
} // End of if(n==0 and m==0)
} // End of for(uint8_t n=0;n<(DEGREE+1);n++)
} // End of for(uint8_t m=0;m<(ORDER+1);m++)
} // End of if(n==m){
} // End of if(n==0 and m==0)
} // End of for(uint8_t n=0;n<(DEGREE+1);n++)
} // End of for(uint8_t m=0;m<(ORDER+1);m++)
// overwrite accel if not properly initialized
accel[0] = 0;
@@ -106,7 +106,7 @@ class Jgm3Model {
accel[1] += partAccel[1];
accel[2] += partAccel[2];
} // End of for(uint8_t n=0;n<DEGREE;n++)
} // End of uint8_t m=0;m<ORDER;m++
} // End of uint8_t m=0;m<ORDER;m++
}
void initializeNavOrbit(const double position[3], const double velocity[3], timeval timeUTC) {

View File

@@ -166,9 +166,9 @@ ReturnValue_t Sgp4Propagator::propagate(double* position, double* velocity, time
timeval timeSinceEpoch = time - epoch;
double minutesSinceEpoch = timeSinceEpoch.tv_sec / 60. + timeSinceEpoch.tv_usec / 60000000.;
double daysSinceEpoch = minutesSinceEpoch / 60 / 24;
double yearsSinceEpoch = minutesSinceEpoch / 60 / 24 / 365;
if ((daysSinceEpoch > 7) || (daysSinceEpoch < -7)) {
if ((yearsSinceEpoch > 1) || (yearsSinceEpoch < -1)) {
return TLE_TOO_OLD;
}

View File

@@ -88,18 +88,13 @@ ReturnValue_t MapPacketExtraction::unpackBlockingPackets(TcTransferFrame* frame)
uint32_t totalLength = frame->getDataLength();
if (totalLength > MAX_PACKET_SIZE) return CONTENT_TOO_LARGE;
uint8_t* position = frame->getDataField();
while ((totalLength > ccsds::HEADER_LEN)) {
SpacePacketReader packet(position, totalLength);
status = packet.checkSize();
if (status != returnvalue::OK) {
// TODO: Better error handling
status = DATA_CORRUPTED;
}
uint32_t packetSize = packet.getFullPacketLen();
while ((totalLength > SpacePacketBase::MINIMUM_SIZE)) {
SpacePacketBase packet(position);
uint32_t packetSize = packet.getFullSize();
if (packetSize <= totalLength) {
status = sendCompletePacket(packet.getFullData(), packet.getFullPacketLen());
totalLength -= packet.getFullPacketLen();
position += packet.getFullPacketLen();
status = sendCompletePacket(packet.getWholeData(), packet.getFullSize());
totalLength -= packet.getFullSize();
position += packet.getFullSize();
status = returnvalue::OK;
} else {
status = DATA_CORRUPTED;
@@ -112,7 +107,7 @@ ReturnValue_t MapPacketExtraction::unpackBlockingPackets(TcTransferFrame* frame)
return status;
}
ReturnValue_t MapPacketExtraction::sendCompletePacket(const uint8_t* data, uint32_t size) {
ReturnValue_t MapPacketExtraction::sendCompletePacket(uint8_t* data, uint32_t size) {
store_address_t store_id;
ReturnValue_t status = this->packetStore->addData(&store_id, data, size);
if (status == returnvalue::OK) {

View File

@@ -47,7 +47,7 @@ class MapPacketExtraction : public MapPacketExtractionIF {
* @param size Complete total size of the packet.
* @return Return Code of the Packet Store or the Message Queue.
*/
ReturnValue_t sendCompletePacket(const uint8_t* data, uint32_t size);
ReturnValue_t sendCompletePacket(uint8_t* data, uint32_t size);
/**
* Helper method to reset the internal buffer.
*/

View File

@@ -64,8 +64,8 @@ class PoolDataSetBase : public PoolDataSetIF, public SerializeIF {
* - @c SET_WAS_ALREADY_READ if read() is called twice without calling
* commit() in between
*/
ReturnValue_t read(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
uint32_t lockTimeout = 20) override;
virtual ReturnValue_t read(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
uint32_t lockTimeout = 20) override;
/**
* @brief The commit call initializes writing back the registered variables.
* @details
@@ -84,15 +84,15 @@ class PoolDataSetBase : public PoolDataSetIF, public SerializeIF {
* - @c COMMITING_WITHOUT_READING if set was not read yet and
* contains non write-only variables
*/
ReturnValue_t commit(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
uint32_t lockTimeout = 20) override;
virtual ReturnValue_t commit(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
uint32_t lockTimeout = 20) override;
/**
* Register the passed pool variable instance into the data set.
* @param variable
* @return
*/
ReturnValue_t registerVariable(PoolVariableIF* variable) override;
virtual ReturnValue_t registerVariable(PoolVariableIF* variable) override;
/**
* Provides the means to lock the underlying data structure to ensure

Some files were not shown because too many files have changed in this diff Show More