Compare commits
2 Commits
mohr/intro
...
mueller/dh
Author | SHA1 | Date | |
---|---|---|---|
5ff28ff562 | |||
fcdb90ff0a |
3
.gitignore
vendored
3
.gitignore
vendored
@ -10,8 +10,5 @@
|
||||
.settings
|
||||
.metadata
|
||||
|
||||
# VSCode
|
||||
.vscode
|
||||
|
||||
/build*
|
||||
/cmake-build*
|
||||
|
28
CHANGELOG.md
28
CHANGELOG.md
@ -10,6 +10,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
# [v6.0.0]
|
||||
|
||||
## Changes
|
||||
|
||||
- Removed `HasReturnvaluesIF` class in favor of `returnvalue` namespace with `OK` and `FAILED`
|
||||
constants.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/659
|
||||
|
||||
## Added
|
||||
|
||||
- DHB TM handler `handleDeviceTM` renamed to `handleDeviceTm` and now takes
|
||||
@ -23,16 +29,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- Add new `UnsignedByteField` class
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/660
|
||||
|
||||
## Changes
|
||||
|
||||
- Removed `HasReturnvaluesIF` class in favor of `returnvalue` namespace with `OK` and `FAILED`
|
||||
constants.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/659
|
||||
- Overhaul of the TMTC stack, including various changes and improvements
|
||||
for other modules
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/655
|
||||
which also includes a migration guide
|
||||
|
||||
# [v5.0.0] 25.07.2022
|
||||
|
||||
## Changes
|
||||
@ -166,6 +162,7 @@ https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/593
|
||||
- https://gitlab.kitware.com/cmake/cmake/-/issues/21696
|
||||
Easiest solution for now: Keep this option OFF by default.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/616
|
||||
- Linux HAL: Add wiretapping option for I2C. Enabled with `FSFW_HAL_I2C_WIRETAPPING` defined to 1
|
||||
- Dedicated Version class and constant `fsfw::FSFW_VERSION` containing version information
|
||||
inside `fsfw/version.h`
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/559
|
||||
@ -180,17 +177,6 @@ https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/593
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/590
|
||||
- `Subsystem`: New API to add table and sequence entries
|
||||
|
||||
## HAL
|
||||
|
||||
- SPI: Cache the SPI device in the communication interface. Architecturally, this makes a
|
||||
lot more sense because each ComIF should be responsible for one SPI bus.
|
||||
- SPI: Move the empty transfer to update the line polarity to separate function. This means
|
||||
it is not automatically called when calling the setter function for SPI speed and mode.
|
||||
The user should call this function after locking the CS mutex if multiple SPI devices with
|
||||
differing speeds and modes are attached to one bus.
|
||||
- SPI: Getter functions for SPI speed and mode.
|
||||
- I2C: Add wiretapping option for I2C. Enabled with `FSFW_HAL_I2C_WIRETAPPING` defined to 1.
|
||||
|
||||
## Fixed
|
||||
|
||||
- TCP TMTC Server: `MutexGuard` was not created properly in
|
||||
|
@ -80,7 +80,7 @@ set(FSFW_CATCH2_LIB_MAJOR_VERSION
|
||||
3
|
||||
CACHE STRING "Catch2 library major version requirement")
|
||||
set(FSFW_CATCH2_LIB_VERSION
|
||||
v${FSFW_CATCH2_LIB_MAJOR_VERSION}.1.0
|
||||
v${FSFW_CATCH2_LIB_MAJOR_VERSION}.0.0-preview5
|
||||
CACHE STRING "Catch2 library exact version requirement")
|
||||
|
||||
# Keep this off by default for now. See PR:
|
||||
@ -195,7 +195,7 @@ message(
|
||||
)
|
||||
|
||||
# Check whether the user has already installed ETL first
|
||||
find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} CONFIG QUIET)
|
||||
find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET)
|
||||
# Not installed, so use FetchContent to download and provide etl
|
||||
if(NOT ${FSFW_ETL_LIB_NAME}_FOUND)
|
||||
message(
|
||||
@ -360,8 +360,7 @@ if(NOT FSFW_CONFIG_PATH)
|
||||
if(NOT FSFW_BUILD_DOCS)
|
||||
message(
|
||||
WARNING
|
||||
"${MSG_PREFIX} Flight Software Framework configuration path FSFW_CONFIG_PATH not set"
|
||||
)
|
||||
"${MSG_PREFIX} Flight Software Framework configuration path not set")
|
||||
message(
|
||||
WARNING
|
||||
"${MSG_PREFIX} Setting default configuration from ${DEF_CONF_PATH} ..")
|
||||
|
@ -175,7 +175,7 @@ cmake -DFSFW_BUILD_DOCS=ON -DFSFW_OSAL=host ..
|
||||
Then you can generate the documentation using
|
||||
|
||||
```sh
|
||||
cmake --build . -- Sphinx -j
|
||||
cmake --build . -j
|
||||
```
|
||||
|
||||
You can find the generated documentation inside the `docs/sphinx` folder inside the build
|
||||
|
@ -5,21 +5,16 @@ 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
|
||||
|
||||
RUN python3 -m pip install sphinx breathe
|
||||
RUN apt-get --yes install gcc g++ cmake make lcov git valgrind nano iputils-ping
|
||||
|
||||
RUN git clone https://github.com/catchorg/Catch2.git && \
|
||||
cd Catch2 && \
|
||||
git checkout v3.1.0 && \
|
||||
cmake -Bbuild -H. -DBUILD_TESTING=OFF && \
|
||||
cmake --build build/ --target install
|
||||
cd Catch2 && \
|
||||
git checkout v3.0.0-preview5 && \
|
||||
cmake -Bbuild -H. -DBUILD_TESTING=OFF && \
|
||||
cmake --build build/ --target install
|
||||
|
||||
RUN git clone https://github.com/ETLCPP/etl.git && \
|
||||
cd etl && \
|
||||
git checkout 20.28.0 && \
|
||||
cmake -B build . && \
|
||||
cmake --install build/
|
||||
|
||||
#ssh needs a valid user to work
|
||||
RUN adduser --uid 114 jenkins
|
||||
cd etl && \
|
||||
git checkout 20.28.0 && \
|
||||
cmake -B build . && \
|
||||
cmake --install build/
|
||||
|
50
automation/Jenkinsfile
vendored
50
automation/Jenkinsfile
vendored
@ -1,13 +1,9 @@
|
||||
pipeline {
|
||||
environment {
|
||||
BUILDDIR = 'cmake-build-tests'
|
||||
DOCDDIR = 'cmake-build-documentation'
|
||||
BUILDDIR = 'build-tests'
|
||||
}
|
||||
agent {
|
||||
docker {
|
||||
image 'fsfw-ci:d5'
|
||||
args '--network host'
|
||||
}
|
||||
docker { image 'fsfw-ci:d3'}
|
||||
}
|
||||
stages {
|
||||
stage('Clean') {
|
||||
@ -43,47 +39,5 @@ pipeline {
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Documentation') {
|
||||
when {
|
||||
branch 'development'
|
||||
}
|
||||
steps {
|
||||
dir(DOCDDIR) {
|
||||
sh 'cmake -DFSFW_BUILD_DOCS=ON -DFSFW_OSAL=host ..'
|
||||
sh 'make Sphinx'
|
||||
sshagent(credentials: ['documentation-buildfix']) {
|
||||
sh 'ssh -o StrictHostKeyChecking=no buildfix@documentation.intra.irs.uni-stuttgart.de rm -rf /mnt/data/www/html/fsfw/development/*'
|
||||
sh 'scp -o StrictHostKeyChecking=no -r docs/sphinx/* buildfix@documentation.intra.irs.uni-stuttgart.de:/mnt/data/www/html/fsfw/development'
|
||||
}
|
||||
}
|
||||
dir(BUILDDIR) {
|
||||
sshagent(credentials: ['documentation-buildfix']) {
|
||||
sh 'ssh -o StrictHostKeyChecking=no buildfix@documentation.intra.irs.uni-stuttgart.de rm -rf /mnt/data/www/html/fsfw/coverage/development/*'
|
||||
sh 'scp -o StrictHostKeyChecking=no -r fsfw-tests_coverage/* buildfix@documentation.intra.irs.uni-stuttgart.de:/mnt/data/www/html/fsfw/coverage/development'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Master Documentation') {
|
||||
when {
|
||||
branch 'master'
|
||||
}
|
||||
steps {
|
||||
dir(DOCDDIR) {
|
||||
sh 'cmake -DFSFW_BUILD_DOCS=ON -DFSFW_OSAL=host ..'
|
||||
sh 'make Sphinx'
|
||||
sshagent(credentials: ['documentation-buildfix']) {
|
||||
sh 'ssh -o StrictHostKeyChecking=no buildfix@documentation.intra.irs.uni-stuttgart.de rm -rf /mnt/data/www/html/fsfw/master/*'
|
||||
sh 'scp -o StrictHostKeyChecking=no -r docs/sphinx/* buildfix@documentation.intra.irs.uni-stuttgart.de:/mnt/data/www/html/fsfw/master'
|
||||
}
|
||||
}
|
||||
dir(BUILDDIR) {
|
||||
sshagent(credentials: ['documentation-buildfix']) {
|
||||
sh 'ssh -o StrictHostKeyChecking=no buildfix@documentation.intra.irs.uni-stuttgart.de rm -rf /mnt/data/www/html/fsfw/coverage/master/*'
|
||||
sh 'scp -o StrictHostKeyChecking=no -r fsfw-tests_coverage/* buildfix@documentation.intra.irs.uni-stuttgart.de:/mnt/data/www/html/fsfw/coverage/master'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,10 +4,6 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
// It is assumed the user has a subsystem and class ID list in some user header files.
|
||||
// #include "events/subsystemIdRanges.h"
|
||||
// #include "returnvalues/classIds.h"
|
||||
|
||||
//! Used to determine whether C++ ostreams are used which can increase
|
||||
//! the binary size significantly. If this is disabled,
|
||||
//! the C stdio functions can be used alternatively
|
||||
|
@ -35,8 +35,8 @@ void Factory::produceFsfwObjects(void) {
|
||||
}
|
||||
|
||||
void Factory::setStaticFrameworkObjectIds() {
|
||||
PusServiceBase::PUS_DISTRIBUTOR = objects::NO_OBJECT;
|
||||
PusServiceBase::PACKET_DESTINATION = objects::NO_OBJECT;
|
||||
PusServiceBase::packetSource = objects::NO_OBJECT;
|
||||
PusServiceBase::packetDestination = objects::NO_OBJECT;
|
||||
|
||||
CommandingServiceBase::defaultPacketSource = objects::NO_OBJECT;
|
||||
CommandingServiceBase::defaultPacketDestination = objects::NO_OBJECT;
|
||||
|
@ -13,7 +13,7 @@ from shutil import which
|
||||
from typing import List
|
||||
|
||||
|
||||
UNITTEST_FOLDER_NAME = "cmake-build-tests"
|
||||
UNITTEST_FOLDER_NAME = "build-tests"
|
||||
DOCS_FOLDER_NAME = "build-docs"
|
||||
|
||||
|
||||
|
@ -15,7 +15,6 @@ add_subdirectory(globalfunctions)
|
||||
add_subdirectory(health)
|
||||
add_subdirectory(housekeeping)
|
||||
add_subdirectory(internalerror)
|
||||
add_subdirectory(introspection)
|
||||
add_subdirectory(ipc)
|
||||
add_subdirectory(memory)
|
||||
add_subdirectory(modes)
|
||||
|
@ -1,62 +0,0 @@
|
||||
#include "Action.h"
|
||||
|
||||
#include <fsfw/serialize/SerializeAdapter.h>
|
||||
|
||||
#undef Action
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
|
||||
Action::Action() {}
|
||||
|
||||
void Action::setEnum(EnumIF *theEnum) {
|
||||
id = theEnum->getValue();
|
||||
name = theEnum->getDescription();
|
||||
}
|
||||
|
||||
const char *Action::getName() { return name; }
|
||||
#else
|
||||
Action::Action(ActionId_t id) : id(id) {}
|
||||
#endif
|
||||
ActionId_t Action::getId() { return id; }
|
||||
|
||||
void Action::registerParameter(ParameterIF *parameter) { parameterList.push_back(parameter); }
|
||||
|
||||
std::vector<ParameterIF *> const *Action::getParameters() const { return ¶meterList; }
|
||||
|
||||
size_t Action::getSerializedSize() const {
|
||||
size_t size = SerializeAdapter::getSerializedSize(&id);
|
||||
for (auto parameter : *getParameters()) {
|
||||
size += parameter->getSerializedSize();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
ReturnValue_t Action::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result = SerializeAdapter::serialize(&id, buffer, size, maxSize, streamEndianness);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
for (auto parameter : *getParameters()) {
|
||||
result = parameter->serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t Action::deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) {
|
||||
ReturnValue_t result = returnvalue::OK;/* TODO not needed as must have been read before to find this action = SerializeAdapter::deSerialize(&id, buffer, size, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}*/
|
||||
for (auto parameter : *getParameters()) {
|
||||
result = parameter->deSerialize(buffer, size, streamEndianness);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <fsfw/serialize/SerializeIF.h>
|
||||
#include "ActionMessage.h"
|
||||
#include "ParameterIF.h"
|
||||
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
#include "../introspection/Enum.h"
|
||||
#endif
|
||||
|
||||
class Action: public SerializeIF {
|
||||
public:
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
Action();
|
||||
void setEnum(EnumIF* id);
|
||||
const char *getName();
|
||||
#else
|
||||
Action(ActionId_t id);
|
||||
#endif
|
||||
ActionId_t getId();
|
||||
|
||||
MessageQueueId_t commandedBy;
|
||||
|
||||
[[nodiscard]] virtual ReturnValue_t handle() = 0;
|
||||
|
||||
void registerParameter(ParameterIF *parameter);
|
||||
|
||||
std::vector<ParameterIF *> const *getParameters() const;
|
||||
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
private:
|
||||
ActionId_t id;
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
const char *name;
|
||||
#endif
|
||||
std::vector<ParameterIF *> parameterList;
|
||||
};
|
@ -57,10 +57,6 @@ void ActionHelper::finish(bool success, MessageQueueId_t reportTo, ActionId_t co
|
||||
|
||||
void ActionHelper::setQueueToUse(MessageQueueIF* queue) { queueToUse = queue; }
|
||||
|
||||
MessageQueueIF const * ActionHelper::getQueue() const {
|
||||
return queueToUse;
|
||||
}
|
||||
|
||||
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
|
||||
store_address_t dataAddress) {
|
||||
const uint8_t* dataPtr = nullptr;
|
||||
@ -70,29 +66,9 @@ void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t act
|
||||
CommandMessage reply;
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
ipcStore->deleteData(dataAddress);
|
||||
return;
|
||||
}
|
||||
auto actionIter = actionMap.find(actionId);
|
||||
if (actionIter == actionMap.end()){
|
||||
CommandMessage reply;
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, HasActionsIF::INVALID_ACTION_ID);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
ipcStore->deleteData(dataAddress);
|
||||
return;
|
||||
}
|
||||
Action* action = actionIter->second;
|
||||
result = action->deSerialize(&dataPtr, &size, SerializeIF::Endianness::NETWORK);
|
||||
if ((result != returnvalue::OK) or (size != 0)){
|
||||
CommandMessage reply;
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, HasActionsIF::INVALID_PARAMETERS);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
ipcStore->deleteData(dataAddress);
|
||||
return;
|
||||
}
|
||||
//TODO call action->check()
|
||||
action->commandedBy = commandedBy;
|
||||
result = owner->executeAction(action);
|
||||
result = owner->executeAction(actionId, commandedBy, dataPtr, size);
|
||||
ipcStore->deleteData(dataAddress);
|
||||
if (result == HasActionsIF::EXECUTION_FINISHED) {
|
||||
CommandMessage reply;
|
||||
@ -187,11 +163,3 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, ActionId_t rep
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void ActionHelper::registerAction(Action* action) {
|
||||
//TODO error handling
|
||||
ActionId_t id = action->getId();
|
||||
actionMap.emplace(id, action);
|
||||
}
|
||||
|
||||
std::map<ActionId_t, Action*> const* ActionHelper::getActionMap() { return &actionMap; }
|
@ -1,13 +1,9 @@
|
||||
#ifndef FSFW_ACTION_ACTIONHELPER_H_
|
||||
#define FSFW_ACTION_ACTIONHELPER_H_
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "Action.h"
|
||||
#include "ActionMessage.h"
|
||||
#include "fsfw/ipc/MessageQueueIF.h"
|
||||
#include "fsfw/serialize/SerializeIF.h"
|
||||
|
||||
/**
|
||||
* @brief Action Helper is a helper class which handles action messages
|
||||
*
|
||||
@ -102,16 +98,6 @@ class ActionHelper {
|
||||
*/
|
||||
void setQueueToUse(MessageQueueIF* queue);
|
||||
|
||||
/**
|
||||
* Needed so templateAction can check if actionHelper was
|
||||
* contructed already to aid in debuggig a nasty coding error.
|
||||
*/
|
||||
MessageQueueIF const * getQueue() const;
|
||||
|
||||
void registerAction(Action* action);
|
||||
|
||||
std::map<ActionId_t, Action*> const* getActionMap();
|
||||
|
||||
protected:
|
||||
//! Increase of value of this per step
|
||||
static const uint8_t STEP_OFFSET = 1;
|
||||
@ -122,8 +108,6 @@ class ActionHelper {
|
||||
MessageQueueIF* queueToUse;
|
||||
//! Pointer to an IPC Store, initialized during construction or
|
||||
StorageManagerIF* ipcStore = nullptr;
|
||||
//! Map of all implemented Actions
|
||||
std::map<ActionId_t, Action*> actionMap;
|
||||
|
||||
/**
|
||||
* Internal function called by handleActionMessage
|
||||
|
@ -1,3 +1,3 @@
|
||||
target_sources(
|
||||
${LIB_FSFW_NAME} PRIVATE Action.cpp ActionHelper.cpp ActionMessage.cpp
|
||||
${LIB_FSFW_NAME} PRIVATE ActionHelper.cpp ActionMessage.cpp
|
||||
CommandActionHelper.cpp SimpleActionHelper.cpp)
|
||||
|
@ -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);
|
||||
|
@ -44,12 +44,8 @@ class HasActionsIF {
|
||||
/**
|
||||
* Function to get the MessageQueueId_t of the implementing object
|
||||
* @return MessageQueueId_t of the object
|
||||
*
|
||||
*/
|
||||
[[nodiscard]] virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||
|
||||
[[nodiscard]] virtual ActionHelper* getActionHelper() = 0;
|
||||
|
||||
/**
|
||||
* Execute or initialize the execution of a certain function.
|
||||
* The ActionHelpers will execute this function and behave differently
|
||||
@ -59,7 +55,8 @@ class HasActionsIF {
|
||||
* -@c EXECUTION_FINISHED Finish reply will be generated
|
||||
* -@c Not returnvalue::OK Step failure reply will be generated
|
||||
*/
|
||||
virtual ReturnValue_t executeAction(Action* action) = 0;
|
||||
virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size) = 0;
|
||||
};
|
||||
|
||||
#endif /* FSFW_ACTION_HASACTIONSIF_H_ */
|
||||
|
@ -1,40 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Parameter.h"
|
||||
|
||||
template <typename T>
|
||||
class MinMaxParameter : public Parameter<T> {
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
private:
|
||||
MinMaxParameter(Action *owner, const char *name, T min, T max)
|
||||
: Parameter<T>(owner, name), min(min), max(max) {}
|
||||
|
||||
public:
|
||||
static MinMaxParameter createMinMaxParameter(Action *owner, const char *name, T min, T max) {
|
||||
return MinMaxParameter(owner, name, min, max);
|
||||
}
|
||||
virtual double getMinFloating() override { return static_cast<double>(min); }
|
||||
virtual int64_t getMinSigned() override { return static_cast<int64_t>(min); }
|
||||
|
||||
virtual double getMaxFloating() override { return static_cast<double>(max); }
|
||||
virtual int64_t getMaxSigned() override { return static_cast<int64_t>(max); }
|
||||
|
||||
#else
|
||||
private:
|
||||
MinMaxParameter(Action *owner, T min, T max) : Parameter<T>(owner), min(min), max(max) {}
|
||||
|
||||
public:
|
||||
static MinMaxParameter createMinMaxParameter(Action *owner, T min, T max) {
|
||||
return MinMaxParameter(owner, min, max);
|
||||
}
|
||||
#endif
|
||||
private:
|
||||
T min;
|
||||
T max;
|
||||
};
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
#define createMinMaxParameter(p1, p2, p3, p4) createMinMaxParameter(p1, p2, p3, p4)
|
||||
#else
|
||||
#define createMinMaxParameter(p1, p2, p3, p4) createMinMaxParameter(p1, p3, p4)
|
||||
#endif
|
@ -1,120 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "Action.h"
|
||||
#include <fsfw/introspection/Types.h>
|
||||
#include <fsfw/introspection/TypesHelper.h>
|
||||
#include "ParameterIF.h"
|
||||
// TODO: ifdef introspection stuff
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
class Parameter : public ParameterIF {
|
||||
protected:
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
Parameter(Action *owner, const char *name)
|
||||
: name(name)
|
||||
#else
|
||||
Parameter(Action *owner)
|
||||
#endif
|
||||
{
|
||||
owner->registerParameter(this);
|
||||
}
|
||||
|
||||
public:
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
static Parameter createParameter(Action *owner, const char *name) {
|
||||
return Parameter(owner, name);
|
||||
}
|
||||
#else
|
||||
static Parameter createParameter(Action *owner) { return Parameter(owner); }
|
||||
#endif
|
||||
|
||||
bool isValid() override {
|
||||
return enumHelper<std::is_base_of<EnumIF, T>::value>::isValid(&value);
|
||||
}
|
||||
|
||||
operator T(){
|
||||
return value;
|
||||
}
|
||||
|
||||
Parameter& operator =(const T& newValue){
|
||||
value = newValue;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
Types::ParameterType getType() override {
|
||||
return enumHelper<std::is_base_of<EnumIF, T>::value>::template getType<T>();
|
||||
}
|
||||
#endif
|
||||
|
||||
T value;
|
||||
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const override {
|
||||
return SerializeAdapter::serialize(&value, buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
|
||||
size_t getSerializedSize() const override { return SerializeAdapter::getSerializedSize(&value); }
|
||||
|
||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override {
|
||||
return SerializeAdapter::deSerialize(&value, buffer, size, streamEndianness);
|
||||
}
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
double getFloating() override { return (double)value; }
|
||||
int64_t getSigned() override { return (int64_t)value; }
|
||||
|
||||
bool setFloating(double value) override {
|
||||
if (getType() != Types::FLOATING) {
|
||||
return false;
|
||||
}
|
||||
this->value = T(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool setSigned(int64_t value) override {
|
||||
if ((getType() != Types::SIGNED) && (getType() != Types::ENUM)) {
|
||||
return false;
|
||||
}
|
||||
this->value = T(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
double getMinFloating() override {
|
||||
return enumHelper<std::is_base_of<EnumIF, T>::value>::template getMin<T>();
|
||||
}
|
||||
int64_t getMinSigned() override {
|
||||
return enumHelper<std::is_base_of<EnumIF, T>::value>::template getMin<T>();
|
||||
}
|
||||
|
||||
double getMaxFloating() override {
|
||||
return enumHelper<std::is_base_of<EnumIF, T>::value>::template getMax<T>();
|
||||
}
|
||||
int64_t getMaxSigned() override {
|
||||
return enumHelper<std::is_base_of<EnumIF, T>::value>::template getMax<T>();
|
||||
}
|
||||
|
||||
std::vector<int64_t> getEnumValues() override {
|
||||
return enumHelper<std::is_base_of<EnumIF, T>::value>::getEnumValues(&value);
|
||||
}
|
||||
const char *const *getEnumDescriptions() override {
|
||||
return enumHelper<std::is_base_of<EnumIF, T>::value>::getEnumDescriptions(&value);
|
||||
}
|
||||
|
||||
const char *getName() override { return name; }
|
||||
|
||||
private:
|
||||
const char *name;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
#define createParameter(p1, p2) createParameter(p1, p2)
|
||||
#else
|
||||
#define createParameter(p1, p2) createParameter(p1)
|
||||
#endif
|
@ -1,45 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <fsfw/serialize/SerializeIF.h>
|
||||
#include <fsfw/introspection/Types.h>
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
#include <vector>
|
||||
#endif
|
||||
|
||||
class ParameterIF : public SerializeIF {
|
||||
public:
|
||||
virtual bool isValid() = 0;
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
|
||||
|
||||
|
||||
virtual const char *getName() = 0;
|
||||
|
||||
virtual Types::ParameterType getType() = 0;
|
||||
|
||||
virtual double getFloating() = 0;
|
||||
virtual int64_t getSigned() = 0;
|
||||
|
||||
virtual bool setFloating(double value) = 0;
|
||||
virtual bool setSigned(int64_t value) = 0;
|
||||
|
||||
virtual double getMinFloating() = 0;
|
||||
virtual int64_t getMinSigned() = 0;
|
||||
|
||||
virtual double getMaxFloating() = 0;
|
||||
virtual int64_t getMaxSigned() = 0;
|
||||
|
||||
virtual std::vector<int64_t> getEnumValues() = 0;
|
||||
virtual const char *const * getEnumDescriptions() = 0;
|
||||
|
||||
// ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
// Endianness streamEndianness) const override = 0;
|
||||
|
||||
// size_t getSerializedSize() const override = 0;
|
||||
|
||||
// ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
// Endianness streamEndianness) override = 0;
|
||||
|
||||
#endif
|
||||
};
|
@ -44,27 +44,11 @@ void SimpleActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId
|
||||
if (result != returnvalue::OK) {
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
ipcStore->deleteData(dataAddress);
|
||||
return;
|
||||
}
|
||||
auto actionIter = actionMap.find(actionId);
|
||||
if (actionIter == actionMap.end()){
|
||||
CommandMessage reply;
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, HasActionsIF::INVALID_ACTION_ID);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
ipcStore->deleteData(dataAddress);
|
||||
return;
|
||||
}
|
||||
Action* action = actionIter->second;
|
||||
result = action->deSerialize(&dataPtr, &size, SerializeIF::Endianness::NETWORK);
|
||||
if ((result != returnvalue::OK) or (size != 0)) {
|
||||
CommandMessage reply;
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, HasActionsIF::INVALID_PARAMETERS);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
ipcStore->deleteData(dataAddress);
|
||||
return;
|
||||
}
|
||||
result = action->handle();
|
||||
lastCommander = commandedBy;
|
||||
lastAction = actionId;
|
||||
result = owner->executeAction(actionId, commandedBy, dataPtr, size);
|
||||
ipcStore->deleteData(dataAddress);
|
||||
switch (result) {
|
||||
case returnvalue::OK:
|
||||
|
@ -1,29 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Action.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
|
||||
template <class owner, class action, class ActionEnum>
|
||||
class TemplateAction : public Action {
|
||||
public:
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
TemplateAction(owner *myOwner, ActionEnum id) : Action(), myOwner(myOwner) {
|
||||
Action::setEnum(&id);
|
||||
if (myOwner->getActionHelper() == nullptr) {
|
||||
sif::error
|
||||
<< "TemplateAction::TemplateAction: Action instances need to be created (ie located) after the actionHelper instance."
|
||||
<< "Program will segfault now..." << std::endl;
|
||||
}
|
||||
myOwner->getActionHelper()->registerAction(this);
|
||||
}
|
||||
#else
|
||||
TemplateAction(owner *myOwner, ActionEnum id) : Action((uint32_t)id), myOwner(myOwner) {
|
||||
myOwner->getActionHelper()->registerAction(this);
|
||||
}
|
||||
#endif
|
||||
|
||||
ReturnValue_t handle() override { return myOwner->handleAction(dynamic_cast<action *>(this)); }
|
||||
|
||||
private:
|
||||
owner *myOwner;
|
||||
};
|
@ -1,25 +1,24 @@
|
||||
#include "fsfw/cfdp/CfdpHandler.h"
|
||||
#include "fsfw/cfdp/CFDPHandler.h"
|
||||
|
||||
#include "fsfw/cfdp/CfdpMessage.h"
|
||||
#include "fsfw/cfdp/CFDPMessage.h"
|
||||
#include "fsfw/ipc/CommandMessage.h"
|
||||
#include "fsfw/ipc/QueueFactory.h"
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw/storagemanager/storeAddress.h"
|
||||
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
|
||||
|
||||
object_id_t CfdpHandler::packetSource = 0;
|
||||
object_id_t CfdpHandler::packetDestination = 0;
|
||||
object_id_t CFDPHandler::packetSource = 0;
|
||||
object_id_t CFDPHandler::packetDestination = 0;
|
||||
|
||||
CfdpHandler::CfdpHandler(object_id_t setObjectId, CFDPDistributor* dist)
|
||||
CFDPHandler::CFDPHandler(object_id_t setObjectId, CFDPDistributor* dist)
|
||||
: SystemObject(setObjectId) {
|
||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||
requestQueue = QueueFactory::instance()->createMessageQueue(
|
||||
CFDP_HANDLER_MAX_RECEPTION, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||
requestQueue = QueueFactory::instance()->createMessageQueue(CFDP_HANDLER_MAX_RECEPTION);
|
||||
distributor = dist;
|
||||
}
|
||||
|
||||
CfdpHandler::~CfdpHandler() = default;
|
||||
CFDPHandler::~CFDPHandler() {}
|
||||
|
||||
ReturnValue_t CfdpHandler::initialize() {
|
||||
ReturnValue_t CFDPHandler::initialize() {
|
||||
ReturnValue_t result = SystemObject::initialize();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
@ -28,7 +27,7 @@ ReturnValue_t CfdpHandler::initialize() {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t CfdpHandler::handleRequest(store_address_t storeId) {
|
||||
ReturnValue_t CFDPHandler::handleRequest(store_address_t storeId) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "CFDPHandler::handleRequest" << std::endl;
|
||||
@ -42,17 +41,17 @@ ReturnValue_t CfdpHandler::handleRequest(store_address_t storeId) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t CfdpHandler::performOperation(uint8_t opCode) {
|
||||
ReturnValue_t CFDPHandler::performOperation(uint8_t opCode) {
|
||||
ReturnValue_t status = returnvalue::OK;
|
||||
CommandMessage currentMessage;
|
||||
for (status = this->requestQueue->receiveMessage(¤tMessage); status == returnvalue::OK;
|
||||
status = this->requestQueue->receiveMessage(¤tMessage)) {
|
||||
store_address_t storeId = CfdpMessage::getStoreId(¤tMessage);
|
||||
store_address_t storeId = CFDPMessage::getStoreId(¤tMessage);
|
||||
this->handleRequest(storeId);
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
uint16_t CfdpHandler::getIdentifier() { return 0; }
|
||||
uint16_t CFDPHandler::getIdentifier() { return 0; }
|
||||
|
||||
MessageQueueId_t CfdpHandler::getRequestQueue() { return this->requestQueue->getId(); }
|
||||
MessageQueueId_t CFDPHandler::getRequestQueue() { return this->requestQueue->getId(); }
|
@ -12,15 +12,15 @@ namespace Factory {
|
||||
void setStaticFrameworkObjectIds();
|
||||
}
|
||||
|
||||
class CfdpHandler : public ExecutableObjectIF, public AcceptsTelecommandsIF, public SystemObject {
|
||||
class CFDPHandler : public ExecutableObjectIF, public AcceptsTelecommandsIF, public SystemObject {
|
||||
friend void(Factory::setStaticFrameworkObjectIds)();
|
||||
|
||||
public:
|
||||
CfdpHandler(object_id_t setObjectId, CFDPDistributor* distributor);
|
||||
CFDPHandler(object_id_t setObjectId, CFDPDistributor* distributor);
|
||||
/**
|
||||
* The destructor is empty.
|
||||
*/
|
||||
virtual ~CfdpHandler();
|
||||
virtual ~CFDPHandler();
|
||||
|
||||
virtual ReturnValue_t handleRequest(store_address_t storeId);
|
||||
|
||||
@ -42,7 +42,7 @@ class CfdpHandler : public ExecutableObjectIF, public AcceptsTelecommandsIF, pub
|
||||
* The current CFDP packet to be processed.
|
||||
* It is deleted after handleRequest was executed.
|
||||
*/
|
||||
CfdpPacketStored currentPacket;
|
||||
CFDPPacketStored currentPacket;
|
||||
|
||||
static object_id_t packetSource;
|
||||
|
17
src/fsfw/cfdp/CFDPMessage.cpp
Normal file
17
src/fsfw/cfdp/CFDPMessage.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
#include "CFDPMessage.h"
|
||||
|
||||
CFDPMessage::CFDPMessage() {}
|
||||
|
||||
CFDPMessage::~CFDPMessage() {}
|
||||
|
||||
void CFDPMessage::setCommand(CommandMessage *message, store_address_t cfdpPacket) {
|
||||
message->setParameter(cfdpPacket.raw);
|
||||
}
|
||||
|
||||
store_address_t CFDPMessage::getStoreId(const CommandMessage *message) {
|
||||
store_address_t storeAddressCFDPPacket;
|
||||
storeAddressCFDPPacket = message->getParameter();
|
||||
return storeAddressCFDPPacket;
|
||||
}
|
||||
|
||||
void CFDPMessage::clear(CommandMessage *message) {}
|
@ -5,14 +5,14 @@
|
||||
#include "fsfw/objectmanager/ObjectManagerIF.h"
|
||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||
|
||||
class CfdpMessage {
|
||||
class CFDPMessage {
|
||||
private:
|
||||
CfdpMessage();
|
||||
CFDPMessage();
|
||||
|
||||
public:
|
||||
static const uint8_t MESSAGE_ID = messagetypes::CFDP;
|
||||
|
||||
virtual ~CfdpMessage();
|
||||
virtual ~CFDPMessage();
|
||||
static void setCommand(CommandMessage* message, store_address_t cfdpPacket);
|
||||
|
||||
static store_address_t getStoreId(const CommandMessage* message);
|
@ -1,4 +1,4 @@
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE CfdpHandler.cpp CfdpMessage.cpp)
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE CFDPHandler.cpp CFDPMessage.cpp)
|
||||
|
||||
add_subdirectory(pdu)
|
||||
add_subdirectory(tlv)
|
||||
|
@ -1,17 +0,0 @@
|
||||
#include "CfdpMessage.h"
|
||||
|
||||
CfdpMessage::CfdpMessage() = default;
|
||||
|
||||
CfdpMessage::~CfdpMessage() = default;
|
||||
|
||||
void CfdpMessage::setCommand(CommandMessage *message, store_address_t cfdpPacket) {
|
||||
message->setParameter(cfdpPacket.raw);
|
||||
}
|
||||
|
||||
store_address_t CfdpMessage::getStoreId(const CommandMessage *message) {
|
||||
store_address_t storeId;
|
||||
storeId = static_cast<store_address_t>(message->getParameter());
|
||||
return storeId;
|
||||
}
|
||||
|
||||
void CfdpMessage::clear(CommandMessage *message) {}
|
@ -21,7 +21,7 @@ cfdp::Lv& cfdp::Lv::operator=(const Lv& other) {
|
||||
if (value == nullptr or otherSize == 0) {
|
||||
this->zeroLen = true;
|
||||
}
|
||||
this->value.setConstBuffer(value, otherSize);
|
||||
this->value.setBuffer(value, otherSize);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -70,7 +70,7 @@ ReturnValue_t cfdp::Lv::deSerialize(const uint8_t** buffer, size_t* size,
|
||||
}
|
||||
zeroLen = false;
|
||||
// Zero-copy implementation
|
||||
value.setConstBuffer(*buffer + 1, lengthField);
|
||||
value.setBuffer(const_cast<uint8_t*>(*buffer + 1), lengthField);
|
||||
*buffer += 1 + lengthField;
|
||||
*size -= 1 + lengthField;
|
||||
return returnvalue::OK;
|
||||
|
@ -75,7 +75,7 @@ ReturnValue_t cfdp::Tlv::deSerialize(const uint8_t **buffer, size_t *size,
|
||||
}
|
||||
zeroLen = false;
|
||||
// Zero-copy implementation
|
||||
value.setConstBuffer(*buffer + 1, lengthField);
|
||||
value.setBuffer(const_cast<uint8_t *>(*buffer + 1), lengthField);
|
||||
*buffer += 1 + lengthField;
|
||||
*size -= 1 + lengthField;
|
||||
return returnvalue::OK;
|
||||
@ -96,7 +96,7 @@ void cfdp::Tlv::setValue(uint8_t *value, size_t len) {
|
||||
if (len > 0) {
|
||||
zeroLen = false;
|
||||
}
|
||||
this->value.setConstBuffer(value, len);
|
||||
this->value.setBuffer(value, len);
|
||||
}
|
||||
|
||||
uint8_t cfdp::Tlv::getLengthField() const { return this->value.getSerializedSize() - 1; }
|
||||
|
@ -13,9 +13,7 @@ ControllerBase::ControllerBase(object_id_t setObjectId, object_id_t parentId,
|
||||
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); }
|
||||
@ -103,10 +101,6 @@ ReturnValue_t ControllerBase::performOperation(uint8_t opCode) {
|
||||
|
||||
void ControllerBase::modeChanged(Mode_t mode_, Submode_t submode_) {}
|
||||
|
||||
const ModeHelper * ControllerBase::getModeHelper() const {
|
||||
return &modeHelper;
|
||||
}
|
||||
|
||||
ReturnValue_t ControllerBase::setHealth(HealthState health) {
|
||||
switch (health) {
|
||||
case HEALTHY:
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
#include "fsfw/health/HasHealthIF.h"
|
||||
#include "fsfw/health/HealthHelper.h"
|
||||
#include "fsfw/introspection/ClasslessEnum.h"
|
||||
#include "fsfw/modes/HasModesIF.h"
|
||||
#include "fsfw/modes/ModeHelper.h"
|
||||
#include "fsfw/objectmanager/SystemObject.h"
|
||||
@ -21,9 +20,7 @@ class ControllerBase : public HasModesIF,
|
||||
public ExecutableObjectIF,
|
||||
public SystemObject {
|
||||
public:
|
||||
FSFW_CLASSLESS_ENUM(ControllerModes, Mode_t,
|
||||
((CONTROLLER_MODE_ON, MODE_ON, "On"))((CONTROLLER_MODE_OFF, MODE_OFF,
|
||||
"Off"))((MODE_NORMAL, 2, "Normal")))
|
||||
static const Mode_t MODE_NORMAL = 2;
|
||||
|
||||
ControllerBase(object_id_t setObjectId, object_id_t parentId, size_t commandQueueDepth = 3);
|
||||
~ControllerBase() override;
|
||||
@ -42,9 +39,6 @@ class ControllerBase : public HasModesIF,
|
||||
void setTaskIF(PeriodicTaskIF *task) override;
|
||||
ReturnValue_t initializeAfterTaskCreation() override;
|
||||
|
||||
/** HasModeIF override */
|
||||
const ModeHelper *getModeHelper() const override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Implemented by child class. Handle command messages which are not
|
||||
|
@ -8,12 +8,11 @@ ExtendedControllerBase::ExtendedControllerBase(object_id_t objectId, object_id_t
|
||||
|
||||
ExtendedControllerBase::~ExtendedControllerBase() = default;
|
||||
|
||||
ActionHelper *ExtendedControllerBase::getActionHelper() {
|
||||
return &actionHelper;
|
||||
}
|
||||
|
||||
ReturnValue_t ExtendedControllerBase::executeAction(Action *action) {
|
||||
return action->handle();
|
||||
ReturnValue_t ExtendedControllerBase::executeAction(ActionId_t actionId,
|
||||
MessageQueueId_t commandedBy,
|
||||
const uint8_t *data, size_t size) {
|
||||
/* Needs to be overriden and implemented by child class. */
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
object_id_t ExtendedControllerBase::getObjectId() const { return SystemObject::getObjectId(); }
|
||||
|
@ -29,10 +29,6 @@ class ExtendedControllerBase : public ControllerBase,
|
||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
ReturnValue_t initializeAfterTaskCreation() override;
|
||||
|
||||
/* HasActionsIF overrides */
|
||||
ActionHelper* getActionHelper() override;
|
||||
ReturnValue_t executeAction(Action* actionId) override;
|
||||
|
||||
protected:
|
||||
LocalDataPoolManager poolManager;
|
||||
ActionHelper actionHelper;
|
||||
@ -53,6 +49,10 @@ class ExtendedControllerBase : public ControllerBase,
|
||||
/* Handle the four messages mentioned above */
|
||||
void handleQueue() override;
|
||||
|
||||
/* HasActionsIF overrides */
|
||||
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size) override;
|
||||
|
||||
/* HasLocalDatapoolIF overrides */
|
||||
LocalDataPoolManager* getHkManagerHandle() override;
|
||||
[[nodiscard]] object_id_t getObjectId() const override;
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||
#include "fsfw/tmtcpacket/ccsds/SpacePacketReader.h"
|
||||
#include "fsfw/tmtcpacket/SpacePacketBase.h"
|
||||
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
||||
#include "fsfw/tmtcservices/TmTcMessage.h"
|
||||
|
||||
|
@ -79,7 +79,8 @@ class HasLocalDataPoolIF {
|
||||
* @param clearMessage If this is set to true, the pool manager will take care of
|
||||
* clearing the store automatically
|
||||
*/
|
||||
virtual void handleChangedDataset(sid_t sid, store_address_t storeId = store_address_t::invalid(),
|
||||
virtual void handleChangedDataset(sid_t sid,
|
||||
store_address_t storeId = storeId::INVALID_STORE_ADDRESS,
|
||||
bool* clearMessage = nullptr) {
|
||||
if (clearMessage != nullptr) {
|
||||
*clearMessage = true;
|
||||
@ -99,7 +100,7 @@ class HasLocalDataPoolIF {
|
||||
* after the callback.
|
||||
*/
|
||||
virtual void handleChangedPoolVariable(gp_id_t gpid,
|
||||
store_address_t storeId = store_address_t::invalid(),
|
||||
store_address_t storeId = storeId::INVALID_STORE_ADDRESS,
|
||||
bool* clearMessage = nullptr) {
|
||||
if (clearMessage != nullptr) {
|
||||
*clearMessage = true;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
|
||||
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
|
||||
#include "fsfw/datapoollocal.h"
|
||||
@ -14,7 +15,6 @@
|
||||
#include "internal/HasLocalDpIFManagerAttorney.h"
|
||||
#include "internal/LocalPoolDataSetAttorney.h"
|
||||
|
||||
// TODO: Get rid of this. This should be a constructor argument, not something hardcoded in any way
|
||||
object_id_t LocalDataPoolManager::defaultHkDestination = objects::PUS_SERVICE_3_HOUSEKEEPING;
|
||||
|
||||
LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner, MessageQueueIF* queueToUse,
|
||||
@ -57,7 +57,7 @@ ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) {
|
||||
}
|
||||
|
||||
if (defaultHkDestination != objects::NO_OBJECT) {
|
||||
auto* hkPacketReceiver =
|
||||
AcceptsHkPacketsIF* hkPacketReceiver =
|
||||
ObjectManager::instance()->get<AcceptsHkPacketsIF>(defaultHkDestination);
|
||||
if (hkPacketReceiver != nullptr) {
|
||||
hkDestinationId = hkPacketReceiver->getHkQueue();
|
||||
@ -209,9 +209,9 @@ ReturnValue_t LocalDataPoolManager::handleNotificationSnapshot(HkReceiver& recei
|
||||
}
|
||||
|
||||
/* Prepare and send update snapshot */
|
||||
timeval now{};
|
||||
timeval now;
|
||||
Clock::getClock_timeval(&now);
|
||||
CCSDSTime::CDS_short cds{};
|
||||
CCSDSTime::CDS_short cds;
|
||||
CCSDSTime::convertToCcsds(&cds, &now);
|
||||
HousekeepingSnapshot updatePacket(
|
||||
reinterpret_cast<uint8_t*>(&cds), sizeof(cds),
|
||||
@ -245,9 +245,9 @@ ReturnValue_t LocalDataPoolManager::handleNotificationSnapshot(HkReceiver& recei
|
||||
}
|
||||
|
||||
/* Prepare and send update snapshot */
|
||||
timeval now{};
|
||||
timeval now;
|
||||
Clock::getClock_timeval(&now);
|
||||
CCSDSTime::CDS_short cds{};
|
||||
CCSDSTime::CDS_short cds;
|
||||
CCSDSTime::convertToCcsds(&cds, &now);
|
||||
HousekeepingSnapshot updatePacket(
|
||||
reinterpret_cast<uint8_t*>(&cds), sizeof(cds),
|
||||
@ -291,7 +291,12 @@ ReturnValue_t LocalDataPoolManager::addUpdateToStore(HousekeepingSnapshot& updat
|
||||
|
||||
void LocalDataPoolManager::handleChangeResetLogic(DataType type, DataId dataId,
|
||||
MarkChangedIF* toReset) {
|
||||
for (auto& changeInfo : hkUpdateResetList) {
|
||||
if (hkUpdateResetList == nullptr) {
|
||||
/* Config error */
|
||||
return;
|
||||
}
|
||||
HkUpdateResetList& listRef = *hkUpdateResetList;
|
||||
for (auto& changeInfo : listRef) {
|
||||
if (changeInfo.dataType != type) {
|
||||
continue;
|
||||
}
|
||||
@ -321,37 +326,38 @@ void LocalDataPoolManager::handleChangeResetLogic(DataType type, DataId dataId,
|
||||
}
|
||||
|
||||
void LocalDataPoolManager::resetHkUpdateResetHelper() {
|
||||
for (auto& changeInfo : hkUpdateResetList) {
|
||||
if (hkUpdateResetList == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& changeInfo : *hkUpdateResetList) {
|
||||
changeInfo.currentUpdateCounter = changeInfo.updateCounter;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t LocalDataPoolManager::subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams params) {
|
||||
return subscribeForPeriodicPacket(params);
|
||||
}
|
||||
|
||||
ReturnValue_t LocalDataPoolManager::subscribeForDiagPeriodicPacket(
|
||||
subdp::DiagnosticsHkPeriodicParams params) {
|
||||
return subscribeForPeriodicPacket(params);
|
||||
}
|
||||
|
||||
ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(subdp::ParamsBase& params) {
|
||||
struct HkReceiver hkReceiver;
|
||||
hkReceiver.dataId.sid = params.sid;
|
||||
hkReceiver.reportingType = ReportingType::PERIODIC;
|
||||
hkReceiver.dataType = DataType::DATA_SET;
|
||||
if (params.receiver == MessageQueueIF::NO_QUEUE) {
|
||||
hkReceiver.destinationQueue = hkDestinationId;
|
||||
} else {
|
||||
hkReceiver.destinationQueue = params.receiver;
|
||||
ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(sid_t sid, bool enableReporting,
|
||||
float collectionInterval,
|
||||
bool isDiagnostics,
|
||||
object_id_t packetDestination) {
|
||||
AcceptsHkPacketsIF* hkReceiverObject =
|
||||
ObjectManager::instance()->get<AcceptsHkPacketsIF>(packetDestination);
|
||||
if (hkReceiverObject == nullptr) {
|
||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "subscribeForPeriodicPacket",
|
||||
QUEUE_OR_DESTINATION_INVALID);
|
||||
return QUEUE_OR_DESTINATION_INVALID;
|
||||
}
|
||||
|
||||
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, params.sid);
|
||||
struct HkReceiver hkReceiver;
|
||||
hkReceiver.dataId.sid = sid;
|
||||
hkReceiver.reportingType = ReportingType::PERIODIC;
|
||||
hkReceiver.dataType = DataType::DATA_SET;
|
||||
hkReceiver.destinationQueue = hkReceiverObject->getHkQueue();
|
||||
|
||||
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
||||
if (dataSet != nullptr) {
|
||||
LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, params.enableReporting);
|
||||
LocalPoolDataSetAttorney::setDiagnostic(*dataSet, params.isDiagnostics());
|
||||
LocalPoolDataSetAttorney::initializePeriodicHelper(*dataSet, params.collectionInterval,
|
||||
LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, enableReporting);
|
||||
LocalPoolDataSetAttorney::setDiagnostic(*dataSet, isDiagnostics);
|
||||
LocalPoolDataSetAttorney::initializePeriodicHelper(*dataSet, collectionInterval,
|
||||
owner->getPeriodicOperationFrequency());
|
||||
}
|
||||
|
||||
@ -359,30 +365,27 @@ ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(subdp::ParamsBase
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t LocalDataPoolManager::subscribeForRegularUpdatePacket(
|
||||
subdp::RegularHkUpdateParams params) {
|
||||
return subscribeForUpdatePacket(params);
|
||||
}
|
||||
ReturnValue_t LocalDataPoolManager::subscribeForDiagUpdatePacket(
|
||||
subdp::DiagnosticsHkUpdateParams params) {
|
||||
return subscribeForUpdatePacket(params);
|
||||
}
|
||||
|
||||
ReturnValue_t LocalDataPoolManager::subscribeForUpdatePacket(subdp::ParamsBase& params) {
|
||||
struct HkReceiver hkReceiver;
|
||||
hkReceiver.dataId.sid = params.sid;
|
||||
hkReceiver.reportingType = ReportingType::UPDATE_HK;
|
||||
hkReceiver.dataType = DataType::DATA_SET;
|
||||
if (params.receiver == MessageQueueIF::NO_QUEUE) {
|
||||
hkReceiver.destinationQueue = hkDestinationId;
|
||||
} else {
|
||||
hkReceiver.destinationQueue = params.receiver;
|
||||
ReturnValue_t LocalDataPoolManager::subscribeForUpdatePacket(sid_t sid, bool isDiagnostics,
|
||||
bool reportingEnabled,
|
||||
object_id_t packetDestination) {
|
||||
AcceptsHkPacketsIF* hkReceiverObject =
|
||||
ObjectManager::instance()->get<AcceptsHkPacketsIF>(packetDestination);
|
||||
if (hkReceiverObject == nullptr) {
|
||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "subscribeForPeriodicPacket",
|
||||
QUEUE_OR_DESTINATION_INVALID);
|
||||
return QUEUE_OR_DESTINATION_INVALID;
|
||||
}
|
||||
|
||||
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, params.sid);
|
||||
struct HkReceiver hkReceiver;
|
||||
hkReceiver.dataId.sid = sid;
|
||||
hkReceiver.reportingType = ReportingType::UPDATE_HK;
|
||||
hkReceiver.dataType = DataType::DATA_SET;
|
||||
hkReceiver.destinationQueue = hkReceiverObject->getHkQueue();
|
||||
|
||||
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
||||
if (dataSet != nullptr) {
|
||||
LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, true);
|
||||
LocalPoolDataSetAttorney::setDiagnostic(*dataSet, params.isDiagnostics());
|
||||
LocalPoolDataSetAttorney::setDiagnostic(*dataSet, isDiagnostics);
|
||||
}
|
||||
|
||||
hkReceivers.push_back(hkReceiver);
|
||||
@ -433,7 +436,11 @@ ReturnValue_t LocalDataPoolManager::subscribeForVariableUpdateMessage(
|
||||
}
|
||||
|
||||
void LocalDataPoolManager::handleHkUpdateResetListInsertion(DataType dataType, DataId dataId) {
|
||||
for (auto& updateResetStruct : hkUpdateResetList) {
|
||||
if (hkUpdateResetList == nullptr) {
|
||||
hkUpdateResetList = new std::vector<struct HkUpdateResetHelper>();
|
||||
}
|
||||
|
||||
for (auto& updateResetStruct : *hkUpdateResetList) {
|
||||
if (dataType == DataType::DATA_SET) {
|
||||
if (updateResetStruct.dataId.sid == dataId.sid) {
|
||||
updateResetStruct.updateCounter++;
|
||||
@ -457,7 +464,7 @@ void LocalDataPoolManager::handleHkUpdateResetListInsertion(DataType dataType, D
|
||||
} else {
|
||||
hkUpdateResetHelper.dataId.localPoolId = dataId.localPoolId;
|
||||
}
|
||||
hkUpdateResetList.push_back(hkUpdateResetHelper);
|
||||
hkUpdateResetList->push_back(hkUpdateResetHelper);
|
||||
}
|
||||
|
||||
ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(CommandMessage* message) {
|
||||
@ -570,10 +577,6 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(CommandMessage* me
|
||||
|
||||
CommandMessage reply;
|
||||
if (result != returnvalue::OK) {
|
||||
if (result == WRONG_HK_PACKET_TYPE) {
|
||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "handleHousekeepingMessage",
|
||||
WRONG_HK_PACKET_TYPE);
|
||||
}
|
||||
HousekeepingMessage::setHkRequestFailureReply(&reply, sid, result);
|
||||
} else {
|
||||
HousekeepingMessage::setHkRequestSuccessReply(&reply, sid);
|
||||
@ -636,7 +639,6 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid,
|
||||
/* Error, all destinations invalid */
|
||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "generateHousekeepingPacket",
|
||||
QUEUE_OR_DESTINATION_INVALID);
|
||||
return QUEUE_OR_DESTINATION_INVALID;
|
||||
}
|
||||
destination = hkDestinationId;
|
||||
}
|
||||
@ -813,7 +815,9 @@ void LocalDataPoolManager::clearReceiversList() {
|
||||
/* Clear the vector completely and releases allocated memory. */
|
||||
HkReceivers().swap(hkReceivers);
|
||||
/* Also clear the reset helper if it exists */
|
||||
HkUpdateResetList().swap(hkUpdateResetList);
|
||||
if (hkUpdateResetList != nullptr) {
|
||||
HkUpdateResetList().swap(*hkUpdateResetList);
|
||||
}
|
||||
}
|
||||
|
||||
MutexIF* LocalDataPoolManager::getLocalPoolMutex() { return this->mutex; }
|
||||
@ -829,8 +833,6 @@ void LocalDataPoolManager::printWarningOrError(sif::OutputTypes outputType,
|
||||
errorPrint = "Dataset not found";
|
||||
} else if (error == POOLOBJECT_NOT_FOUND) {
|
||||
errorPrint = "Pool Object not found";
|
||||
} else if (error == WRONG_HK_PACKET_TYPE) {
|
||||
errorPrint = "Wrong Packet Type";
|
||||
} else if (error == returnvalue::FAILED) {
|
||||
if (outputType == sif::OutputTypes::OUT_WARNING) {
|
||||
errorPrint = "Generic Warning";
|
||||
@ -875,7 +877,3 @@ void LocalDataPoolManager::printWarningOrError(sif::OutputTypes outputType,
|
||||
}
|
||||
|
||||
LocalDataPoolManager* LocalDataPoolManager::getPoolManagerHandle() { return this; }
|
||||
|
||||
void LocalDataPoolManager::setHkDestinationId(MessageQueueId_t hkDestId) {
|
||||
hkDestinationId = hkDestId;
|
||||
}
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include "ProvidesDataPoolSubscriptionIF.h"
|
||||
#include "fsfw/datapool/DataSetIF.h"
|
||||
#include "fsfw/datapool/PoolEntry.h"
|
||||
#include "fsfw/housekeeping/AcceptsHkPacketsIF.h"
|
||||
#include "fsfw/housekeeping/HousekeepingMessage.h"
|
||||
#include "fsfw/housekeeping/HousekeepingPacketDownlink.h"
|
||||
#include "fsfw/housekeeping/PeriodicHousekeepingHelper.h"
|
||||
@ -81,9 +80,7 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
||||
*/
|
||||
LocalDataPoolManager(HasLocalDataPoolIF* owner, MessageQueueIF* queueToUse,
|
||||
bool appendValidityBuffer = true);
|
||||
~LocalDataPoolManager() override;
|
||||
|
||||
void setHkDestinationId(MessageQueueId_t hkDestId);
|
||||
virtual ~LocalDataPoolManager();
|
||||
|
||||
/**
|
||||
* Assigns the queue to use. Make sure to call this in the #initialize
|
||||
@ -115,6 +112,31 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
||||
*/
|
||||
virtual ReturnValue_t performHkOperation();
|
||||
|
||||
/**
|
||||
* @brief Subscribe for the generation of periodic packets.
|
||||
* @details
|
||||
* This subscription mechanism will generally be used by the data creator
|
||||
* to generate housekeeping packets which are downlinked directly.
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t subscribeForPeriodicPacket(
|
||||
sid_t sid, bool enableReporting, float collectionInterval, bool isDiagnostics,
|
||||
object_id_t packetDestination = defaultHkDestination) override;
|
||||
|
||||
/**
|
||||
* @brief Subscribe for the generation of packets if the dataset
|
||||
* is marked as changed.
|
||||
* @details
|
||||
* This subscription mechanism will generally be used by the data creator.
|
||||
* @param sid
|
||||
* @param isDiagnostics
|
||||
* @param packetDestination
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t subscribeForUpdatePacket(
|
||||
sid_t sid, bool reportingEnabled, bool isDiagnostics,
|
||||
object_id_t packetDestination = defaultHkDestination) override;
|
||||
|
||||
/**
|
||||
* @brief Subscribe for a notification message which will be sent
|
||||
* if a dataset has changed.
|
||||
@ -129,7 +151,7 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
||||
* Otherwise, only an notification message is sent.
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t subscribeForSetUpdateMessage(uint32_t setId, object_id_t destinationObject,
|
||||
ReturnValue_t subscribeForSetUpdateMessage(const uint32_t setId, object_id_t destinationObject,
|
||||
MessageQueueId_t targetQueueId,
|
||||
bool generateSnapshot) override;
|
||||
|
||||
@ -147,7 +169,7 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
||||
* Otherwise, only an notification message is sent.
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t subscribeForVariableUpdateMessage(lp_id_t localPoolId,
|
||||
ReturnValue_t subscribeForVariableUpdateMessage(const lp_id_t localPoolId,
|
||||
object_id_t destinationObject,
|
||||
MessageQueueId_t targetQueueId,
|
||||
bool generateSnapshot) override;
|
||||
@ -230,7 +252,7 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
||||
*/
|
||||
void clearReceiversList();
|
||||
|
||||
[[nodiscard]] object_id_t getCreatorObjectId() const;
|
||||
object_id_t getCreatorObjectId() const;
|
||||
|
||||
/**
|
||||
* Get the pointer to the mutex. Can be used to lock the data pool
|
||||
@ -240,17 +262,9 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
||||
*/
|
||||
MutexIF* getMutexHandle();
|
||||
|
||||
LocalDataPoolManager* getPoolManagerHandle() override;
|
||||
ReturnValue_t subscribeForRegularPeriodicPacket(subdp::RegularHkPeriodicParams params) override;
|
||||
ReturnValue_t subscribeForDiagPeriodicPacket(subdp::DiagnosticsHkPeriodicParams params) override;
|
||||
|
||||
ReturnValue_t subscribeForRegularUpdatePacket(subdp::RegularHkUpdateParams params) override;
|
||||
ReturnValue_t subscribeForDiagUpdatePacket(subdp::DiagnosticsHkUpdateParams params) override;
|
||||
virtual LocalDataPoolManager* getPoolManagerHandle() override;
|
||||
|
||||
protected:
|
||||
ReturnValue_t subscribeForPeriodicPacket(subdp::ParamsBase& params);
|
||||
ReturnValue_t subscribeForUpdatePacket(subdp::ParamsBase& params);
|
||||
|
||||
/** Core data structure for the actual pool data */
|
||||
localpool::DataPool localPoolMap;
|
||||
/** Every housekeeping data manager has a mutex to protect access
|
||||
@ -298,8 +312,8 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
||||
|
||||
using HkUpdateResetList = std::vector<struct HkUpdateResetHelper>;
|
||||
/** This list is used to manage creating multiple update packets and only resetting
|
||||
the update flag if all of them were created. */
|
||||
HkUpdateResetList hkUpdateResetList = HkUpdateResetList();
|
||||
the update flag if all of them were created. Will only be created when needed. */
|
||||
HkUpdateResetList* hkUpdateResetList = nullptr;
|
||||
|
||||
/** This is the map holding the actual data. Should only be initialized
|
||||
* once ! */
|
||||
|
@ -162,7 +162,6 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
|
||||
object_id_t getCreatorObjectId();
|
||||
|
||||
bool getReportingEnabled() const;
|
||||
void setReportingEnabled(bool enabled);
|
||||
|
||||
/**
|
||||
* Returns the current periodic HK generation interval this set
|
||||
@ -190,6 +189,7 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
|
||||
* Used for periodic generation.
|
||||
*/
|
||||
bool reportingEnabled = false;
|
||||
void setReportingEnabled(bool enabled);
|
||||
|
||||
void initializePeriodicHelper(float collectionInterval, dur_millis_t minimumPeriodicInterval,
|
||||
uint8_t nonDiagIntervalFactor = 5);
|
||||
|
@ -1,90 +1,24 @@
|
||||
#ifndef FSFW_DATAPOOLLOCAL_PROVIDESDATAPOOLSUBSCRIPTION_H_
|
||||
#define FSFW_DATAPOOLLOCAL_PROVIDESDATAPOOLSUBSCRIPTION_H_
|
||||
|
||||
#include "fsfw/housekeeping/AcceptsHkPacketsIF.h"
|
||||
#include "fsfw/ipc/MessageQueueIF.h"
|
||||
#include "fsfw/ipc/messageQueueDefinitions.h"
|
||||
#include "fsfw/returnvalues/returnvalue.h"
|
||||
#include "../ipc/messageQueueDefinitions.h"
|
||||
#include "../returnvalues/returnvalue.h"
|
||||
#include "localPoolDefinitions.h"
|
||||
|
||||
namespace subdp {
|
||||
|
||||
struct ParamsBase {
|
||||
ParamsBase(sid_t sid, bool enableReporting, float collectionInterval, bool diagnostics)
|
||||
: sid(sid),
|
||||
enableReporting(enableReporting),
|
||||
collectionInterval(collectionInterval),
|
||||
diagnostics(diagnostics) {}
|
||||
|
||||
[[nodiscard]] bool isDiagnostics() const { return diagnostics; }
|
||||
|
||||
sid_t sid;
|
||||
bool enableReporting;
|
||||
float collectionInterval;
|
||||
MessageQueueId_t receiver = MessageQueueIF::NO_QUEUE;
|
||||
|
||||
protected:
|
||||
bool diagnostics;
|
||||
};
|
||||
|
||||
struct RegularHkPeriodicParams : public ParamsBase {
|
||||
RegularHkPeriodicParams(sid_t sid, bool enableReporting, float collectionInterval)
|
||||
: ParamsBase(sid, enableReporting, collectionInterval, false) {}
|
||||
};
|
||||
|
||||
struct DiagnosticsHkPeriodicParams : public ParamsBase {
|
||||
DiagnosticsHkPeriodicParams(sid_t sid, bool enableReporting, float collectionInterval)
|
||||
: ParamsBase(sid, enableReporting, collectionInterval, true) {}
|
||||
};
|
||||
|
||||
struct RegularHkUpdateParams : public ParamsBase {
|
||||
RegularHkUpdateParams(sid_t sid, bool enableReporting)
|
||||
: ParamsBase(sid, enableReporting, 0.0, false) {}
|
||||
};
|
||||
|
||||
struct DiagnosticsHkUpdateParams : public ParamsBase {
|
||||
DiagnosticsHkUpdateParams(sid_t sid, bool enableReporting)
|
||||
: ParamsBase(sid, enableReporting, 0.0, true) {}
|
||||
};
|
||||
} // namespace subdp
|
||||
|
||||
class ProvidesDataPoolSubscriptionIF {
|
||||
public:
|
||||
virtual ~ProvidesDataPoolSubscriptionIF() = default;
|
||||
virtual ~ProvidesDataPoolSubscriptionIF(){};
|
||||
|
||||
/**
|
||||
* @brief Subscribe for the generation of periodic packets. Used for regular HK packets
|
||||
* @brief Subscribe for the generation of periodic packets.
|
||||
* @details
|
||||
* This subscription mechanism will generally be used by the data creator
|
||||
* to generate housekeeping packets which are downlinked directly.
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams params) = 0;
|
||||
/**
|
||||
* @brief Subscribe for the generation of periodic packets. Used for diagnostic packets
|
||||
* @details
|
||||
* This subscription mechanism will generally be used by the data creator
|
||||
* to generate housekeeping packets which are downlinked directly.
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t subscribeForDiagPeriodicPacket(
|
||||
subdp::DiagnosticsHkPeriodicParams params) = 0;
|
||||
|
||||
[[deprecated(
|
||||
"Please use the new API which takes all arguments as one wrapper "
|
||||
"struct")]] virtual ReturnValue_t
|
||||
subscribeForPeriodicPacket(sid_t sid, bool enableReporting, float collectionInterval,
|
||||
bool isDiagnostics,
|
||||
object_id_t packetDestination = objects::NO_OBJECT) {
|
||||
if (isDiagnostics) {
|
||||
subdp::DiagnosticsHkPeriodicParams params(sid, enableReporting, collectionInterval);
|
||||
return subscribeForDiagPeriodicPacket(params);
|
||||
} else {
|
||||
subdp::RegularHkPeriodicParams params(sid, enableReporting, collectionInterval);
|
||||
return subscribeForRegularPeriodicPacket(params);
|
||||
}
|
||||
}
|
||||
|
||||
virtual ReturnValue_t subscribeForPeriodicPacket(sid_t sid, bool enableReporting,
|
||||
float collectionInterval, bool isDiagnostics,
|
||||
object_id_t packetDestination) = 0;
|
||||
/**
|
||||
* @brief Subscribe for the generation of packets if the dataset
|
||||
* is marked as changed.
|
||||
@ -95,28 +29,9 @@ class ProvidesDataPoolSubscriptionIF {
|
||||
* @param packetDestination
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t subscribeForRegularUpdatePacket(subdp::RegularHkUpdateParams params) = 0;
|
||||
virtual ReturnValue_t subscribeForDiagUpdatePacket(subdp::DiagnosticsHkUpdateParams params) = 0;
|
||||
|
||||
// virtual ReturnValue_t
|
||||
// subscribeForUpdatePacket(sid_t sid, bool reportingEnabled, bool isDiagnostics) {
|
||||
// return subscribeForUpdatePacket(sid, reportingEnabled, isDiagnostics, objects::NO_OBJECT);
|
||||
// }
|
||||
|
||||
[[deprecated(
|
||||
"Please use the new API which takes all arguments as one wrapper "
|
||||
"struct")]] virtual ReturnValue_t
|
||||
subscribeForUpdatePacket(sid_t sid, bool reportingEnabled, bool isDiagnostics,
|
||||
object_id_t packetDestination = objects::NO_OBJECT) {
|
||||
if (isDiagnostics) {
|
||||
subdp::DiagnosticsHkUpdateParams params(sid, reportingEnabled);
|
||||
return subscribeForDiagUpdatePacket(params);
|
||||
} else {
|
||||
subdp::RegularHkUpdateParams params(sid, reportingEnabled);
|
||||
return subscribeForRegularUpdatePacket(params);
|
||||
}
|
||||
}
|
||||
|
||||
virtual ReturnValue_t subscribeForUpdatePacket(sid_t sid, bool reportingEnabled,
|
||||
bool isDiagnostics,
|
||||
object_id_t packetDestination) = 0;
|
||||
/**
|
||||
* @brief Subscribe for a notification message which will be sent
|
||||
* if a dataset has changed.
|
||||
@ -131,7 +46,8 @@ class ProvidesDataPoolSubscriptionIF {
|
||||
* Otherwise, only an notification message is sent.
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t subscribeForSetUpdateMessage(uint32_t setId, object_id_t destinationObject,
|
||||
virtual ReturnValue_t subscribeForSetUpdateMessage(const uint32_t setId,
|
||||
object_id_t destinationObject,
|
||||
MessageQueueId_t targetQueueId,
|
||||
bool generateSnapshot) = 0;
|
||||
/**
|
||||
@ -148,7 +64,7 @@ class ProvidesDataPoolSubscriptionIF {
|
||||
* only an notification message is sent.
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t subscribeForVariableUpdateMessage(lp_id_t localPoolId,
|
||||
virtual ReturnValue_t subscribeForVariableUpdateMessage(const lp_id_t localPoolId,
|
||||
object_id_t destinationObject,
|
||||
MessageQueueId_t targetQueueId,
|
||||
bool generateSnapshot) = 0;
|
||||
|
@ -26,7 +26,11 @@ void AssemblyBase::performChildOperation() {
|
||||
|
||||
void AssemblyBase::startTransition(Mode_t mode, Submode_t submode) {
|
||||
doStartTransition(mode, submode);
|
||||
triggerModeHelperEvents(mode, submode);
|
||||
if (modeHelper.isForced()) {
|
||||
triggerEvent(FORCING_MODE, mode, submode);
|
||||
} else {
|
||||
triggerEvent(CHANGING_MODE, mode, submode);
|
||||
}
|
||||
}
|
||||
|
||||
void AssemblyBase::doStartTransition(Mode_t mode, Submode_t submode) {
|
||||
@ -73,10 +77,9 @@ bool AssemblyBase::handleChildrenChangedHealth() {
|
||||
}
|
||||
HealthState healthState = healthHelper.healthTable->getHealth(iter->first);
|
||||
if (healthState == HasHealthIF::NEEDS_RECOVERY) {
|
||||
triggerEvent(TRYING_RECOVERY, iter->first, 0);
|
||||
triggerEvent(TRYING_RECOVERY);
|
||||
recoveryState = RECOVERY_STARTED;
|
||||
recoveringDevice = iter;
|
||||
// The user needs to take care of commanding the children off in commandChildren
|
||||
doStartTransition(targetMode, targetSubmode);
|
||||
} else {
|
||||
triggerEvent(CHILD_CHANGED_HEALTH);
|
||||
@ -225,9 +228,6 @@ ReturnValue_t AssemblyBase::handleHealthReply(CommandMessage* message) {
|
||||
bool AssemblyBase::checkAndHandleRecovery() {
|
||||
switch (recoveryState) {
|
||||
case RECOVERY_STARTED:
|
||||
// The recovery was already start in #handleChildrenChangedHealth and we just need
|
||||
// to wait for an off time period.
|
||||
// TODO: make time period configurable
|
||||
recoveryState = RECOVERY_WAIT;
|
||||
recoveryOffTimer.resetTimer();
|
||||
return true;
|
||||
@ -266,11 +266,3 @@ void AssemblyBase::overwriteDeviceHealth(object_id_t objectId, HasHealthIF::Heal
|
||||
modeHelper.setForced(true);
|
||||
sendHealthCommand(childrenMap[objectId].commandQueue, EXTERNAL_CONTROL);
|
||||
}
|
||||
|
||||
void AssemblyBase::triggerModeHelperEvents(Mode_t mode, Submode_t submode) {
|
||||
if (modeHelper.isForced()) {
|
||||
triggerEvent(FORCING_MODE, mode, submode);
|
||||
} else {
|
||||
triggerEvent(CHANGING_MODE, mode, submode);
|
||||
}
|
||||
}
|
||||
|
@ -12,8 +12,7 @@
|
||||
* Documentation: Dissertation Baetz p.156, 157.
|
||||
*
|
||||
* This class reduces the complexity of controller components which would
|
||||
* otherwise be needed for the handling of redundant devices. However, it can also be used to
|
||||
* manage the mode keeping and recovery of non-redundant devices
|
||||
* otherwise be needed for the handling of redundant devices.
|
||||
*
|
||||
* The template class monitors mode and health state of its children
|
||||
* and checks availability of devices on every detected change.
|
||||
@ -27,9 +26,11 @@
|
||||
*
|
||||
* Important:
|
||||
*
|
||||
* The implementation must call #registerChild for all commanded children during initialization.
|
||||
* The implementation must call registerChild(object_id_t child)
|
||||
* for all commanded children during initialization.
|
||||
* The implementation must call the initialization function of the base class.
|
||||
* (This will call the function in SubsystemBase)
|
||||
*
|
||||
*/
|
||||
class AssemblyBase : public SubsystemBase {
|
||||
public:
|
||||
@ -46,10 +47,9 @@ class AssemblyBase : public SubsystemBase {
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Command children to reach [mode,submode] combination. Can be done by setting
|
||||
* #commandsOutstanding correctly, or using #executeTable. In case of an FDIR recovery,
|
||||
* the user needs to ensure that the target devices are healthy. If a device is not healthy,
|
||||
* a recovery might be on-going and the device needs to be commanded to off first.
|
||||
* Command children to reach [mode,submode] combination
|
||||
* Can be done by setting #commandsOutstanding correctly,
|
||||
* or using executeTable()
|
||||
* @param mode
|
||||
* @param submode
|
||||
* @return
|
||||
@ -120,19 +120,8 @@ class AssemblyBase : public SubsystemBase {
|
||||
|
||||
virtual ReturnValue_t handleHealthReply(CommandMessage *message);
|
||||
|
||||
/**
|
||||
* @brief Default periodic handler
|
||||
* @details
|
||||
* This is the default periodic handler which will be called by the SubsystemBase
|
||||
* performOperation. It performs the child transitions or reacts to changed health/mode states
|
||||
* of children objects
|
||||
*/
|
||||
virtual void performChildOperation() override;
|
||||
virtual void performChildOperation();
|
||||
|
||||
/**
|
||||
* This function handles changed mode or health states of children
|
||||
* @return
|
||||
*/
|
||||
bool handleChildrenChanged();
|
||||
|
||||
/**
|
||||
@ -145,37 +134,12 @@ class AssemblyBase : public SubsystemBase {
|
||||
|
||||
bool handleChildrenChangedHealth();
|
||||
|
||||
/**
|
||||
* Core transition handler. The default implementation will only do something if
|
||||
* #commandsOutstanding is smaller or equal to zero, which means that all mode commands
|
||||
* from the #doPerformTransition call were executed successfully.
|
||||
*
|
||||
* Unless a second step was requested, the function will then use #checkChildrenState to
|
||||
* determine whether the target mode was reached.
|
||||
*
|
||||
* There is some special handling for certain (internal) modes:
|
||||
* - A second step is necessary. #commandChildren will be performed again
|
||||
* - The device health was overwritten. #commandChildren will be called
|
||||
* - A recovery is ongoing. #checkAndHandleRecovery will be called.
|
||||
*/
|
||||
virtual void handleChildrenTransition();
|
||||
|
||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode);
|
||||
|
||||
/**
|
||||
* Calls #doStartTransition and triggers an informative event as well that the mode will
|
||||
* change
|
||||
* @param mode
|
||||
* @param submode
|
||||
*/
|
||||
virtual void startTransition(Mode_t mode, Submode_t submode);
|
||||
|
||||
/**
|
||||
* This function starts the transition by setting the internal #targetSubmode and #targetMode
|
||||
* variables and then calling the #commandChildren function.
|
||||
* @param mode
|
||||
* @param submode
|
||||
*/
|
||||
virtual void doStartTransition(Mode_t mode, Submode_t submode);
|
||||
|
||||
virtual bool isInTransition();
|
||||
@ -196,7 +160,7 @@ class AssemblyBase : public SubsystemBase {
|
||||
* Manages recovery of a device
|
||||
* @return true if recovery is still ongoing, false else.
|
||||
*/
|
||||
virtual bool checkAndHandleRecovery();
|
||||
bool checkAndHandleRecovery();
|
||||
|
||||
/**
|
||||
* Helper method to overwrite health state of one of the children.
|
||||
@ -204,8 +168,6 @@ class AssemblyBase : public SubsystemBase {
|
||||
* @param objectId Must be a registered child.
|
||||
*/
|
||||
void overwriteDeviceHealth(object_id_t objectId, HasHealthIF::HealthState oldHealth);
|
||||
|
||||
void triggerModeHelperEvents(Mode_t mode, Submode_t submode);
|
||||
};
|
||||
|
||||
#endif /* FSFW_DEVICEHANDLERS_ASSEMBLYBASE_H_ */
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include "fsfw/ipc/MessageQueueMessage.h"
|
||||
#include "fsfw/ipc/QueueFactory.h"
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw/serialize/SerialBufferAdapter.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||
#include "fsfw/subsystem/SubsystemBase.h"
|
||||
@ -40,9 +39,8 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t device
|
||||
childTransitionDelay(5000),
|
||||
transitionSourceMode(_MODE_POWER_DOWN),
|
||||
transitionSourceSubMode(SUBMODE_NONE) {
|
||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||
cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||
cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE);
|
||||
insertInCommandMap(RAW_COMMAND_ID);
|
||||
cookieInfo.state = COOKIE_UNUSED;
|
||||
cookieInfo.pendingCommand = deviceCommandMap.end();
|
||||
@ -50,6 +48,9 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t device
|
||||
printWarningOrError(sif::OutputTypes::OUT_ERROR, "DeviceHandlerBase", returnvalue::FAILED,
|
||||
"Invalid cookie");
|
||||
}
|
||||
if (this->fdirInstance == nullptr) {
|
||||
this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId, defaultFdirParentId);
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::setHkDestination(object_id_t hkDestination) {
|
||||
@ -127,18 +128,6 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
if (this->fdirInstance == nullptr) {
|
||||
this->fdirInstance =
|
||||
new DeviceHandlerFailureIsolation(this->getObjectId(), defaultFdirParentId);
|
||||
}
|
||||
|
||||
if (this->parent != objects::NO_OBJECT) {
|
||||
HasModesIF* modeIF = ObjectManager::instance()->get<HasModesIF>(this->parent);
|
||||
HasHealthIF* healthIF = ObjectManager::instance()->get<HasHealthIF>(this->parent);
|
||||
if (modeIF != nullptr and healthIF != nullptr) {
|
||||
setParentQueue(modeIF->getCommandQueue());
|
||||
}
|
||||
}
|
||||
|
||||
communicationInterface =
|
||||
ObjectManager::instance()->get<DeviceCommunicationIF>(deviceCommunicationId);
|
||||
@ -374,12 +363,13 @@ void DeviceHandlerBase::doStateMachine() {
|
||||
}
|
||||
} break;
|
||||
case _MODE_WAIT_OFF: {
|
||||
uint32_t currentUptime;
|
||||
Clock::getUptime(¤tUptime);
|
||||
|
||||
if (powerSwitcher == nullptr) {
|
||||
setMode(MODE_OFF);
|
||||
break;
|
||||
}
|
||||
uint32_t currentUptime;
|
||||
Clock::getUptime(¤tUptime);
|
||||
if (currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) {
|
||||
triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT, 0);
|
||||
setMode(MODE_ERROR_ON);
|
||||
@ -580,9 +570,6 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
|
||||
mode = newMode;
|
||||
modeChanged();
|
||||
setNormalDatapoolEntriesInvalid();
|
||||
if (newMode == MODE_OFF) {
|
||||
disableCommandsAndReplies();
|
||||
}
|
||||
if (!isTransitionalMode()) {
|
||||
modeHelper.modeChanged(newMode, newSubmode);
|
||||
announceMode(false);
|
||||
@ -1270,33 +1257,40 @@ ReturnValue_t DeviceHandlerBase::letChildHandleMessage(CommandMessage* message)
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::handleDeviceTm(const uint8_t* rawData, size_t rawDataLen,
|
||||
DeviceCommandId_t replyId, bool forceDirectTm) {
|
||||
SerialBufferAdapter bufferWrapper(rawData, rawDataLen);
|
||||
handleDeviceTm(bufferWrapper, replyId, forceDirectTm);
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::handleDeviceTm(const SerializeIF& dataSet, DeviceCommandId_t replyId,
|
||||
void DeviceHandlerBase::handleDeviceTm(util::DataWrapper dataWrapper, DeviceCommandId_t replyId,
|
||||
bool forceDirectTm) {
|
||||
if (dataWrapper.isNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto iter = deviceReplyMap.find(replyId);
|
||||
if (iter == deviceReplyMap.end()) {
|
||||
triggerEvent(DEVICE_UNKNOWN_REPLY, replyId);
|
||||
return;
|
||||
}
|
||||
|
||||
auto reportData = [&](MessageQueueId_t queueId) {
|
||||
if (dataWrapper.type == util::DataTypes::SERIALIZABLE) {
|
||||
return actionHelper.reportData(queueId, replyId, dataWrapper.dataUnion.serializable);
|
||||
} else if (dataWrapper.type == util::DataTypes::RAW) {
|
||||
return actionHelper.reportData(queueId, replyId, dataWrapper.dataUnion.raw.data,
|
||||
dataWrapper.dataUnion.raw.len);
|
||||
}
|
||||
return returnvalue::FAILED;
|
||||
};
|
||||
|
||||
// Regular replies to a command
|
||||
if (iter->second.command != deviceCommandMap.end()) {
|
||||
MessageQueueId_t queueId = iter->second.command->second.sendReplyTo;
|
||||
|
||||
// This may fail, but we'll ignore the fault.
|
||||
if (queueId != NO_COMMANDER) {
|
||||
// This may fail, but we'll ignore the fault.
|
||||
actionHelper.reportData(queueId, replyId, const_cast<SerializeIF*>(&dataSet));
|
||||
reportData(queueId);
|
||||
}
|
||||
|
||||
// This check should make sure we get any TM but don't get anything doubled.
|
||||
if (wiretappingMode == TM && (requestedRawTraffic != queueId)) {
|
||||
DeviceTmReportingWrapper wrapper(getObjectId(), replyId, dataSet);
|
||||
DeviceTmReportingWrapper wrapper(getObjectId(), replyId, dataWrapper);
|
||||
actionHelper.reportData(requestedRawTraffic, replyId, &wrapper);
|
||||
}
|
||||
|
||||
@ -1305,13 +1299,12 @@ void DeviceHandlerBase::handleDeviceTm(const SerializeIF& dataSet, DeviceCommand
|
||||
// hiding of sender needed so the service will handle it as
|
||||
// unexpected Data, no matter what state (progress or completed)
|
||||
// it is in
|
||||
actionHelper.reportData(defaultRawReceiver, replyId, const_cast<SerializeIF*>(&dataSet),
|
||||
true);
|
||||
reportData(defaultRawReceiver);
|
||||
}
|
||||
}
|
||||
// Unrequested or aperiodic replies
|
||||
else {
|
||||
DeviceTmReportingWrapper wrapper(getObjectId(), replyId, dataSet);
|
||||
DeviceTmReportingWrapper wrapper(getObjectId(), replyId, dataWrapper);
|
||||
if (wiretappingMode == TM) {
|
||||
actionHelper.reportData(requestedRawTraffic, replyId, &wrapper);
|
||||
}
|
||||
@ -1324,23 +1317,22 @@ void DeviceHandlerBase::handleDeviceTm(const SerializeIF& dataSet, DeviceCommand
|
||||
}
|
||||
}
|
||||
|
||||
ActionHelper* DeviceHandlerBase::getActionHelper() { return &actionHelper; }
|
||||
|
||||
ReturnValue_t DeviceHandlerBase::executeAction(Action* action) {
|
||||
ReturnValue_t DeviceHandlerBase::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size) {
|
||||
ReturnValue_t result = acceptExternalDeviceCommands();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
DeviceCommandMap::iterator iter = deviceCommandMap.find(action->getId());
|
||||
DeviceCommandMap::iterator iter = deviceCommandMap.find(actionId);
|
||||
if (iter == deviceCommandMap.end()) {
|
||||
result = COMMAND_NOT_SUPPORTED;
|
||||
} else if (iter->second.isExecuting) {
|
||||
result = COMMAND_ALREADY_SENT;
|
||||
} else {
|
||||
iter->second.sendReplyTo = action->commandedBy;
|
||||
result = action->handle();
|
||||
result = buildCommandFromCommand(actionId, data, size);
|
||||
}
|
||||
if (result == returnvalue::OK) {
|
||||
iter->second.sendReplyTo = commandedBy;
|
||||
iter->second.isExecuting = true;
|
||||
cookieInfo.pendingCommand = iter;
|
||||
cookieInfo.state = COOKIE_WRITE_READY;
|
||||
@ -1468,8 +1460,6 @@ void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* task) { executingTask = task;
|
||||
void DeviceHandlerBase::debugInterface(uint8_t positionTracker, object_id_t objectId,
|
||||
uint32_t parameter) {}
|
||||
|
||||
Submode_t DeviceHandlerBase::getInitialSubmode() { return SUBMODE_NONE; }
|
||||
|
||||
void DeviceHandlerBase::performOperationHook() {}
|
||||
|
||||
ReturnValue_t DeviceHandlerBase::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
@ -1492,7 +1482,7 @@ ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() {
|
||||
this->poolManager.initializeAfterTaskCreation();
|
||||
|
||||
if (setStartupImmediately) {
|
||||
startTransition(MODE_ON, getInitialSubmode());
|
||||
startTransition(MODE_ON, SUBMODE_NONE);
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
@ -1576,36 +1566,3 @@ MessageQueueId_t DeviceHandlerBase::getCommanderQueueId(DeviceCommandId_t replyI
|
||||
}
|
||||
return commandIter->second.sendReplyTo;
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::setCustomFdir(FailureIsolationBase* fdir) { this->fdirInstance = fdir; }
|
||||
|
||||
void DeviceHandlerBase::setParent(object_id_t parent) { this->parent = parent; }
|
||||
|
||||
void DeviceHandlerBase::setPowerSwitcher(PowerSwitchIF* switcher) {
|
||||
this->powerSwitcher = switcher;
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::disableCommandsAndReplies() {
|
||||
for (auto& command : deviceCommandMap) {
|
||||
if (command.second.isExecuting) {
|
||||
command.second.isExecuting = false;
|
||||
}
|
||||
}
|
||||
for (auto& reply : deviceReplyMap) {
|
||||
if (!reply.second.periodic) {
|
||||
if (reply.second.countdown != nullptr) {
|
||||
reply.second.countdown->timeOut();
|
||||
} else {
|
||||
reply.second.delayCycles = 0;
|
||||
}
|
||||
reply.second.active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ModeHelper const* DeviceHandlerBase::getModeHelper() const { return &modeHelper; }
|
||||
|
||||
ModeDefinitionHelper DeviceHandlerBase::getModeDefinitionHelper() {
|
||||
return ModeDefinitionHelper::create<DeviceHandlerMode, DefaultSubmode>();
|
||||
}
|
||||
|
||||
|
@ -103,9 +103,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF *comCookie,
|
||||
FailureIsolationBase *fdirInstance = nullptr, size_t cmdQueueSize = 20);
|
||||
|
||||
void setCustomFdir(FailureIsolationBase *fdir);
|
||||
void setParent(object_id_t parent);
|
||||
void setPowerSwitcher(PowerSwitchIF *switcher);
|
||||
void setHkDestination(object_id_t hkDestination);
|
||||
|
||||
/**
|
||||
@ -204,15 +201,13 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
*/
|
||||
virtual void setParentQueue(MessageQueueId_t parentQueueId);
|
||||
|
||||
/** @brief Implementations required for HasActionIF */
|
||||
ActionHelper* getActionHelper() override;
|
||||
ReturnValue_t executeAction(Action *action) override;
|
||||
/** @brief Implementation required for HasActionIF */
|
||||
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t *data, size_t size) override;
|
||||
|
||||
Mode_t getTransitionSourceMode() const;
|
||||
Submode_t getTransitionSourceSubMode() const;
|
||||
void getMode(Mode_t *mode, Submode_t *submode) override;
|
||||
ModeHelper const * getModeHelper() const override;
|
||||
ModeDefinitionHelper getModeDefinitionHelper() override;
|
||||
virtual void getMode(Mode_t *mode, Submode_t *submode);
|
||||
HealthState getHealth();
|
||||
ReturnValue_t setHealth(HealthState health);
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
@ -316,8 +311,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
* - Anything else triggers an even with the returnvalue as a parameter
|
||||
*/
|
||||
virtual ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t *id) = 0;
|
||||
|
||||
//TODO Remove and update documentation
|
||||
/**
|
||||
* @brief Build a device command packet from data supplied by a direct
|
||||
* command (PUS Service 8)
|
||||
@ -344,7 +337,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
*/
|
||||
virtual ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand,
|
||||
const uint8_t *commandData,
|
||||
size_t commandDataLen) {return returnvalue::FAILED;}
|
||||
size_t commandDataLen) = 0;
|
||||
|
||||
/* Reply handling */
|
||||
/**
|
||||
@ -471,14 +464,14 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
* @brief This is a helper method to insert replies in the reply map.
|
||||
* @param deviceCommand Identifier of the reply to add.
|
||||
* @param maxDelayCycles The maximum number of delay cycles the reply waits
|
||||
* until it times out.
|
||||
* until it times out.
|
||||
* @param periodic Indicates if the command is periodic (i.e. it is sent
|
||||
* by the device repeatedly without request) or not. Default is aperiodic (0).
|
||||
* Please note that periodic replies are disabled by default. You can enable them with
|
||||
* #updatePeriodicReply
|
||||
* by the device repeatedly without request) or not. Default is aperiodic (0).
|
||||
* Please note that periodic replies are disabled by default. You can enable them with
|
||||
* #updatePeriodicReply
|
||||
* @param countdown Instead of using maxDelayCycles to timeout a device reply it is also possible
|
||||
* to provide a pointer to a Countdown object which will signal the timeout
|
||||
* when expired
|
||||
* to provide a pointer to a Countdown object which will signal the timeout
|
||||
* when expired
|
||||
* @return - @c returnvalue::OK when the command was successfully inserted,
|
||||
* - @c returnvalue::FAILED else.
|
||||
*/
|
||||
@ -663,12 +656,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
virtual void debugInterface(uint8_t positionTracker = 0, object_id_t objectId = 0,
|
||||
uint32_t parameter = 0);
|
||||
|
||||
/**
|
||||
* @brief Can be overwritten by a child to specify the initial submode when device has been set
|
||||
* to startup immediately.
|
||||
*/
|
||||
virtual Submode_t getInitialSubmode();
|
||||
|
||||
protected:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_BASE;
|
||||
|
||||
@ -787,18 +774,11 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
* This is used to keep track of pending replies.
|
||||
*/
|
||||
struct DeviceReplyInfo {
|
||||
//! For Command-Reply combinations:
|
||||
//! The maximum number of cycles the handler should wait for a reply
|
||||
//! to this command.
|
||||
//!
|
||||
//! Reply Only:
|
||||
//! For periodic replies, this variable will be the number of delay cycles between the replies.
|
||||
//! For the non-periodic variant, this variable is not used as there is no meaningful
|
||||
//! definition for delay
|
||||
uint16_t maxDelayCycles;
|
||||
//! This variable will be set to #maxDelayCycles if a reply is expected.
|
||||
//! For non-periodic replies without a command, this variable is unused.
|
||||
//! A runtime value of 0 means there is no reply is currently expected.
|
||||
//! The currently remaining cycles the handler should wait for a reply,
|
||||
//! 0 means there is no reply expected
|
||||
uint16_t delayCycles;
|
||||
size_t replyLen = 0; //!< Expected size of the reply.
|
||||
//! if this is !=0, the delayCycles will not be reset to 0 but to
|
||||
@ -854,7 +834,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
/** Pointer to the used FDIR instance. If not provided by child,
|
||||
* default class is instantiated. */
|
||||
FailureIsolationBase *fdirInstance;
|
||||
object_id_t parent = objects::NO_OBJECT;
|
||||
|
||||
//! To correctly delete the default instance.
|
||||
bool defaultFDIRUsed;
|
||||
@ -1074,24 +1053,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
|
||||
bool isAwaitingReply();
|
||||
|
||||
/**
|
||||
* Wrapper function for @handleDeviceTm which wraps the raw buffer with @SerialBufferAdapter.
|
||||
* For interpreted data, prefer the other function.
|
||||
* @param rawData
|
||||
* @param rawDataLen
|
||||
* @param replyId
|
||||
* @param forceDirectTm
|
||||
*/
|
||||
void handleDeviceTm(const uint8_t *rawData, size_t rawDataLen, DeviceCommandId_t replyId,
|
||||
bool forceDirectTm = false);
|
||||
/**
|
||||
* Can be used to handle Service 8 data replies. This will also generate the TM wiretapping
|
||||
* packets accordingly.
|
||||
* @param dataSet
|
||||
* @param replyId
|
||||
* @param forceDirectTm
|
||||
*/
|
||||
void handleDeviceTm(const SerializeIF &dataSet, DeviceCommandId_t replyId,
|
||||
void handleDeviceTm(util::DataWrapper dataWrapper, DeviceCommandId_t replyId,
|
||||
bool forceDirectTm = false);
|
||||
|
||||
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
@ -1345,11 +1307,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
void printWarningOrError(sif::OutputTypes errorType, const char *functionName,
|
||||
ReturnValue_t errorCode = returnvalue::FAILED,
|
||||
const char *errorPrint = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Disables all commands and replies when device is set to MODE_OFF
|
||||
*/
|
||||
void disableCommandsAndReplies();
|
||||
};
|
||||
|
||||
#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */
|
||||
|
@ -29,7 +29,6 @@ ReturnValue_t DeviceHandlerFailureIsolation::eventReceived(EventMessage* event)
|
||||
switch (event->getEvent()) {
|
||||
case HasModesIF::MODE_TRANSITION_FAILED:
|
||||
case HasModesIF::OBJECT_IN_INVALID_MODE:
|
||||
case DeviceHandlerIF::DEVICE_WANTS_HARD_REBOOT:
|
||||
// We'll try a recovery as long as defined in MAX_REBOOT.
|
||||
// Might cause some AssemblyBase cycles, so keep number low.
|
||||
handleRecovery(event->getEvent());
|
||||
|
@ -4,7 +4,6 @@
|
||||
#include "../action/HasActionsIF.h"
|
||||
#include "../datapoollocal/localPoolDefinitions.h"
|
||||
#include "../events/Event.h"
|
||||
#include "../introspection/ClasslessEnum.h"
|
||||
#include "../ipc/MessageQueueSenderIF.h"
|
||||
#include "../modes/HasModesIF.h"
|
||||
#include "DeviceHandlerMessage.h"
|
||||
@ -38,30 +37,23 @@ class DeviceHandlerIF {
|
||||
* The mode of the device itself is transparent to the user but related to the mode of the
|
||||
* handler. MODE_ON and MODE_OFF are included in hasModesIF.h
|
||||
*/
|
||||
FSFW_CLASSLESS_ENUM(
|
||||
DeviceHandlerMode, Mode_t,
|
||||
//! The device is powered and ready to perform operations. In this mode, no
|
||||
//! commands are sent by the device handler itself, but direct commands can be
|
||||
//! commanded and will be executed/forwarded to the device
|
||||
//! This is an alias of MODE_ON to have the FSFW_ENUM complete for introspection
|
||||
((DEVICEHANDLER_MODE_ON, HasModesIF::MODE_ON, "On"))
|
||||
//! The device is powered off. The only command accepted in this
|
||||
//! mode is a mode change to on.
|
||||
//! This is an alias of MODE_OFF to have the FSFW_ENUM complete for introspection
|
||||
((DEVICEHANDLER_MODE_OFF, HasModesIF::MODE_OFF, "Off"))
|
||||
//! The device is powered on and the device handler periodically sends
|
||||
//! commands. The commands to be sent are selected by the handler
|
||||
//! according to the submode.
|
||||
((MODE_NORMAL, 2, "Normal"))
|
||||
//! The device is powered on and ready to perform operations. In this mode,
|
||||
//! raw commands can be sent. The device handler will send all replies
|
||||
//! received from the command back to the commanding object as raw TM
|
||||
((MODE_RAW, 3, "Raw"))
|
||||
//! The device is shut down but the switch could not be turned off, so the
|
||||
//! device still is powered. In this mode, only a mode change to @c MODE_OFF
|
||||
//! can be commanded, which tries to switch off the device again.
|
||||
((MODE_ERROR_ON, 4, "Error")))
|
||||
|
||||
// MODE_ON = 0, //!< The device is powered and ready to perform operations. In this mode, no
|
||||
// commands are sent by the device handler itself, but direct commands van be commanded and will
|
||||
// be interpreted MODE_OFF = 1, //!< The device is powered off. The only command accepted in this
|
||||
// mode is a mode change to on.
|
||||
//! The device is powered on and the device handler periodically sends
|
||||
//! commands. The commands to be sent are selected by the handler
|
||||
//! according to the submode.
|
||||
static const Mode_t MODE_NORMAL = 2;
|
||||
//! The device is powered on and ready to perform operations. In this mode,
|
||||
//! raw commands can be sent. The device handler will send all replies
|
||||
//! received from the command back to the commanding object.
|
||||
static const Mode_t MODE_RAW = 3;
|
||||
//! The device is shut down but the switch could not be turned off, so the
|
||||
//! device still is powered. In this mode, only a mode change to @c MODE_OFF
|
||||
//! can be commanded, which tries to switch off the device again.
|
||||
static const Mode_t MODE_ERROR_ON = 4;
|
||||
//! This is a transitional state which can not be commanded. The device
|
||||
//! handler performs all commands to get the device in a state ready to
|
||||
//! perform commands. When this is completed, the mode changes to @c MODE_ON.
|
||||
@ -117,7 +109,6 @@ class DeviceHandlerIF {
|
||||
static const Event INVALID_DEVICE_COMMAND = MAKE_EVENT(8, severity::LOW);
|
||||
static const Event MONITORING_LIMIT_EXCEEDED = MAKE_EVENT(9, severity::LOW);
|
||||
static const Event MONITORING_AMBIGUOUS = MAKE_EVENT(10, severity::HIGH);
|
||||
static const Event DEVICE_WANTS_HARD_REBOOT = MAKE_EVENT(11, severity::HIGH);
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF;
|
||||
|
||||
|
@ -3,8 +3,8 @@
|
||||
#include "fsfw/serialize/SerializeAdapter.h"
|
||||
|
||||
DeviceTmReportingWrapper::DeviceTmReportingWrapper(object_id_t objectId, ActionId_t actionId,
|
||||
const SerializeIF& data)
|
||||
: objectId(objectId), actionId(actionId), data(data) {}
|
||||
util::DataWrapper data)
|
||||
: objectId(objectId), actionId(actionId), dataWrapper(data) {}
|
||||
|
||||
DeviceTmReportingWrapper::~DeviceTmReportingWrapper() = default;
|
||||
|
||||
@ -19,11 +19,24 @@ ReturnValue_t DeviceTmReportingWrapper::serialize(uint8_t** buffer, size_t* size
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
return data.serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (dataWrapper.isNull()) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
if (dataWrapper.type == util::DataTypes::SERIALIZABLE) {
|
||||
return dataWrapper.dataUnion.serializable->serialize(buffer, size, maxSize, streamEndianness);
|
||||
} else if (dataWrapper.type == util::DataTypes::RAW) {
|
||||
if (*size + dataWrapper.dataUnion.raw.len > maxSize) {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
std::memcpy(*buffer, dataWrapper.dataUnion.raw.data, dataWrapper.dataUnion.raw.len);
|
||||
*buffer += dataWrapper.dataUnion.raw.len;
|
||||
*size += dataWrapper.dataUnion.raw.len;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
size_t DeviceTmReportingWrapper::getSerializedSize() const {
|
||||
return sizeof(objectId) + sizeof(ActionId_t) + data.getSerializedSize();
|
||||
return sizeof(objectId) + sizeof(ActionId_t) + dataWrapper.getLength();
|
||||
}
|
||||
|
||||
ReturnValue_t DeviceTmReportingWrapper::deSerialize(const uint8_t** buffer, size_t* size,
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
class DeviceTmReportingWrapper : public SerializeIF {
|
||||
public:
|
||||
DeviceTmReportingWrapper(object_id_t objectId, ActionId_t actionId, const SerializeIF& data);
|
||||
DeviceTmReportingWrapper(object_id_t objectId, ActionId_t actionId, util::DataWrapper data);
|
||||
~DeviceTmReportingWrapper() override;
|
||||
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
@ -19,7 +19,7 @@ class DeviceTmReportingWrapper : public SerializeIF {
|
||||
private:
|
||||
object_id_t objectId;
|
||||
ActionId_t actionId;
|
||||
const SerializeIF& data;
|
||||
util::DataWrapper dataWrapper;
|
||||
|
||||
// Deserialization forbidden
|
||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
|
@ -8,9 +8,7 @@ HealthDevice::HealthDevice(object_id_t setObjectId, MessageQueueId_t parentQueue
|
||||
parentQueue(parentQueue),
|
||||
commandQueue(),
|
||||
healthHelper(this, setObjectId) {
|
||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||
3, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(3);
|
||||
}
|
||||
|
||||
HealthDevice::~HealthDevice() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "fwSubsystemIdRanges.h"
|
||||
// could be moved to more suitable location
|
||||
#include <events/subsystemIdRanges.h>
|
||||
|
||||
using EventId_t = uint16_t;
|
||||
using EventSeverity_t = uint8_t;
|
||||
|
@ -18,9 +18,8 @@ const LocalPool::LocalPoolConfig EventManager::poolConfig = {
|
||||
EventManager::EventManager(object_id_t setObjectId)
|
||||
: SystemObject(setObjectId), factoryBackend(0, poolConfig, false, true) {
|
||||
mutex = MutexFactory::instance()->createMutex();
|
||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||
eventReportQueue = QueueFactory::instance()->createMessageQueue(
|
||||
MAX_EVENTS_PER_CYCLE, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
|
||||
eventReportQueue = QueueFactory::instance()->createMessageQueue(MAX_EVENTS_PER_CYCLE,
|
||||
EventMessage::EVENT_MESSAGE_SIZE);
|
||||
}
|
||||
|
||||
EventManager::~EventManager() {
|
||||
@ -47,20 +46,9 @@ ReturnValue_t EventManager::performOperation(uint8_t opCode) {
|
||||
|
||||
void EventManager::notifyListeners(EventMessage* message) {
|
||||
lockMutex();
|
||||
for (auto& listener : listenerList) {
|
||||
if (listener.second.match(message)) {
|
||||
ReturnValue_t result =
|
||||
MessageQueueSenderIF::sendMessage(listener.first, message, message->getSender());
|
||||
if (result != returnvalue::OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << std::hex << "EventManager::notifyListeners: MSG to 0x" << std::setfill('0')
|
||||
<< std::setw(8) << listener.first << " failed with result 0x" << std::setw(4)
|
||||
<< result << std::setfill(' ') << std::endl;
|
||||
#else
|
||||
sif::printError("Sending message to listener 0x%08x failed with result %04x\n",
|
||||
listener.first, result);
|
||||
#endif
|
||||
}
|
||||
for (auto iter = listenerList.begin(); iter != listenerList.end(); ++iter) {
|
||||
if (iter->second.match(message)) {
|
||||
MessageQueueSenderIF::sendMessage(iter->first, message, message->getSender());
|
||||
}
|
||||
}
|
||||
unlockMutex();
|
||||
@ -206,19 +194,4 @@ void EventManager::printUtility(sif::OutputTypes printType, EventMessage* messag
|
||||
}
|
||||
}
|
||||
|
||||
void EventManager::printListeners() {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::info << "Event manager listener MQ IDs:" << std::setfill('0') << std::hex << std::endl;
|
||||
for (auto& listener : listenerList) {
|
||||
sif::info << "0x" << std::setw(8) << listener.first << std::endl;
|
||||
}
|
||||
sif::info << std::dec << std::setfill(' ');
|
||||
#else
|
||||
sif::printInfo("Event manager listener MQ IDs:\n");
|
||||
for (auto& listener : listenerList) {
|
||||
sif::printInfo("0x%08x\n", listener.first);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* FSFW_OBJ_EVENT_TRANSLATION == 1 */
|
||||
|
@ -43,7 +43,6 @@ class EventManager : public EventManagerIF, public ExecutableObjectIF, public Sy
|
||||
object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
|
||||
bool reporterInverted = false);
|
||||
ReturnValue_t performOperation(uint8_t opCode);
|
||||
void printListeners();
|
||||
|
||||
protected:
|
||||
MessageQueueIF* eventReportQueue = nullptr;
|
||||
|
@ -9,9 +9,8 @@
|
||||
FailureIsolationBase::FailureIsolationBase(object_id_t owner, object_id_t parent,
|
||||
uint8_t messageDepth, uint8_t parameterDomainBase)
|
||||
: ownerId(owner), faultTreeParent(parent), parameterDomainBase(parameterDomainBase) {
|
||||
auto mqArgs = MqArgs(owner, static_cast<void*>(this));
|
||||
eventQueue = QueueFactory::instance()->createMessageQueue(
|
||||
messageDepth, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
|
||||
eventQueue =
|
||||
QueueFactory::instance()->createMessageQueue(messageDepth, EventMessage::EVENT_MESSAGE_SIZE);
|
||||
}
|
||||
|
||||
FailureIsolationBase::~FailureIsolationBase() {
|
||||
@ -62,12 +61,11 @@ ReturnValue_t FailureIsolationBase::initialize() {
|
||||
ObjectManager::instance()->get<ConfirmsFailuresIF>(faultTreeParent);
|
||||
if (parentIF == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "FailureIsolationBase::intialize: Parent object "
|
||||
<< "invalid" << std::endl;
|
||||
sif::error << "Make sure it implements ConfirmsFailuresIF" << std::endl;
|
||||
#else
|
||||
sif::printError("FailureIsolationBase::intialize: Parent object invalid\n");
|
||||
sif::printError("Make sure it implements ConfirmsFailuresIF\n");
|
||||
sif::error << "FailureIsolationBase::intialize: Parent object"
|
||||
<< "invalid." << std::endl;
|
||||
#endif
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "Make sure it implements ConfirmsFailuresIF." << std::endl;
|
||||
#endif
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
return returnvalue::FAILED;
|
||||
|
@ -12,12 +12,13 @@
|
||||
class FailureIsolationBase : public ConfirmsFailuresIF, public HasParametersIF {
|
||||
public:
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FDIR_1;
|
||||
//! FDIR has an internal state, which changed from par2 (oldState) to par1 (newState).
|
||||
static const Event FDIR_CHANGED_STATE = MAKE_EVENT(1, severity::INFO);
|
||||
//! FDIR tries to restart device. Par1: event that caused recovery.
|
||||
static const Event FDIR_STARTS_RECOVERY = MAKE_EVENT(2, severity::MEDIUM);
|
||||
//! FDIR turns off device. Par1: event that caused recovery.
|
||||
static const Event FDIR_TURNS_OFF_DEVICE = MAKE_EVENT(3, severity::MEDIUM);
|
||||
static const Event FDIR_CHANGED_STATE =
|
||||
MAKE_EVENT(1, severity::INFO); //!< FDIR has an internal state, which changed from par2
|
||||
//!< (oldState) to par1 (newState).
|
||||
static const Event FDIR_STARTS_RECOVERY = MAKE_EVENT(
|
||||
2, severity::MEDIUM); //!< FDIR tries to restart device. Par1: event that caused recovery.
|
||||
static const Event FDIR_TURNS_OFF_DEVICE = MAKE_EVENT(
|
||||
3, severity::MEDIUM); //!< FDIR turns off device. Par1: event that caused recovery.
|
||||
|
||||
FailureIsolationBase(object_id_t owner, object_id_t parent = objects::NO_OBJECT,
|
||||
uint8_t messageDepth = 10, uint8_t parameterDomainBase = 0xF0);
|
||||
|
@ -4,7 +4,6 @@ target_sources(
|
||||
AsciiConverter.cpp
|
||||
CRC.cpp
|
||||
DleEncoder.cpp
|
||||
DleParser.cpp
|
||||
PeriodicOperationDivider.cpp
|
||||
timevalOperations.cpp
|
||||
Type.cpp
|
||||
|
@ -1,230 +0,0 @@
|
||||
#include "DleParser.h"
|
||||
|
||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
DleParser::DleParser(SimpleRingBuffer& decodeRingBuf, DleEncoder& decoder, BufPair encodedBuf,
|
||||
BufPair decodedBuf, UserHandler handler, void* args)
|
||||
: decodeRingBuf(decodeRingBuf),
|
||||
decoder(decoder),
|
||||
encodedBuf(encodedBuf),
|
||||
decodedBuf(decodedBuf),
|
||||
handler(handler),
|
||||
ctx(args) {
|
||||
if (handler == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "DleParser::DleParser: Invalid user handler" << std::endl;
|
||||
#else
|
||||
sif::printError("DleParser::DleParser: Invalid user handler\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t DleParser::passData(uint8_t* data, size_t len) {
|
||||
if (data == nullptr or len == 0 or handler == nullptr) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
size_t copyIntoRingBufFromHere = 0;
|
||||
size_t copyAmount = len;
|
||||
size_t startIdx = 0;
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
bool startFoundInThisPacket = false;
|
||||
for (size_t idx = 0; idx < len; idx++) {
|
||||
if (data[idx] == DleEncoder::STX_CHAR) {
|
||||
if (not startFound and not startFoundInThisPacket) {
|
||||
startIdx = idx;
|
||||
copyIntoRingBufFromHere = idx;
|
||||
copyAmount = len - idx;
|
||||
} else {
|
||||
// Maybe print warning, should not happen
|
||||
decodeRingBuf.clear();
|
||||
ErrorInfo info;
|
||||
info.len = idx;
|
||||
prepareErrorContext(ErrorTypes::CONSECUTIVE_STX_CHARS, info);
|
||||
handler(ctx);
|
||||
copyIntoRingBufFromHere = idx;
|
||||
copyAmount = len - idx;
|
||||
}
|
||||
startFound = true;
|
||||
startFoundInThisPacket = true;
|
||||
} else if (data[idx] == DleEncoder::ETX_CHAR) {
|
||||
if (startFoundInThisPacket) {
|
||||
size_t readLen = 0;
|
||||
size_t decodedLen = 0;
|
||||
result = decoder.decode(data + startIdx, idx + 1 - startIdx, &readLen, decodedBuf.first,
|
||||
decodedBuf.second, &decodedLen);
|
||||
if (result == returnvalue::OK) {
|
||||
ctx.setType(ContextType::PACKET_FOUND);
|
||||
ctx.decodedPacket.first = decodedBuf.first;
|
||||
ctx.decodedPacket.second = decodedLen;
|
||||
this->handler(ctx);
|
||||
} else if (result == DleEncoder::STREAM_TOO_SHORT) {
|
||||
ErrorInfo info;
|
||||
info.res = result;
|
||||
prepareErrorContext(ErrorTypes::DECODING_BUF_TOO_SMALL, info);
|
||||
handler(ctx);
|
||||
} else {
|
||||
ErrorInfo info;
|
||||
info.res = result;
|
||||
prepareErrorContext(ErrorTypes::DECODING_BUF_TOO_SMALL, info);
|
||||
handler(ctx);
|
||||
}
|
||||
decodeRingBuf.clear();
|
||||
if ((idx + 1) < len) {
|
||||
copyIntoRingBufFromHere = idx + 1;
|
||||
copyAmount = len - idx - 1;
|
||||
} else {
|
||||
copyAmount = 0;
|
||||
}
|
||||
} else if (startFound) {
|
||||
// ETX found but STX was found in another mini packet. Reconstruct the full packet
|
||||
// to decode it
|
||||
result = decodeRingBuf.writeData(data, idx + 1);
|
||||
if (result != returnvalue::OK) {
|
||||
ErrorInfo info;
|
||||
info.res = result;
|
||||
prepareErrorContext(ErrorTypes::RING_BUF_ERROR, info);
|
||||
handler(ctx);
|
||||
}
|
||||
size_t fullEncodedLen = decodeRingBuf.getAvailableReadData();
|
||||
if (fullEncodedLen > encodedBuf.second) {
|
||||
ErrorInfo info;
|
||||
info.len = fullEncodedLen;
|
||||
prepareErrorContext(ErrorTypes::ENCODED_BUF_TOO_SMALL, info);
|
||||
handler(ctx);
|
||||
decodeRingBuf.clear();
|
||||
} else {
|
||||
size_t decodedLen = 0;
|
||||
size_t readLen = 0;
|
||||
decodeRingBuf.readData(encodedBuf.first, fullEncodedLen, true);
|
||||
result = decoder.decode(encodedBuf.first, fullEncodedLen, &readLen, decodedBuf.first,
|
||||
decodedBuf.second, &decodedLen);
|
||||
if (result == returnvalue::OK) {
|
||||
if (this->handler != nullptr) {
|
||||
ctx.setType(ContextType::PACKET_FOUND);
|
||||
ctx.decodedPacket.first = decodedBuf.first;
|
||||
ctx.decodedPacket.second = decodedLen;
|
||||
this->handler(ctx);
|
||||
}
|
||||
} else if (result == DleEncoder::STREAM_TOO_SHORT) {
|
||||
ErrorInfo info;
|
||||
info.res = result;
|
||||
prepareErrorContext(ErrorTypes::DECODING_BUF_TOO_SMALL, info);
|
||||
handler(ctx);
|
||||
} else {
|
||||
ErrorInfo info;
|
||||
info.res = result;
|
||||
prepareErrorContext(ErrorTypes::DECODE_ERROR, info);
|
||||
handler(ctx);
|
||||
}
|
||||
decodeRingBuf.clear();
|
||||
startFound = false;
|
||||
startFoundInThisPacket = false;
|
||||
if ((idx + 1) < len) {
|
||||
copyIntoRingBufFromHere = idx + 1;
|
||||
copyAmount = len - idx - 1;
|
||||
} else {
|
||||
copyAmount = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// End data without preceeding STX
|
||||
ErrorInfo info;
|
||||
info.len = idx + 1;
|
||||
prepareErrorContext(ErrorTypes::CONSECUTIVE_ETX_CHARS, info);
|
||||
handler(ctx);
|
||||
decodeRingBuf.clear();
|
||||
if ((idx + 1) < len) {
|
||||
copyIntoRingBufFromHere = idx + 1;
|
||||
copyAmount = len - idx - 1;
|
||||
} else {
|
||||
copyAmount = 0;
|
||||
}
|
||||
}
|
||||
startFoundInThisPacket = false;
|
||||
startFound = false;
|
||||
}
|
||||
}
|
||||
if (copyAmount > 0) {
|
||||
result = decodeRingBuf.writeData(data + copyIntoRingBufFromHere, copyAmount);
|
||||
if (result != returnvalue::OK) {
|
||||
ErrorInfo info;
|
||||
info.res = result;
|
||||
prepareErrorContext(ErrorTypes::RING_BUF_ERROR, info);
|
||||
handler(ctx);
|
||||
}
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
void DleParser::defaultFoundPacketHandler(uint8_t* packet, size_t len, void* args) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::info << "DleParserBase::handleFoundPacket: Detected DLE packet with " << len << " bytes"
|
||||
<< std::endl;
|
||||
#else
|
||||
sif::printInfo("DleParserBase::handleFoundPacket: Detected DLE packet with %d bytes\n", len);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void DleParser::defaultErrorHandler(ErrorTypes err, ErrorInfo ctx) {
|
||||
switch (err) {
|
||||
case (ErrorTypes::NONE): {
|
||||
errorPrinter("No error");
|
||||
break;
|
||||
}
|
||||
case (ErrorTypes::DECODE_ERROR): {
|
||||
errorPrinter("Decode Error");
|
||||
break;
|
||||
}
|
||||
case (ErrorTypes::RING_BUF_ERROR): {
|
||||
errorPrinter("Ring Buffer Error");
|
||||
break;
|
||||
}
|
||||
case (ErrorTypes::ENCODED_BUF_TOO_SMALL):
|
||||
case (ErrorTypes::DECODING_BUF_TOO_SMALL): {
|
||||
char opt[64];
|
||||
snprintf(opt, sizeof(opt), ": Too small for packet with length %zu", ctx.len);
|
||||
if (err == ErrorTypes::ENCODED_BUF_TOO_SMALL) {
|
||||
errorPrinter("Encoded buf too small", opt);
|
||||
} else {
|
||||
errorPrinter("Decoding buf too small", opt);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (ErrorTypes::CONSECUTIVE_STX_CHARS): {
|
||||
errorPrinter("Consecutive STX chars detected");
|
||||
break;
|
||||
}
|
||||
case (ErrorTypes::CONSECUTIVE_ETX_CHARS): {
|
||||
errorPrinter("Consecutive ETX chars detected");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DleParser::errorPrinter(const char* str, const char* opt) {
|
||||
if (opt == nullptr) {
|
||||
opt = "";
|
||||
}
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::info << "DleParserBase::handleParseError: " << str << opt << std::endl;
|
||||
#else
|
||||
sif::printInfo("DleParserBase::handleParseError: %s%s\n", str, opt);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void DleParser::prepareErrorContext(ErrorTypes err, ErrorInfo info) {
|
||||
ctx.setType(ContextType::ERROR);
|
||||
ctx.error.first = err;
|
||||
ctx.error.second = info;
|
||||
}
|
||||
|
||||
void DleParser::reset() {
|
||||
startFound = false;
|
||||
decodeRingBuf.clear();
|
||||
}
|
@ -1,124 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <fsfw/container/SimpleRingBuffer.h>
|
||||
#include <fsfw/globalfunctions/DleEncoder.h>
|
||||
#include <fsfw/returnvalues/returnvalue.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
/**
|
||||
* @brief This base helper class can be used to extract DLE encoded packets from a data stream
|
||||
* @details
|
||||
* The core API of the parser takes received packets which can contains DLE packets. The parser
|
||||
* can deal with DLE packets split across multiple packets. It does so by using a dedicated
|
||||
* decoding ring buffer. The user can process received packets and detect errors by
|
||||
* overriding two provided virtual methods. This also allows detecting multiple DLE packets
|
||||
* inside one passed packet.
|
||||
*/
|
||||
class DleParser {
|
||||
public:
|
||||
using BufPair = std::pair<uint8_t*, size_t>;
|
||||
|
||||
enum class ContextType { PACKET_FOUND, ERROR };
|
||||
|
||||
enum class ErrorTypes {
|
||||
NONE,
|
||||
ENCODED_BUF_TOO_SMALL,
|
||||
DECODING_BUF_TOO_SMALL,
|
||||
DECODE_ERROR,
|
||||
RING_BUF_ERROR,
|
||||
CONSECUTIVE_STX_CHARS,
|
||||
CONSECUTIVE_ETX_CHARS
|
||||
};
|
||||
|
||||
union ErrorInfo {
|
||||
size_t len;
|
||||
ReturnValue_t res;
|
||||
};
|
||||
|
||||
using ErrorPair = std::pair<ErrorTypes, ErrorInfo>;
|
||||
|
||||
struct Context {
|
||||
public:
|
||||
Context(void* args) : userArgs(args) { setType(ContextType::PACKET_FOUND); }
|
||||
|
||||
void setType(ContextType type) {
|
||||
if (type == ContextType::PACKET_FOUND) {
|
||||
error.first = ErrorTypes::NONE;
|
||||
error.second.len = 0;
|
||||
} else {
|
||||
decodedPacket.first = nullptr;
|
||||
decodedPacket.second = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ContextType getType() const { return type; }
|
||||
|
||||
BufPair decodedPacket = {};
|
||||
ErrorPair error;
|
||||
void* userArgs;
|
||||
|
||||
private:
|
||||
ContextType type;
|
||||
};
|
||||
|
||||
using UserHandler = void (*)(const Context& ctx);
|
||||
|
||||
/**
|
||||
* Base class constructor
|
||||
* @param decodeRingBuf Ring buffer used to store multiple packets to allow detecting DLE packets
|
||||
* split across multiple packets
|
||||
* @param decoder Decoder instance
|
||||
* @param encodedBuf Buffer used to store encoded packets. It has to be large enough to hold
|
||||
* the largest expected encoded DLE packet size
|
||||
* @param decodedBuf Buffer used to store decoded packets. It has to be large enough to hold the
|
||||
* largest expected decoded DLE packet size
|
||||
* @param handler Function which will be called on a found packet
|
||||
* @param args Arbitrary user argument
|
||||
*/
|
||||
DleParser(SimpleRingBuffer& decodeRingBuf, DleEncoder& decoder, BufPair encodedBuf,
|
||||
BufPair decodedBuf, UserHandler handler, void* args);
|
||||
|
||||
/**
|
||||
* This function allows to pass new data into the parser. It then scans for DLE packets
|
||||
* automatically and inserts (part of) the packet into a ring buffer if necessary.
|
||||
* @param data
|
||||
* @param len
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t passData(uint8_t* data, size_t len);
|
||||
|
||||
/**
|
||||
* Example found packet handler
|
||||
* function call
|
||||
* @param packet Decoded packet
|
||||
* @param len Length of detected packet
|
||||
*/
|
||||
void defaultFoundPacketHandler(uint8_t* packet, size_t len, void* args);
|
||||
/**
|
||||
* Will be called if an error occured in the #passData call
|
||||
* @param err
|
||||
* @param ctx Context information depending on the error type
|
||||
* - For buffer length errors, will be set to the detected packet length which is too large
|
||||
* - For decode or ring buffer errors, will be set to the result returned from the failed call
|
||||
*/
|
||||
static void defaultErrorHandler(ErrorTypes err, ErrorInfo ctx);
|
||||
|
||||
static void errorPrinter(const char* str, const char* opt = nullptr);
|
||||
|
||||
void prepareErrorContext(ErrorTypes err, ErrorInfo ctx);
|
||||
/**
|
||||
* Resets the parser by resetting the internal states and clearing the decoding ring buffer
|
||||
*/
|
||||
void reset();
|
||||
|
||||
private:
|
||||
SimpleRingBuffer& decodeRingBuf;
|
||||
DleEncoder& decoder;
|
||||
BufPair encodedBuf;
|
||||
BufPair decodedBuf;
|
||||
UserHandler handler = nullptr;
|
||||
Context ctx;
|
||||
bool startFound = false;
|
||||
};
|
@ -16,24 +16,26 @@ class HasHealthIF {
|
||||
};
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::HAS_HEALTH_IF;
|
||||
static constexpr ReturnValue_t OBJECT_NOT_HEALTHY = returnvalue::makeCode(INTERFACE_ID, 1);
|
||||
static constexpr ReturnValue_t INVALID_HEALTH_STATE = returnvalue::makeCode(INTERFACE_ID, 2);
|
||||
static constexpr ReturnValue_t IS_EXTERNALLY_CONTROLLED = returnvalue::makeCode(INTERFACE_ID, 3);
|
||||
static const ReturnValue_t OBJECT_NOT_HEALTHY = MAKE_RETURN_CODE(1);
|
||||
static const ReturnValue_t INVALID_HEALTH_STATE = MAKE_RETURN_CODE(2);
|
||||
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER_1;
|
||||
//! P1: New Health, P2: Old Health
|
||||
static const Event HEALTH_INFO = MAKE_EVENT(6, severity::INFO);
|
||||
static const Event CHILD_CHANGED_HEALTH = MAKE_EVENT(7, severity::INFO);
|
||||
static const Event CHILD_PROBLEMS = MAKE_EVENT(8, severity::LOW);
|
||||
//! Assembly overwrites health information of children to keep satellite alive.
|
||||
static const Event OVERWRITING_HEALTH = MAKE_EVENT(9, severity::LOW);
|
||||
//! Someone starts a recovery of a component (typically power-cycle). No parameters.
|
||||
static const Event TRYING_RECOVERY = MAKE_EVENT(10, severity::MEDIUM);
|
||||
//! Recovery is ongoing. Comes twice during recovery.
|
||||
//! P1: 0 for the first, 1 for the second event. P2: 0
|
||||
static const Event RECOVERY_STEP = MAKE_EVENT(11, severity::MEDIUM);
|
||||
//! Recovery was completed. Not necessarily successful. No parameters.
|
||||
static const Event RECOVERY_DONE = MAKE_EVENT(12, severity::MEDIUM);
|
||||
static const Event OVERWRITING_HEALTH =
|
||||
MAKE_EVENT(9, severity::LOW); //!< Assembly overwrites health information of children to keep
|
||||
//!< satellite alive.
|
||||
static const Event TRYING_RECOVERY =
|
||||
MAKE_EVENT(10, severity::MEDIUM); //!< Someone starts a recovery of a component (typically
|
||||
//!< power-cycle). No parameters.
|
||||
static const Event RECOVERY_STEP =
|
||||
MAKE_EVENT(11, severity::MEDIUM); //!< Recovery is ongoing. Comes twice during recovery. P1:
|
||||
//!< 0 for the first, 1 for the second event. P2: 0
|
||||
static const Event RECOVERY_DONE = MAKE_EVENT(
|
||||
12,
|
||||
severity::MEDIUM); //!< Recovery was completed. Not necessarily successful. No parameters.
|
||||
|
||||
virtual ~HasHealthIF() {}
|
||||
|
||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||
|
@ -9,8 +9,8 @@
|
||||
|
||||
class HealthTable : public HealthTableIF, public SystemObject {
|
||||
public:
|
||||
explicit HealthTable(object_id_t objectid);
|
||||
~HealthTable() override;
|
||||
HealthTable(object_id_t objectid);
|
||||
virtual ~HealthTable();
|
||||
|
||||
void setMutexTimeout(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs);
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
#ifndef FRAMEWORK_HOUSEKEEPING_ACCEPTSHKPACKETSIF_H_
|
||||
#define FRAMEWORK_HOUSEKEEPING_ACCEPTSHKPACKETSIF_H_
|
||||
|
||||
#include "fsfw/ipc/MessageQueueMessageIF.h"
|
||||
#include "../ipc/MessageQueueMessageIF.h"
|
||||
|
||||
class AcceptsHkPacketsIF {
|
||||
public:
|
||||
virtual ~AcceptsHkPacketsIF() = default;
|
||||
[[nodiscard]] virtual MessageQueueId_t getHkQueue() const = 0;
|
||||
virtual ~AcceptsHkPacketsIF(){};
|
||||
virtual MessageQueueId_t getHkQueue() const = 0;
|
||||
};
|
||||
|
||||
#endif /* FRAMEWORK_HOUSEKEEPING_ACCEPTSHKPACKETSIF_H_ */
|
||||
|
@ -7,13 +7,11 @@
|
||||
|
||||
InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth)
|
||||
: SystemObject(setObjectId),
|
||||
commandQueue(QueueFactory::instance()->createMessageQueue(messageQueueDepth)),
|
||||
poolManager(this, commandQueue),
|
||||
internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
|
||||
internalErrorDataset(this) {
|
||||
mutex = MutexFactory::instance()->createMutex();
|
||||
auto mqArgs = MqArgs(setObjectId, static_cast<void *>(this));
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||
messageQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||
}
|
||||
|
||||
InternalErrorReporter::~InternalErrorReporter() { MutexFactory::instance()->deleteMutex(mutex); }
|
||||
@ -38,14 +36,15 @@ ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) {
|
||||
if ((newQueueHits > 0) or (newTmHits > 0) or (newStoreHits > 0)) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "InternalErrorReporter::performOperation: Errors "
|
||||
<< "occured: Queue | TM | Store : " << newQueueHits << " | " << newTmHits << " | "
|
||||
<< newStoreHits << std::endl;
|
||||
<< "occured!" << std::endl;
|
||||
sif::debug << "Queue errors: " << newQueueHits << std::endl;
|
||||
sif::debug << "TM errors: " << newTmHits << std::endl;
|
||||
sif::debug << "Store errors: " << newStoreHits << std::endl;
|
||||
#else
|
||||
sif::printDebug(
|
||||
"InternalErrorReporter::performOperation: Errors occured: Queue | TM | Store: %lu | %lu "
|
||||
"| %lu\n",
|
||||
static_cast<unsigned int>(newQueueHits), static_cast<unsigned int>(newTmHits),
|
||||
static_cast<unsigned int>(newStoreHits));
|
||||
sif::printDebug("InternalErrorReporter::performOperation: Errors occured!\n");
|
||||
sif::printDebug("Queue errors: %lu\n", static_cast<unsigned int>(newQueueHits));
|
||||
sif::printDebug("TM errors: %lu\n", static_cast<unsigned int>(newTmHits));
|
||||
sif::printDebug("Store errors: %lu\n", static_cast<unsigned int>(newStoreHits));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -127,12 +126,11 @@ MessageQueueId_t InternalErrorReporter::getCommandQueue() const {
|
||||
|
||||
ReturnValue_t InternalErrorReporter::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||
LocalDataPoolManager &poolManager) {
|
||||
localDataPoolMap.emplace(errorPoolIds::TM_HITS, &tmHitsEntry);
|
||||
localDataPoolMap.emplace(errorPoolIds::QUEUE_HITS, &queueHitsEntry);
|
||||
localDataPoolMap.emplace(errorPoolIds::STORE_HITS, &storeHitsEntry);
|
||||
poolManager.subscribeForDiagPeriodicPacket(subdp::DiagnosticsHkPeriodicParams(
|
||||
internalErrorSid, false,
|
||||
static_cast<float>(getPeriodicOperationFrequency()) / static_cast<float>(1000.0)));
|
||||
localDataPoolMap.emplace(errorPoolIds::TM_HITS, new PoolEntry<uint32_t>());
|
||||
localDataPoolMap.emplace(errorPoolIds::QUEUE_HITS, new PoolEntry<uint32_t>());
|
||||
localDataPoolMap.emplace(errorPoolIds::STORE_HITS, new PoolEntry<uint32_t>());
|
||||
poolManager.subscribeForPeriodicPacket(internalErrorSid, false, getPeriodicOperationFrequency(),
|
||||
true);
|
||||
internalErrorDataset.setValidity(true, true);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
@ -72,9 +72,6 @@ class InternalErrorReporter : public SystemObject,
|
||||
uint32_t queueHits = 0;
|
||||
uint32_t tmHits = 0;
|
||||
uint32_t storeHits = 0;
|
||||
PoolEntry<uint32_t> tmHitsEntry = PoolEntry<uint32_t>();
|
||||
PoolEntry<uint32_t> storeHitsEntry = PoolEntry<uint32_t>();
|
||||
PoolEntry<uint32_t> queueHitsEntry = PoolEntry<uint32_t>();
|
||||
|
||||
uint32_t getAndResetQueueHits();
|
||||
void incrementQueueHits();
|
||||
|
@ -12,7 +12,7 @@
|
||||
*/
|
||||
class InternalErrorReporterIF {
|
||||
public:
|
||||
virtual ~InternalErrorReporterIF() = default;
|
||||
virtual ~InternalErrorReporterIF() {}
|
||||
/**
|
||||
* @brief Function to be called if a message queue could not be sent.
|
||||
* @details OSAL Implementations should call this function to indicate that
|
||||
|
@ -1 +0,0 @@
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE ParameterTypeSelector.cpp)
|
@ -1,48 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <fsfw/returnvalues/returnvalue.h>
|
||||
|
||||
#include <boost/preprocessor.hpp>
|
||||
|
||||
// TODO ifdef EnumIF, consistent naming of functions arrays and macros (probably enum values and
|
||||
// descriptions)
|
||||
|
||||
#include "EnumIF.h"
|
||||
#include "EnumCommon.h"
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
|
||||
#define FSFW_CLASSLESS_ENUM(name, type, elements) \
|
||||
enum : type { BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH(CLEAN_ENUM_ITEM, "", elements)) }; \
|
||||
\
|
||||
class name : public EnumIF { \
|
||||
public: \
|
||||
enum : type { BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH(CLEAN_ENUM_ITEM, "", elements)) }; \
|
||||
name(type value) : value(value) {} \
|
||||
name() : value(-1) {} \
|
||||
name(const name &other) : value(other.value) {} \
|
||||
int64_t getValue() const override { return value; } \
|
||||
operator type() { return value; } \
|
||||
name &operator=(name other) { \
|
||||
value = other.value; \
|
||||
return *this; \
|
||||
} \
|
||||
name &operator=(type value) { \
|
||||
this->value = value; \
|
||||
return *this; \
|
||||
} \
|
||||
CREATE_KEY_ARRAY(elements, type) \
|
||||
VALUE_CHECK(type) \
|
||||
GET_INDEX() \
|
||||
CREATE_DESCRIPTION_ARRAY(elements) \
|
||||
GET_DESCRIPTION_FUNC() \
|
||||
private: \
|
||||
type value; \
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#define FSFW_CLASSLESS_ENUM(name, type, elements) \
|
||||
enum name : type { BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH(CLEAN_ENUM_ITEM, "", elements)) };
|
||||
|
||||
#endif
|
@ -1,64 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <fsfw/returnvalues/returnvalue.h>
|
||||
#include <fsfw/serialize/SerializeAdapter.h>
|
||||
|
||||
#include <boost/preprocessor.hpp>
|
||||
|
||||
// TODO ifdef EnumIF, consistent naming of functions arrays and macros (probably enum values and
|
||||
// descriptions)
|
||||
|
||||
#include "EnumIF.h"
|
||||
#include "EnumCommon.h"
|
||||
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
|
||||
#define FSFW_ENUM(name, type, elements) \
|
||||
class name : public EnumIF, public SerializeIF { \
|
||||
public: \
|
||||
enum : type { BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH(CLEAN_ENUM_ITEM, "", elements)) }; \
|
||||
name(type value) : value(value) {} \
|
||||
name() : value(-1) {} \
|
||||
name(const name &other) : value(other.value) {} \
|
||||
int64_t getValue() const override { return value; } \
|
||||
operator type() { return value; } \
|
||||
name &operator=(name other) { \
|
||||
value = other.value; \
|
||||
return *this; \
|
||||
} \
|
||||
name &operator=(type value) { \
|
||||
this->value = value; \
|
||||
return *this; \
|
||||
} \
|
||||
CREATE_KEY_ARRAY(elements, type) \
|
||||
VALUE_CHECK(type) \
|
||||
GET_INDEX() \
|
||||
CREATE_DESCRIPTION_ARRAY(elements) \
|
||||
GET_DESCRIPTION_FUNC() \
|
||||
virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize, \
|
||||
Endianness streamEndianness) const override { \
|
||||
return SerializeAdapter::serialize<>(&value, buffer, size, maxSize, streamEndianness); \
|
||||
} \
|
||||
virtual size_t getSerializedSize() const override { \
|
||||
return SerializeAdapter::getSerializedSize<>(&value); \
|
||||
} \
|
||||
virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, \
|
||||
Endianness streamEndianness) override { \
|
||||
return SerializeAdapter::deSerialize<>(&value, buffer, size, streamEndianness); \
|
||||
} \
|
||||
\
|
||||
private: \
|
||||
type value; \
|
||||
};
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#define FSFW_ENUM(name, type, elements) \
|
||||
enum class name : type { \
|
||||
BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH(CLEAN_ENUM_ITEM, "", elements)) \
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@ -1,62 +0,0 @@
|
||||
#define CLEAN_ENUM_ITEM(r, data, element) \
|
||||
BOOST_PP_IF(BOOST_PP_SUB(BOOST_PP_TUPLE_SIZE(element), 2), \
|
||||
(BOOST_PP_TUPLE_ELEM(0, element) = BOOST_PP_TUPLE_ELEM(1, element)), \
|
||||
(BOOST_PP_TUPLE_ELEM(0, element)))
|
||||
|
||||
#if defined FSFW_ENUM_VALUE_CHECKS || defined FSFW_INTROSPECTION
|
||||
|
||||
|
||||
#define GET_KEY(r, data, element) (BOOST_PP_TUPLE_ELEM(0, element))
|
||||
#define GET_DESCRIPTION(r, data, element) \
|
||||
BOOST_PP_IF(BOOST_PP_SUB(BOOST_PP_TUPLE_SIZE(element), 2), (BOOST_PP_TUPLE_ELEM(2, element)), \
|
||||
(BOOST_PP_TUPLE_ELEM(1, element)))
|
||||
|
||||
#define CREATE_KEY_ARRAY(enum_elements, type) \
|
||||
/*was static constexpr, but clang won't compile that*/ \
|
||||
int64_t elements[BOOST_PP_SEQ_SIZE(BOOST_PP_SEQ_FOR_EACH(GET_KEY, "", enum_elements))] = { \
|
||||
BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH(GET_KEY, "", enum_elements))}; \
|
||||
const int64_t *getElements() const override { return elements; } \
|
||||
size_t getSize() const override { \
|
||||
return BOOST_PP_SEQ_SIZE(BOOST_PP_SEQ_FOR_EACH(GET_KEY, "", enum_elements)); \
|
||||
}
|
||||
#define VALUE_CHECK(type) \
|
||||
bool isValid() const override { \
|
||||
for (size_t i = 0; i < sizeof(elements) / sizeof(elements[0]); i++) { \
|
||||
if (value == elements[i]) { \
|
||||
return true; \
|
||||
} \
|
||||
} \
|
||||
return false; \
|
||||
}
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
#define CREATE_DESCRIPTION_ARRAY(elements) \
|
||||
/*was static constexpr, but clang won't compile that*/ \
|
||||
const char \
|
||||
*descriptions[BOOST_PP_SEQ_SIZE(BOOST_PP_SEQ_FOR_EACH(GET_DESCRIPTION, "", elements))] = { \
|
||||
BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH(GET_DESCRIPTION, "", elements))}; \
|
||||
const char *const *getDescriptions() const override { return descriptions; }
|
||||
#define GET_INDEX() \
|
||||
size_t getIndex(int64_t value) const override { \
|
||||
for (size_t i = 0; i < sizeof(elements) / sizeof(elements[0]); i++) { \
|
||||
if (value == elements[i]) { \
|
||||
return i; \
|
||||
} \
|
||||
} \
|
||||
return -1; \
|
||||
}
|
||||
#define GET_DESCRIPTION_FUNC() \
|
||||
const char *getDescription() const override { \
|
||||
if (getIndex(value) == static_cast<size_t>(-1)) { \
|
||||
return nullptr; \
|
||||
} else { \
|
||||
return descriptions[getIndex(value)]; \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
#define GET_INDEX()
|
||||
#define CREATE_DESCRIPTION_ARRAY(elements)
|
||||
#define GET_DESCRIPTION_FUNC()
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
class EnumIF {
|
||||
public:
|
||||
virtual ~EnumIF() {}
|
||||
virtual int64_t getValue() const = 0;
|
||||
virtual bool isValid() const = 0;
|
||||
virtual size_t getSize() const = 0;
|
||||
virtual size_t getIndex(int64_t value) const = 0;
|
||||
virtual const int64_t *getElements() const = 0;
|
||||
virtual const char *const *getDescriptions() const = 0;
|
||||
virtual const char *getDescription() const = 0;
|
||||
};
|
@ -1,56 +0,0 @@
|
||||
#include "ParameterTypeSelector.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
|
||||
template <typename T>
|
||||
Types::ParameterType ParameterTypeSelector::getType() {
|
||||
return Types::UNSUPPORTED;
|
||||
}
|
||||
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<uint8_t>() {
|
||||
return Types::SIGNED;
|
||||
}
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<int8_t>() {
|
||||
return Types::SIGNED;
|
||||
}
|
||||
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<uint16_t>() {
|
||||
return Types::SIGNED;
|
||||
}
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<int16_t>() {
|
||||
return Types::SIGNED;
|
||||
}
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<uint32_t>() {
|
||||
return Types::SIGNED;
|
||||
}
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<int32_t>() {
|
||||
return Types::SIGNED;
|
||||
}
|
||||
// template <>
|
||||
// Types::ParameterType ParameterTypeSelector::getType<uint64_t>() {
|
||||
// return Types::UNSIGNED;
|
||||
// }
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<int64_t>() {
|
||||
return Types::SIGNED;
|
||||
}
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<float>() {
|
||||
return Types::FLOATING;
|
||||
}
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<double>() {
|
||||
return Types::FLOATING;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,13 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
|
||||
class ParameterTypeSelector {
|
||||
public:
|
||||
template <typename T>
|
||||
static Types::ParameterType getType();
|
||||
};
|
||||
|
||||
#endif
|
@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
//maybe call them MIB types as these are the ones exposed to the MIB?
|
||||
// Note: some DBs (Postgress, Mongo) only support signed 64bit integers. To have a common denominator, all integers are int64_t.
|
||||
// As such, ther is no unsigned Type, as there can not be a uint64_t and uint32_t completely fits into int64_t
|
||||
namespace Types {
|
||||
enum ParameterType { SIGNED, FLOATING, ENUM, STRING, BYTEARRAY, UNSUPPORTED };
|
||||
} // namespace Types
|
@ -1,74 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
#include "Enum.h"
|
||||
#include "Types.h"
|
||||
#include "ParameterTypeSelector.h"
|
||||
|
||||
template <bool>
|
||||
class enumHelper;
|
||||
|
||||
template <>
|
||||
class enumHelper<true> {
|
||||
public:
|
||||
static bool isValid(EnumIF *anEnum) { return anEnum->isValid(); }
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
template <typename T>
|
||||
static Types::ParameterType getType() {
|
||||
return Types::ENUM;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static T getMin() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static T getMax() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static std::vector<int64_t> getEnumValues() { return std::vector<int64_t>(); }
|
||||
|
||||
static std::vector<int64_t> getEnumValues(EnumIF *anEnum) {
|
||||
std::vector<int64_t> vector;
|
||||
for (size_t i = 0; i < anEnum->getSize(); i++) {
|
||||
vector.push_back(anEnum->getElements()[i]);
|
||||
}
|
||||
return vector;
|
||||
}
|
||||
|
||||
static const char *const *getEnumDescriptions(EnumIF *anEnum) {
|
||||
return anEnum->getDescriptions();
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <>
|
||||
class enumHelper<false> {
|
||||
public:
|
||||
static bool isValid(void *) { return true; }
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
template <typename T>
|
||||
static Types::ParameterType getType() {
|
||||
return ParameterTypeSelector::getType<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static T getMin() {
|
||||
return std::numeric_limits<T>::lowest();
|
||||
}
|
||||
template <typename T>
|
||||
static T getMax() {
|
||||
return std::numeric_limits<T>::max();
|
||||
}
|
||||
|
||||
static std::vector<int64_t> getEnumValues(void *) { return std::vector<int64_t>(); }
|
||||
|
||||
static const char *const *getEnumDescriptions(void *) { return nullptr; }
|
||||
#endif
|
||||
};
|
@ -34,7 +34,7 @@ class CommandMessageIF {
|
||||
static const Command_t CMD_NONE = MAKE_COMMAND_ID(0);
|
||||
static const Command_t REPLY_COMMAND_OK = MAKE_COMMAND_ID(1);
|
||||
//! Reply indicating that the current command was rejected,
|
||||
//! Parameter 1 should contain the error code
|
||||
//! par1 should contain the error code
|
||||
static const Command_t REPLY_REJECTED = MAKE_COMMAND_ID(2);
|
||||
|
||||
virtual ~CommandMessageIF(){};
|
||||
|
@ -8,7 +8,7 @@ MessageQueueBase::MessageQueueBase(MessageQueueId_t id, MessageQueueId_t default
|
||||
}
|
||||
}
|
||||
|
||||
MessageQueueBase::~MessageQueueBase() = default;
|
||||
MessageQueueBase::~MessageQueueBase() {}
|
||||
|
||||
ReturnValue_t MessageQueueBase::sendToDefault(MessageQueueMessageIF* message) {
|
||||
return sendToDefaultFrom(message, this->getId(), false);
|
||||
|
@ -7,28 +7,28 @@
|
||||
class MessageQueueBase : public MessageQueueIF {
|
||||
public:
|
||||
MessageQueueBase(MessageQueueId_t id, MessageQueueId_t defaultDest, MqArgs* mqArgs);
|
||||
~MessageQueueBase() override;
|
||||
virtual ~MessageQueueBase();
|
||||
|
||||
// Default implementations for MessageQueueIF where possible
|
||||
[[nodiscard]] MessageQueueId_t getLastPartner() const override;
|
||||
[[nodiscard]] MessageQueueId_t getId() const override;
|
||||
MqArgs& getMqArgs() override;
|
||||
void setDefaultDestination(MessageQueueId_t defaultDestination) override;
|
||||
[[nodiscard]] MessageQueueId_t getDefaultDestination() const override;
|
||||
[[nodiscard]] bool isDefaultDestinationSet() const override;
|
||||
ReturnValue_t sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||
bool ignoreFault) override;
|
||||
ReturnValue_t sendToDefault(MessageQueueMessageIF* message) override;
|
||||
ReturnValue_t reply(MessageQueueMessageIF* message) override;
|
||||
ReturnValue_t receiveMessage(MessageQueueMessageIF* message,
|
||||
MessageQueueId_t* receivedFrom) override;
|
||||
ReturnValue_t sendToDefaultFrom(MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
|
||||
bool ignoreFault = false) override;
|
||||
virtual MessageQueueId_t getLastPartner() const override;
|
||||
virtual MessageQueueId_t getId() const override;
|
||||
virtual MqArgs& getMqArgs() override;
|
||||
virtual void setDefaultDestination(MessageQueueId_t defaultDestination) override;
|
||||
virtual MessageQueueId_t getDefaultDestination() const override;
|
||||
virtual bool isDefaultDestinationSet() const override;
|
||||
virtual ReturnValue_t sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||
bool ignoreFault) override;
|
||||
virtual ReturnValue_t sendToDefault(MessageQueueMessageIF* message) override;
|
||||
virtual ReturnValue_t reply(MessageQueueMessageIF* message) override;
|
||||
virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message,
|
||||
MessageQueueId_t* receivedFrom) override;
|
||||
virtual ReturnValue_t sendToDefaultFrom(MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
|
||||
bool ignoreFault = false) override;
|
||||
|
||||
// OSAL specific, forward the abstract function
|
||||
ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override = 0;
|
||||
ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||
MessageQueueId_t sentFrom, bool ignoreFault = false) override = 0;
|
||||
virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message) = 0;
|
||||
virtual ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||
MessageQueueId_t sentFrom, bool ignoreFault = false) = 0;
|
||||
|
||||
protected:
|
||||
MessageQueueId_t id = MessageQueueIF::NO_QUEUE;
|
||||
|
@ -30,7 +30,7 @@ class MessageQueueIF {
|
||||
//! [EXPORT] : [COMMENT] Returned if the target destination is invalid.
|
||||
static constexpr ReturnValue_t DESTINATION_INVALID = MAKE_RETURN_CODE(4);
|
||||
|
||||
virtual ~MessageQueueIF() = default;
|
||||
virtual ~MessageQueueIF() {}
|
||||
/**
|
||||
* @brief This operation sends a message to the last communication partner.
|
||||
* @details
|
||||
@ -82,11 +82,11 @@ class MessageQueueIF {
|
||||
/**
|
||||
* @brief This method returns the message queue ID of the last communication partner.
|
||||
*/
|
||||
[[nodiscard]] virtual MessageQueueId_t getLastPartner() const = 0;
|
||||
virtual MessageQueueId_t getLastPartner() const = 0;
|
||||
/**
|
||||
* @brief This method returns the message queue ID of this class's message queue.
|
||||
*/
|
||||
[[nodiscard]] virtual MessageQueueId_t getId() const = 0;
|
||||
virtual MessageQueueId_t getId() const = 0;
|
||||
|
||||
/**
|
||||
* @brief With the sendMessage call, a queue message is sent to a receiving queue.
|
||||
@ -159,9 +159,9 @@ class MessageQueueIF {
|
||||
/**
|
||||
* @brief This method is a simple getter for the default destination.
|
||||
*/
|
||||
[[nodiscard]] virtual MessageQueueId_t getDefaultDestination() const = 0;
|
||||
virtual MessageQueueId_t getDefaultDestination() const = 0;
|
||||
|
||||
[[nodiscard]] virtual bool isDefaultDestinationSet() const = 0;
|
||||
virtual bool isDefaultDestinationSet() const = 0;
|
||||
|
||||
virtual MqArgs& getMqArgs() = 0;
|
||||
};
|
||||
|
@ -10,10 +10,10 @@ MessageQueueMessage::MessageQueueMessage() : messageSize(getMinimumMessageSize()
|
||||
}
|
||||
|
||||
MessageQueueMessage::MessageQueueMessage(uint8_t* data, size_t size)
|
||||
: messageSize(MessageQueueMessage::HEADER_SIZE + size) {
|
||||
if (size <= MessageQueueMessage::MAX_DATA_SIZE) {
|
||||
std::memcpy(MessageQueueMessage::getData(), data, size);
|
||||
this->messageSize = MessageQueueMessage::HEADER_SIZE + size;
|
||||
: messageSize(this->HEADER_SIZE + size) {
|
||||
if (size <= this->MAX_DATA_SIZE) {
|
||||
memcpy(this->getData(), data, size);
|
||||
this->messageSize = this->HEADER_SIZE + size;
|
||||
} else {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "MessageQueueMessage: Passed size larger than maximum"
|
||||
@ -21,23 +21,21 @@ MessageQueueMessage::MessageQueueMessage(uint8_t* data, size_t size)
|
||||
<< std::endl;
|
||||
#endif
|
||||
memset(this->internalBuffer, 0, sizeof(this->internalBuffer));
|
||||
this->messageSize = MessageQueueMessage::HEADER_SIZE;
|
||||
this->messageSize = this->HEADER_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
MessageQueueMessage::~MessageQueueMessage() = default;
|
||||
MessageQueueMessage::~MessageQueueMessage() {}
|
||||
|
||||
const uint8_t* MessageQueueMessage::getBuffer() const { return this->internalBuffer; }
|
||||
|
||||
uint8_t* MessageQueueMessage::getBuffer() { return this->internalBuffer; }
|
||||
|
||||
const uint8_t* MessageQueueMessage::getData() const {
|
||||
return this->internalBuffer + MessageQueueMessage::HEADER_SIZE;
|
||||
return this->internalBuffer + this->HEADER_SIZE;
|
||||
}
|
||||
|
||||
uint8_t* MessageQueueMessage::getData() {
|
||||
return this->internalBuffer + MessageQueueMessage::HEADER_SIZE;
|
||||
}
|
||||
uint8_t* MessageQueueMessage::getData() { return this->internalBuffer + this->HEADER_SIZE; }
|
||||
|
||||
MessageQueueId_t MessageQueueMessage::getSender() const {
|
||||
MessageQueueId_t temp_id;
|
||||
@ -60,22 +58,14 @@ void MessageQueueMessage::print(bool printWholeMessage) {
|
||||
}
|
||||
}
|
||||
|
||||
void MessageQueueMessage::clear() {
|
||||
memset(this->getBuffer(), 0, MessageQueueMessage::MAX_MESSAGE_SIZE);
|
||||
}
|
||||
void MessageQueueMessage::clear() { memset(this->getBuffer(), 0, this->MAX_MESSAGE_SIZE); }
|
||||
|
||||
size_t MessageQueueMessage::getMessageSize() const { return this->messageSize; }
|
||||
|
||||
void MessageQueueMessage::setMessageSize(size_t messageSize_) { this->messageSize = messageSize_; }
|
||||
void MessageQueueMessage::setMessageSize(size_t messageSize) { this->messageSize = messageSize; }
|
||||
|
||||
size_t MessageQueueMessage::getMinimumMessageSize() const {
|
||||
return MessageQueueMessage::MIN_MESSAGE_SIZE;
|
||||
}
|
||||
size_t MessageQueueMessage::getMinimumMessageSize() const { return this->MIN_MESSAGE_SIZE; }
|
||||
|
||||
size_t MessageQueueMessage::getMaximumMessageSize() const {
|
||||
return MessageQueueMessage::MAX_MESSAGE_SIZE;
|
||||
}
|
||||
size_t MessageQueueMessage::getMaximumMessageSize() const { return this->MAX_MESSAGE_SIZE; }
|
||||
|
||||
size_t MessageQueueMessage::getMaximumDataSize() const {
|
||||
return MessageQueueMessage::MAX_DATA_SIZE;
|
||||
}
|
||||
size_t MessageQueueMessage::getMaximumDataSize() const { return this->MAX_DATA_SIZE; }
|
||||
|
@ -25,30 +25,6 @@
|
||||
*/
|
||||
class MessageQueueMessage : public MessageQueueMessageIF {
|
||||
public:
|
||||
/**
|
||||
* @brief This constant defines the maximum size of the data content,
|
||||
* excluding the header.
|
||||
* @details
|
||||
* It may be changed if necessary, but in general should be kept
|
||||
* as small as possible.
|
||||
*/
|
||||
static const size_t MAX_DATA_SIZE = 24;
|
||||
/**
|
||||
* @brief This constant defines the maximum total size in bytes
|
||||
* of a sent message.
|
||||
* @details
|
||||
* It is the sum of the maximum data and the header size. Be aware that
|
||||
* this constant is used to define the buffer sizes for every message
|
||||
* queue in the system. So, a change here may have significant impact on
|
||||
* the required resources.
|
||||
*/
|
||||
static constexpr size_t MAX_MESSAGE_SIZE = MAX_DATA_SIZE + HEADER_SIZE;
|
||||
/**
|
||||
* @brief Defines the minimum size of a message where only the
|
||||
* header is included
|
||||
*/
|
||||
static constexpr size_t MIN_MESSAGE_SIZE = HEADER_SIZE;
|
||||
|
||||
/**
|
||||
* @brief The class is initialized empty with this constructor.
|
||||
* @details
|
||||
@ -74,12 +50,59 @@ class MessageQueueMessage : public MessageQueueMessageIF {
|
||||
* @brief As no memory is allocated in this class,
|
||||
* the destructor is empty.
|
||||
*/
|
||||
~MessageQueueMessage() override;
|
||||
virtual ~MessageQueueMessage();
|
||||
|
||||
/**
|
||||
* @brief The size information of each message is stored in
|
||||
* this attribute.
|
||||
* @details
|
||||
* It is public to simplify usage and to allow for passing the size
|
||||
* address as a pointer. Care must be taken when inheriting from this class,
|
||||
* as every child class is responsible for managing the size information by
|
||||
* itself. When using the class to receive a message, the size information
|
||||
* is updated automatically.
|
||||
*
|
||||
* Please note that the minimum size is limited by the size of the header
|
||||
* while the maximum size is limited by the maximum allowed message size.
|
||||
*/
|
||||
size_t messageSize;
|
||||
/**
|
||||
* @brief This constant defines the maximum size of the data content,
|
||||
* excluding the header.
|
||||
* @details
|
||||
* It may be changed if necessary, but in general should be kept
|
||||
* as small as possible.
|
||||
*/
|
||||
static const size_t MAX_DATA_SIZE = 24;
|
||||
|
||||
/**
|
||||
* @brief This constant defines the maximum total size in bytes
|
||||
* of a sent message.
|
||||
* @details
|
||||
* It is the sum of the maximum data and the header size. Be aware that
|
||||
* this constant is used to define the buffer sizes for every message
|
||||
* queue in the system. So, a change here may have significant impact on
|
||||
* the required resources.
|
||||
*/
|
||||
static constexpr size_t MAX_MESSAGE_SIZE = MAX_DATA_SIZE + HEADER_SIZE;
|
||||
/**
|
||||
* @brief Defines the minimum size of a message where only the
|
||||
* header is included
|
||||
*/
|
||||
static constexpr size_t MIN_MESSAGE_SIZE = HEADER_SIZE;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief This is the internal buffer that contains the
|
||||
* actual message data.
|
||||
*/
|
||||
uint8_t internalBuffer[MAX_MESSAGE_SIZE];
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief This method is used to get the complete data of the message.
|
||||
*/
|
||||
[[nodiscard]] const uint8_t* getBuffer() const override;
|
||||
const uint8_t* getBuffer() const override;
|
||||
/**
|
||||
* @brief This method is used to get the complete data of the message.
|
||||
*/
|
||||
@ -89,7 +112,7 @@ class MessageQueueMessage : public MessageQueueMessageIF {
|
||||
* @details
|
||||
* It shall be used by child classes to add data at the right position.
|
||||
*/
|
||||
[[nodiscard]] const uint8_t* getData() const override;
|
||||
const uint8_t* getData() const override;
|
||||
/**
|
||||
* @brief This method is used to fetch the data content of the message.
|
||||
* @details
|
||||
@ -100,7 +123,7 @@ class MessageQueueMessage : public MessageQueueMessageIF {
|
||||
* @brief This method is used to extract the sender's message
|
||||
* queue id information from a received message.
|
||||
*/
|
||||
[[nodiscard]] MessageQueueId_t getSender() const override;
|
||||
MessageQueueId_t getSender() const override;
|
||||
/**
|
||||
* @brief With this method, the whole content
|
||||
* and the message size is set to zero.
|
||||
@ -115,40 +138,16 @@ class MessageQueueMessage : public MessageQueueMessageIF {
|
||||
*/
|
||||
void setSender(MessageQueueId_t setId) override;
|
||||
|
||||
[[nodiscard]] size_t getMessageSize() const override;
|
||||
void setMessageSize(size_t messageSize) override;
|
||||
[[nodiscard]] size_t getMinimumMessageSize() const override;
|
||||
[[nodiscard]] size_t getMaximumMessageSize() const override;
|
||||
[[nodiscard]] size_t getMaximumDataSize() const override;
|
||||
virtual size_t getMessageSize() const override;
|
||||
virtual void setMessageSize(size_t messageSize) override;
|
||||
virtual size_t getMinimumMessageSize() const override;
|
||||
virtual size_t getMaximumMessageSize() const override;
|
||||
virtual size_t getMaximumDataSize() const override;
|
||||
|
||||
/**
|
||||
* @brief This is a debug method that prints the content.
|
||||
*/
|
||||
void print(bool printWholeMessage);
|
||||
|
||||
/**
|
||||
* TODO: This really should not be public. If it should be possible to pass size address as a
|
||||
* pointer, add a getter function returning a const reference to the size
|
||||
* @brief The size information of each message is stored in
|
||||
* this attribute.
|
||||
* @details
|
||||
* It is public to simplify usage and to allow for passing the size
|
||||
* address as a pointer. Care must be taken when inheriting from this class,
|
||||
* as every child class is responsible for managing the size information by
|
||||
* itself. When using the class to receive a message, the size information
|
||||
* is updated automatically.
|
||||
*
|
||||
* Please note that the minimum size is limited by the size of the header
|
||||
* while the maximum size is limited by the maximum allowed message size.
|
||||
*/
|
||||
size_t messageSize;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief This is the internal buffer that contains the
|
||||
* actual message data.
|
||||
*/
|
||||
uint8_t internalBuffer[MAX_MESSAGE_SIZE] = {};
|
||||
};
|
||||
|
||||
#endif /* FSFW_IPC_MESSAGEQUEUEMESSAGE_H_ */
|
||||
|
@ -14,7 +14,7 @@ class MessageQueueMessageIF {
|
||||
*/
|
||||
static const size_t HEADER_SIZE = sizeof(MessageQueueId_t);
|
||||
|
||||
virtual ~MessageQueueMessageIF() = default;
|
||||
virtual ~MessageQueueMessageIF(){};
|
||||
|
||||
/**
|
||||
* @brief With this method, the whole content and the message
|
||||
@ -29,7 +29,7 @@ class MessageQueueMessageIF {
|
||||
* @brief Get read-only pointer to the complete data of the message.
|
||||
* @return
|
||||
*/
|
||||
[[nodiscard]] virtual const uint8_t* getBuffer() const = 0;
|
||||
virtual const uint8_t* getBuffer() const = 0;
|
||||
|
||||
/**
|
||||
* @brief This method is used to get the complete data of the message.
|
||||
@ -48,14 +48,14 @@ class MessageQueueMessageIF {
|
||||
* @brief This method is used to extract the sender's message queue id
|
||||
* information from a received message.
|
||||
*/
|
||||
[[nodiscard]] virtual MessageQueueId_t getSender() const = 0;
|
||||
virtual MessageQueueId_t getSender() const = 0;
|
||||
|
||||
/**
|
||||
* @brief This method is used to fetch the data content of the message.
|
||||
* @details
|
||||
* It shall be used by child classes to add data at the right position.
|
||||
*/
|
||||
[[nodiscard]] virtual const uint8_t* getData() const = 0;
|
||||
virtual const uint8_t* getData() const = 0;
|
||||
/**
|
||||
* @brief This method is used to fetch the data content of the message.
|
||||
* @details
|
||||
@ -67,28 +67,12 @@ class MessageQueueMessageIF {
|
||||
* Get constant message size of current message implementation.
|
||||
* @return
|
||||
*/
|
||||
[[nodiscard]] virtual size_t getMessageSize() const = 0;
|
||||
virtual size_t getMessageSize() const = 0;
|
||||
|
||||
/**
|
||||
* Sets the current message size of a given message
|
||||
* @param messageSize
|
||||
*/
|
||||
virtual void setMessageSize(size_t messageSize) = 0;
|
||||
/**
|
||||
* Returns the smallest possible message size, including any headers
|
||||
* @return
|
||||
*/
|
||||
[[nodiscard]] virtual size_t getMinimumMessageSize() const = 0;
|
||||
/**
|
||||
* Returns the largest possible message size, including any headers
|
||||
* @return
|
||||
*/
|
||||
[[nodiscard]] virtual size_t getMaximumMessageSize() const = 0;
|
||||
/**
|
||||
* Returns the largest possible data size without any headers
|
||||
* @return
|
||||
*/
|
||||
[[nodiscard]] virtual size_t getMaximumDataSize() const = 0;
|
||||
virtual size_t getMinimumMessageSize() const = 0;
|
||||
virtual size_t getMaximumMessageSize() const = 0;
|
||||
virtual size_t getMaximumDataSize() const = 0;
|
||||
};
|
||||
|
||||
#endif /* FRAMEWORK_IPC_MESSAGEQUEUEMESSAGEIF_H_ */
|
||||
|
@ -1,14 +1,14 @@
|
||||
#ifndef FSFW_IPC_MESSAGEQUEUESENDERIF_H_
|
||||
#define FSFW_IPC_MESSAGEQUEUESENDERIF_H_
|
||||
|
||||
#include "../objectmanager/ObjectManagerIF.h"
|
||||
#include "MessageQueueIF.h"
|
||||
#include "MessageQueueMessageIF.h"
|
||||
#include "fsfw/objectmanager/ObjectManagerIF.h"
|
||||
|
||||
class MessageQueueSenderIF {
|
||||
public:
|
||||
virtual ~MessageQueueSenderIF() = default;
|
||||
MessageQueueSenderIF() = delete;
|
||||
virtual ~MessageQueueSenderIF() {}
|
||||
|
||||
/**
|
||||
* Allows sending messages without actually "owning" a message queue.
|
||||
* Not sure whether this is actually a good idea.
|
||||
@ -16,6 +16,9 @@ class MessageQueueSenderIF {
|
||||
static ReturnValue_t sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||
MessageQueueId_t sentFrom = MessageQueueIF::NO_QUEUE,
|
||||
bool ignoreFault = false);
|
||||
|
||||
private:
|
||||
MessageQueueSenderIF() {}
|
||||
};
|
||||
|
||||
#endif /* FSFW_IPC_MESSAGEQUEUESENDERIF_H_ */
|
||||
|
@ -4,9 +4,7 @@
|
||||
#include <cstdint>
|
||||
|
||||
#include "../events/Event.h"
|
||||
#include "../introspection/ClasslessEnum.h"
|
||||
#include "../returnvalues/returnvalue.h"
|
||||
#include "ModeDefinitionHelper.h"
|
||||
#include "ModeHelper.h"
|
||||
#include "ModeMessage.h"
|
||||
|
||||
@ -21,39 +19,35 @@ class HasModesIF {
|
||||
static const ReturnValue_t INVALID_SUBMODE = MAKE_RETURN_CODE(0x04);
|
||||
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER;
|
||||
//! An object announces changing the mode. p1: target mode. p2: target submode
|
||||
static const Event CHANGING_MODE = MAKE_EVENT(0, severity::INFO);
|
||||
//! An Object announces its mode; parameter1 is mode, parameter2 is submode
|
||||
static const Event MODE_INFO = MAKE_EVENT(1, severity::INFO);
|
||||
static const Event CHANGING_MODE =
|
||||
MAKE_EVENT(0, severity::INFO); //!< An object announces changing the mode. p1: target mode.
|
||||
//!< p2: target submode
|
||||
static const Event MODE_INFO = MAKE_EVENT(
|
||||
1,
|
||||
severity::INFO); //!< An Object announces its mode; parameter1 is mode, parameter2 is submode
|
||||
static const Event FALLBACK_FAILED = MAKE_EVENT(2, severity::HIGH);
|
||||
static const Event MODE_TRANSITION_FAILED = MAKE_EVENT(3, severity::LOW);
|
||||
static const Event CANT_KEEP_MODE = MAKE_EVENT(4, severity::HIGH);
|
||||
//! Indicates a bug or configuration failure: Object is in a mode it should never be in.
|
||||
static const Event OBJECT_IN_INVALID_MODE = MAKE_EVENT(5, severity::LOW);
|
||||
//! The mode is changed, but for some reason, the change is forced, i.e. EXTERNAL_CONTROL ignored.
|
||||
//! p1: target mode. p2: target submode
|
||||
static const Event FORCING_MODE = MAKE_EVENT(6, severity::MEDIUM);
|
||||
//! A mode command was rejected by the called object. Par1: called object id, Par2: return code.
|
||||
static const Event MODE_CMD_REJECTED = MAKE_EVENT(7, severity::LOW);
|
||||
static const Event OBJECT_IN_INVALID_MODE =
|
||||
MAKE_EVENT(5, severity::LOW); //!< Indicates a bug or configuration failure: Object is in a
|
||||
//!< mode it should never be in.
|
||||
static const Event FORCING_MODE = MAKE_EVENT(
|
||||
6, severity::MEDIUM); //!< The mode is changed, but for some reason, the change is forced,
|
||||
//!< i.e. EXTERNAL_CONTROL ignored. p1: target mode. p2: target submode
|
||||
static const Event MODE_CMD_REJECTED =
|
||||
MAKE_EVENT(7, severity::LOW); //!< A mode command was rejected by the called object. Par1:
|
||||
//!< called object id, Par2: return code.
|
||||
|
||||
//! The device is powered and ready to perform operations. In this mode, no commands are
|
||||
//! sent by the device handler itself, but direct commands can be commanded and will be
|
||||
//! interpreted
|
||||
static constexpr Mode_t MODE_ON = 1;
|
||||
//! The device is powered off. The only command accepted in this mode is a mode change to on.
|
||||
static constexpr Mode_t MODE_OFF = 0;
|
||||
|
||||
static constexpr Mode_t MODE_INVALID = -1;
|
||||
static constexpr Mode_t MODE_UNDEFINED = -2;
|
||||
|
||||
FSFW_CLASSLESS_ENUM(DefaultSubmode, Submode_t,
|
||||
((SUBMODE_NONE, 0,
|
||||
"Default"))) //!< To avoid checks against magic number "0".
|
||||
static const Mode_t MODE_ON =
|
||||
1; //!< The device is powered and ready to perform operations. In this mode, no commands are
|
||||
//!< sent by the device handler itself, but direct commands van be commanded and will be
|
||||
//!< interpreted
|
||||
static const Mode_t MODE_OFF = 0; //!< The device is powered off. The only command accepted in
|
||||
//!< this mode is a mode change to on.
|
||||
static const Submode_t SUBMODE_NONE = 0; //!< To avoid checks against magic number "0".
|
||||
|
||||
virtual ~HasModesIF() {}
|
||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||
virtual const ModeHelper * getModeHelper() const = 0;
|
||||
virtual ModeDefinitionHelper getModeDefinitionHelper() = 0;
|
||||
virtual void getMode(Mode_t *mode, Submode_t *submode) = 0;
|
||||
|
||||
protected:
|
||||
|
@ -1,33 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <fsfw/introspection/EnumIF.h>
|
||||
|
||||
class ModeDefinitionHelper {
|
||||
public:
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
ModeDefinitionHelper(EnumIF *mode, EnumIF *submode) : mode(mode), submode(submode) {}
|
||||
#else
|
||||
ModeDefinitionHelper(void *mode, void *submode) {};
|
||||
#endif
|
||||
template <typename Mode, typename Submode>
|
||||
static ModeDefinitionHelper create() {
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
EnumIF *mode = new Mode();
|
||||
EnumIF *submode = new Submode();
|
||||
return ModeDefinitionHelper(mode, submode);
|
||||
#else
|
||||
return ModeDefinitionHelper(nullptr, nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void free() {
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
delete mode;
|
||||
delete submode;
|
||||
#endif
|
||||
}
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
EnumIF *mode;
|
||||
EnumIF *submode;
|
||||
#endif
|
||||
};
|
@ -4,7 +4,7 @@
|
||||
#include "fsfw/modes/HasModesIF.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
|
||||
ModeHelper::ModeHelper(HasModesIF *owner)
|
||||
ModeHelper::ModeHelper(HasModesIF* owner)
|
||||
: commandedMode(HasModesIF::MODE_OFF),
|
||||
commandedSubmode(HasModesIF::SUBMODE_NONE),
|
||||
owner(owner),
|
||||
@ -12,7 +12,7 @@ ModeHelper::ModeHelper(HasModesIF *owner)
|
||||
|
||||
ModeHelper::~ModeHelper() {}
|
||||
|
||||
ReturnValue_t ModeHelper::handleModeCommand(CommandMessage *command) {
|
||||
ReturnValue_t ModeHelper::handleModeCommand(CommandMessage* command) {
|
||||
CommandMessage reply;
|
||||
Mode_t mode;
|
||||
Submode_t submode;
|
||||
@ -106,33 +106,3 @@ bool ModeHelper::isTimedOut() { return countdown.hasTimedOut(); }
|
||||
bool ModeHelper::isForced() { return forced; }
|
||||
|
||||
void ModeHelper::setForced(bool forced) { this->forced = forced; }
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
std::vector<std::pair<Mode_t, const char *>> ModeHelper::getModes() const {
|
||||
std::vector<std::pair<Mode_t, const char *>> modeVector;
|
||||
auto modeDefinitionHelper = owner->getModeDefinitionHelper();
|
||||
EnumIF *mode = modeDefinitionHelper.mode;
|
||||
for (size_t i = 0; i < mode->getSize(); i++) {
|
||||
modeVector.push_back(
|
||||
std::pair<Mode_t, const char *>(mode->getElements()[i], mode->getDescriptions()[i]));
|
||||
}
|
||||
modeDefinitionHelper.free();
|
||||
return modeVector;
|
||||
}
|
||||
|
||||
std::vector<std::pair<Submode_t, const char *>> ModeHelper::getSubmodes(Mode_t mode) const {
|
||||
auto modeDefinitionHelper = owner->getModeDefinitionHelper();
|
||||
EnumIF *submode = modeDefinitionHelper.submode;
|
||||
std::vector<std::pair<Submode_t, const char *>> submodeVector;
|
||||
for (size_t i = 0; i < submode->getSize(); i++) {
|
||||
uint32_t ignored;
|
||||
if (owner->checkModeCommand(mode, submode->getElements()[i], &ignored) ==
|
||||
HasReturnvaluesIF::RETURN_OK) {
|
||||
submodeVector.push_back(std::pair<Submode_t, const char *>(submode->getElements()[i],
|
||||
submode->getDescriptions()[i]));
|
||||
}
|
||||
}
|
||||
modeDefinitionHelper.free();
|
||||
return submodeVector;
|
||||
}
|
||||
#endif
|
@ -1,8 +1,6 @@
|
||||
#ifndef FSFW_MODES_MODEHELPER_H_
|
||||
#define FSFW_MODES_MODEHELPER_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "ModeMessage.h"
|
||||
#include "fsfw/ipc/MessageQueueIF.h"
|
||||
#include "fsfw/returnvalues/returnvalue.h"
|
||||
@ -41,12 +39,6 @@ class ModeHelper {
|
||||
|
||||
void setForced(bool forced);
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
std::vector<std::pair<Mode_t, const char *>> getModes() const;
|
||||
|
||||
std::vector<std::pair<Submode_t, const char *>> getSubmodes(Mode_t mode) const;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
HasModesIF *owner;
|
||||
MessageQueueId_t parentQueueId = MessageQueueIF::NO_QUEUE;
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "../serialize/SerialLinkedListAdapter.h"
|
||||
#include "../serialize/SerializeElement.h"
|
||||
#include "../serviceinterface/ServiceInterface.h"
|
||||
#include "../timemanager/TimeWriterIF.h"
|
||||
#include "../timemanager/TimeStamperIF.h"
|
||||
#include "HasMonitorsIF.h"
|
||||
#include "MonitoringIF.h"
|
||||
#include "monitoringConf.h"
|
||||
@ -34,9 +34,9 @@ class MonitoringReportContent : public SerialLinkedListAdapter<SerializeIF> {
|
||||
SerializeElement<T> limitValue;
|
||||
SerializeElement<ReturnValue_t> oldState;
|
||||
SerializeElement<ReturnValue_t> newState;
|
||||
uint8_t rawTimestamp[TimeWriterIF::MAXIMUM_TIMESTAMP_LEN] = {};
|
||||
uint8_t rawTimestamp[TimeStamperIF::MISSION_TIMESTAMP_SIZE] = {};
|
||||
SerializeElement<SerialBufferAdapter<uint8_t>> timestampSerializer;
|
||||
TimeWriterIF* timeStamper;
|
||||
TimeStamperIF* timeStamper;
|
||||
MonitoringReportContent()
|
||||
: SerialLinkedListAdapter<SerializeIF>(¶meterObjectId),
|
||||
monitorId(0),
|
||||
@ -47,7 +47,7 @@ class MonitoringReportContent : public SerialLinkedListAdapter<SerializeIF> {
|
||||
oldState(0),
|
||||
newState(0),
|
||||
timestampSerializer(rawTimestamp, sizeof(rawTimestamp)),
|
||||
timeStamper(nullptr) {
|
||||
timeStamper(NULL) {
|
||||
setAllNext();
|
||||
}
|
||||
MonitoringReportContent(gp_id_t globalPoolId, T value, T limitValue, ReturnValue_t oldState,
|
||||
@ -61,7 +61,7 @@ class MonitoringReportContent : public SerialLinkedListAdapter<SerializeIF> {
|
||||
oldState(oldState),
|
||||
newState(newState),
|
||||
timestampSerializer(rawTimestamp, sizeof(rawTimestamp)),
|
||||
timeStamper(nullptr) {
|
||||
timeStamper(NULL) {
|
||||
setAllNext();
|
||||
if (checkAndSetStamper()) {
|
||||
timeStamper->addTimeStamp(rawTimestamp, sizeof(rawTimestamp));
|
||||
@ -79,7 +79,7 @@ class MonitoringReportContent : public SerialLinkedListAdapter<SerializeIF> {
|
||||
}
|
||||
bool checkAndSetStamper() {
|
||||
if (timeStamper == nullptr) {
|
||||
timeStamper = ObjectManager::instance()->get<TimeWriterIF>(timeStamperId);
|
||||
timeStamper = ObjectManager::instance()->get<TimeStamperIF>(timeStamperId);
|
||||
if (timeStamper == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "MonitoringReportContent::checkAndSetStamper: "
|
||||
|
@ -21,7 +21,7 @@ void ObjectManager::setObjectFactoryFunction(produce_function_t objFactoryFunc,
|
||||
this->factoryArgs = factoryArgs;
|
||||
}
|
||||
|
||||
ObjectManager::ObjectManager() = default;
|
||||
ObjectManager::ObjectManager() {}
|
||||
|
||||
ObjectManager::~ObjectManager() {
|
||||
for (auto const& iter : objectList) {
|
||||
@ -53,7 +53,7 @@ ReturnValue_t ObjectManager::insert(object_id_t id, SystemObjectIF* object) {
|
||||
}
|
||||
|
||||
ReturnValue_t ObjectManager::remove(object_id_t id) {
|
||||
if (this->getSystemObject(id) != nullptr) {
|
||||
if (this->getSystemObject(id) != NULL) {
|
||||
this->objectList.erase(id);
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
// sif::debug << "ObjectManager::removeObject: Object " << std::hex
|
||||
@ -78,7 +78,7 @@ SystemObjectIF* ObjectManager::getSystemObject(object_id_t id) {
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectManager::produce() {
|
||||
void ObjectManager::initialize() {
|
||||
if (objectFactoryFunction == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "ObjectManager::initialize: Passed produceObjects "
|
||||
@ -90,25 +90,18 @@ void ObjectManager::produce() {
|
||||
return;
|
||||
}
|
||||
objectFactoryFunction(factoryArgs);
|
||||
}
|
||||
|
||||
void ObjectManager::initialize() {
|
||||
produce();
|
||||
ReturnValue_t result = returnvalue::FAILED;
|
||||
uint32_t errorCount = 0;
|
||||
for (auto const& it : objectList) {
|
||||
result = it.second->initialize();
|
||||
if (result != returnvalue::OK) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
object_id_t var = it.first;
|
||||
sif::error << "ObjectManager::initialize: Object 0x" << std::hex << std::setw(8)
|
||||
<< std::setfill('0') << it.first << " failed to initialize with code 0x" << result
|
||||
<< std::dec << std::setfill(' ') << std::endl;
|
||||
#else
|
||||
sif::printError(
|
||||
"ObjectManager::initialize: Object 0x%08x failed to initialize with code 0x%04x\n", var,
|
||||
it.first);
|
||||
#endif
|
||||
<< std::setfill('0') << var
|
||||
<< " failed to "
|
||||
"initialize with code 0x"
|
||||
<< result << std::dec << std::setfill(' ') << std::endl;
|
||||
#endif
|
||||
errorCount++;
|
||||
}
|
||||
@ -147,7 +140,3 @@ void ObjectManager::printList() {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
const std::map<object_id_t, SystemObjectIF*> * ObjectManager::getObjectList(){
|
||||
return &objectList;
|
||||
}
|
||||
|
@ -38,13 +38,11 @@ class ObjectManager : public ObjectManagerIF {
|
||||
/**
|
||||
* @brief In the class's destructor, all objects in the list are deleted.
|
||||
*/
|
||||
~ObjectManager() override;
|
||||
virtual ~ObjectManager();
|
||||
ReturnValue_t insert(object_id_t id, SystemObjectIF* object) override;
|
||||
ReturnValue_t remove(object_id_t id) override;
|
||||
void initialize() override;
|
||||
void produce() override;
|
||||
void printList() override;
|
||||
const std::map<object_id_t, SystemObjectIF*> * getObjectList() override;
|
||||
|
||||
protected:
|
||||
SystemObjectIF* getSystemObject(object_id_t id) override;
|
||||
|
@ -1,8 +1,6 @@
|
||||
#ifndef FSFW_OBJECTMANAGER_OBJECTMANAGERIF_H_
|
||||
#define FSFW_OBJECTMANAGER_OBJECTMANAGERIF_H_
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "../returnvalues/returnvalue.h"
|
||||
#include "../serviceinterface/ServiceInterface.h"
|
||||
#include "SystemObjectIF.h"
|
||||
@ -60,14 +58,12 @@ class ObjectManagerIF {
|
||||
* @li returnvalue::OK in case the object was successfully removed
|
||||
*/
|
||||
virtual ReturnValue_t remove(object_id_t id) = 0;
|
||||
virtual void produce() = 0;
|
||||
virtual void initialize() = 0;
|
||||
/**
|
||||
* @brief This is a debug function, that prints the current content of the
|
||||
* object list.
|
||||
*/
|
||||
virtual void printList() = 0;
|
||||
virtual const std::map<object_id_t, SystemObjectIF*>* getObjectList() = 0;
|
||||
};
|
||||
|
||||
#endif /* OBJECTMANAGERIF_H_ */
|
||||
|
@ -46,7 +46,7 @@ class SystemObjectIF : public EventReportingProxyIF {
|
||||
* Therefore, a two-step initialization resolves this problem and prevents
|
||||
* circular dependencies of not-fully initialized objects on start up.
|
||||
* @return - @c returnvalue::OK in case the initialization was successful
|
||||
* - @c returnvalue::FAILED otherwise
|
||||
* - @c returnvalue::FAILED otherwise
|
||||
*/
|
||||
virtual ReturnValue_t initialize() = 0;
|
||||
/**
|
||||
|
@ -33,7 +33,6 @@ enum framework_objects : object_id_t {
|
||||
TC_STORE = 0x534f0100,
|
||||
TM_STORE = 0x534f0200,
|
||||
TIME_STAMPER = 0x53500010,
|
||||
VERIFICATION_REPORTER = 0x53500020,
|
||||
|
||||
FSFW_OBJECTS_END = 0x53ffffff,
|
||||
NO_OBJECT = 0xFFFFFFFF
|
||||
|
@ -16,9 +16,7 @@ elseif(FSFW_OSAL MATCHES "host")
|
||||
|
||||
else()
|
||||
|
||||
message(
|
||||
WARNING
|
||||
"${MSG_PREFIX} The FSFW_OSAL variable was not set. Assuming host OS..")
|
||||
message(WARNING "The OS_FSFW variable was not set. Assuming host OS..")
|
||||
# Not set. Assumuing this is a host build, try to determine host OS
|
||||
if(WIN32)
|
||||
add_subdirectory(host)
|
||||
|
@ -161,7 +161,7 @@ void TcpTmTcServer::handleServerOperation(socket_t& connSocket) {
|
||||
|
||||
while (true) {
|
||||
ssize_t retval = recv(connSocket, reinterpret_cast<char*>(receptionBuffer.data()),
|
||||
receptionBuffer.size(), tcpConfig.tcpFlags);
|
||||
receptionBuffer.capacity(), tcpConfig.tcpFlags);
|
||||
if (retval == 0) {
|
||||
size_t availableReadData = ringBuffer.getAvailableReadData();
|
||||
if (availableReadData > lastRingBufferSize) {
|
||||
@ -335,27 +335,31 @@ ReturnValue_t TcpTmTcServer::handleTcRingBufferData(size_t availableReadData) {
|
||||
}
|
||||
ringBuffer.readData(receptionBuffer.data(), readAmount, true);
|
||||
const uint8_t* bufPtr = receptionBuffer.data();
|
||||
SpacePacketParser::FoundPacketInfo info;
|
||||
if (spacePacketParser == nullptr) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
spacePacketParser->reset();
|
||||
while (spacePacketParser->getAmountRead() < readAmount) {
|
||||
result = spacePacketParser->parseSpacePackets(&bufPtr, readAmount, info);
|
||||
const uint8_t** bufPtrPtr = &bufPtr;
|
||||
size_t startIdx = 0;
|
||||
size_t foundSize = 0;
|
||||
size_t readLen = 0;
|
||||
while (readLen < readAmount) {
|
||||
if (spacePacketParser == nullptr) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
result =
|
||||
spacePacketParser->parseSpacePackets(bufPtrPtr, readAmount, startIdx, foundSize, readLen);
|
||||
switch (result) {
|
||||
case (SpacePacketParser::NO_PACKET_FOUND):
|
||||
case (SpacePacketParser::SPLIT_PACKET): {
|
||||
break;
|
||||
}
|
||||
case (returnvalue::OK): {
|
||||
result = handleTcReception(receptionBuffer.data() + info.startIdx, info.sizeFound);
|
||||
result = handleTcReception(receptionBuffer.data() + startIdx, foundSize);
|
||||
if (result != returnvalue::OK) {
|
||||
status = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
ringBuffer.deleteData(info.sizeFound);
|
||||
ringBuffer.deleteData(foundSize);
|
||||
lastRingBufferSize = ringBuffer.getAvailableReadData();
|
||||
std::memset(receptionBuffer.data() + startIdx, 0, foundSize);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) {
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::convertTimeOfDayToTimeval(const TimeOfDay_t* from, timeval* to) {
|
||||
struct tm time_tm {};
|
||||
struct tm time_tm;
|
||||
|
||||
time_tm.tm_year = from->year - 1900;
|
||||
time_tm.tm_mon = from->month - 1;
|
||||
|
@ -65,11 +65,11 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
||||
// But I will still return a failure here.
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
auto* targetQueue =
|
||||
MessageQueue* targetQueue =
|
||||
dynamic_cast<MessageQueue*>(QueueMapManager::instance()->getMessageQueue(sendTo));
|
||||
if (targetQueue == nullptr) {
|
||||
if (not ignoreFault) {
|
||||
auto* internalErrorReporter =
|
||||
InternalErrorReporterIF* internalErrorReporter =
|
||||
ObjectManager::instance()->get<InternalErrorReporterIF>(objects::INTERNAL_ERROR_REPORTER);
|
||||
if (internalErrorReporter != nullptr) {
|
||||
internalErrorReporter->queueMessageNotSent();
|
||||
@ -84,7 +84,7 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
||||
message->getMaximumMessageSize());
|
||||
} else {
|
||||
if (not ignoreFault) {
|
||||
auto* internalErrorReporter =
|
||||
InternalErrorReporterIF* internalErrorReporter =
|
||||
ObjectManager::instance()->get<InternalErrorReporterIF>(objects::INTERNAL_ERROR_REPORTER);
|
||||
if (internalErrorReporter != nullptr) {
|
||||
internalErrorReporter->queueMessageNotSent();
|
||||
|
@ -68,7 +68,7 @@ class MessageQueue : public MessageQueueBase {
|
||||
* @details This is accomplished by using the delete call provided
|
||||
* by the operating system.
|
||||
*/
|
||||
~MessageQueue() override;
|
||||
virtual ~MessageQueue();
|
||||
|
||||
// Implement non-generic MessageQueueIF functions not handled by MessageQueueBase
|
||||
virtual ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||
@ -111,6 +111,8 @@ class MessageQueue : public MessageQueueBase {
|
||||
size_t messageDepth = 0;
|
||||
|
||||
MutexIF* queueLock;
|
||||
|
||||
MessageQueueId_t defaultDestination = MessageQueueIF::NO_QUEUE;
|
||||
};
|
||||
|
||||
#endif /* FRAMEWORK_OSAL_HOST_MESSAGEQUEUE_H_ */
|
||||
|
@ -13,6 +13,7 @@ ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo,
|
||||
MessageQueueMessageIF* message,
|
||||
MessageQueueId_t sentFrom, bool ignoreFault) {
|
||||
return MessageQueue::sendMessageFromMessageQueue(sendTo, message, sentFrom, ignoreFault);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
QueueFactory* QueueFactory::instance() {
|
||||
@ -22,9 +23,9 @@ QueueFactory* QueueFactory::instance() {
|
||||
return factoryInstance;
|
||||
}
|
||||
|
||||
QueueFactory::QueueFactory() = default;
|
||||
QueueFactory::QueueFactory() {}
|
||||
|
||||
QueueFactory::~QueueFactory() = default;
|
||||
QueueFactory::~QueueFactory() {}
|
||||
|
||||
MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize,
|
||||
MqArgs* args) {
|
||||
|
@ -54,7 +54,7 @@ MessageQueueIF* QueueMapManager::getMessageQueue(MessageQueueId_t messageQueueId
|
||||
} else {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "QueueMapManager::getQueueHandle: The ID " << messageQueueId
|
||||
<< " does not exist in the map" << std::endl;
|
||||
<< " does not exists in the map!" << std::endl;
|
||||
#else
|
||||
sif::printWarning("QueueMapManager::getQueueHandle: The ID %d does not exist in the map!\n",
|
||||
messageQueueId);
|
||||
|
@ -2,22 +2,23 @@
|
||||
|
||||
#include <linux/sysinfo.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <ctime>
|
||||
#include <fstream>
|
||||
|
||||
#include "fsfw/ipc/MutexGuard.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
|
||||
uint32_t Clock::getTicksPerSecond() {
|
||||
uint32_t Clock::getTicksPerSecond(void) {
|
||||
uint32_t ticks = sysconf(_SC_CLK_TCK);
|
||||
return ticks;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::setClock(const TimeOfDay_t* time) {
|
||||
timespec timeUnix{};
|
||||
timeval timeTimeval{};
|
||||
timespec timeUnix;
|
||||
timeval timeTimeval;
|
||||
convertTimeOfDayToTimeval(time, &timeTimeval);
|
||||
timeUnix.tv_sec = timeTimeval.tv_sec;
|
||||
timeUnix.tv_nsec = (__syscall_slong_t)timeTimeval.tv_usec * 1000;
|
||||
@ -31,7 +32,7 @@ ReturnValue_t Clock::setClock(const TimeOfDay_t* time) {
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::setClock(const timeval* time) {
|
||||
timespec timeUnix{};
|
||||
timespec timeUnix;
|
||||
timeUnix.tv_sec = time->tv_sec;
|
||||
timeUnix.tv_nsec = (__syscall_slong_t)time->tv_usec * 1000;
|
||||
int status = clock_settime(CLOCK_REALTIME, &timeUnix);
|
||||
@ -43,7 +44,7 @@ ReturnValue_t Clock::setClock(const timeval* time) {
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
||||
timespec timeUnix{};
|
||||
timespec timeUnix;
|
||||
int status = clock_gettime(CLOCK_REALTIME, &timeUnix);
|
||||
if (status != 0) {
|
||||
return returnvalue::FAILED;
|
||||
@ -54,18 +55,18 @@ ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getClock_usecs(uint64_t* time) {
|
||||
timeval timeVal{};
|
||||
timeval timeVal;
|
||||
ReturnValue_t result = getClock_timeval(&timeVal);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
*time = static_cast<uint64_t>(timeVal.tv_sec) * 1e6 + timeVal.tv_usec;
|
||||
*time = (uint64_t)timeVal.tv_sec * 1e6 + timeVal.tv_usec;
|
||||
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
timeval Clock::getUptime() {
|
||||
timeval uptime{};
|
||||
timeval uptime;
|
||||
auto result = getUptime(&uptime);
|
||||
if (result != returnvalue::OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
@ -98,7 +99,7 @@ ReturnValue_t Clock::getUptime(timeval* uptime) {
|
||||
//}
|
||||
|
||||
ReturnValue_t Clock::getUptime(uint32_t* uptimeMs) {
|
||||
timeval uptime{};
|
||||
timeval uptime;
|
||||
ReturnValue_t result = getUptime(&uptime);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
@ -108,7 +109,7 @@ ReturnValue_t Clock::getUptime(uint32_t* uptimeMs) {
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) {
|
||||
timespec timeUnix{};
|
||||
timespec timeUnix;
|
||||
int status = clock_gettime(CLOCK_REALTIME, &timeUnix);
|
||||
if (status != 0) {
|
||||
// TODO errno
|
||||
@ -121,7 +122,7 @@ ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) {
|
||||
MutexGuard helper(timeMutex);
|
||||
// gmtime writes its output in a global buffer which is not Thread Safe
|
||||
// Therefore we have to use a Mutex here
|
||||
struct std::tm* timeInfo;
|
||||
struct tm* timeInfo;
|
||||
timeInfo = gmtime(&timeUnix.tv_sec);
|
||||
time->year = timeInfo->tm_year + 1900;
|
||||
time->month = timeInfo->tm_mon + 1;
|
||||
@ -135,7 +136,7 @@ ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) {
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::convertTimeOfDayToTimeval(const TimeOfDay_t* from, timeval* to) {
|
||||
std::tm fromTm{};
|
||||
tm fromTm;
|
||||
// Note: Fails for years before AD
|
||||
fromTm.tm_year = from->year - 1900;
|
||||
fromTm.tm_mon = from->month - 1;
|
||||
|
@ -66,8 +66,7 @@ class HasParametersIF {
|
||||
* @param newValues
|
||||
* @param startAtIndex Linear index, runs left to right, top to bottom for
|
||||
* matrix indexes.
|
||||
* @return returnvalue::OK if parameter is valid and a set function of the parameter wrapper was
|
||||
* called.
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
|
@ -44,7 +44,7 @@ store_address_t ParameterMessage::getParameterLoadCommand(const CommandMessage*
|
||||
*pfc = packedParamSettings >> 16 & 0xff;
|
||||
*rows = packedParamSettings >> 8 & 0xff;
|
||||
*columns = packedParamSettings & 0xff;
|
||||
return static_cast<store_address_t>(message->getParameter2());
|
||||
return message->getParameter2();
|
||||
}
|
||||
|
||||
void ParameterMessage::clear(CommandMessage* message) {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user