This commit is contained in:
Robin Müller 2023-02-01 17:33:24 +01:00
parent 5c35b8e3cd
commit 1cacceddad
No known key found for this signature in database
GPG Key ID: 11D4952C8CCEF814
4 changed files with 79 additions and 41 deletions

View File

@ -8,7 +8,7 @@
#include "HealthTableIF.h" #include "HealthTableIF.h"
class HealthTable : public HealthTableIF, public SystemObject { class HealthTable : public HealthTableIF, public SystemObject {
friend class CService201HealthCommanding; friend class CServiceHealthCommanding;
public: public:
explicit HealthTable(object_id_t objectid); explicit HealthTable(object_id_t objectid);

View File

@ -9,4 +9,4 @@ target_sources(
Service17Test.cpp Service17Test.cpp
Service20ParameterManagement.cpp Service20ParameterManagement.cpp
CService200ModeCommanding.cpp CService200ModeCommanding.cpp
CService201HealthCommanding.cpp) CServiceHealthCommanding.cpp)

View File

@ -1,6 +1,5 @@
#include "fsfw/pus/CService201HealthCommanding.h"
#include <fsfw/events/EventManagerIF.h> #include <fsfw/events/EventManagerIF.h>
#include <fsfw/pus/CServiceHealthCommanding.h>
#include "fsfw/health/HasHealthIF.h" #include "fsfw/health/HasHealthIF.h"
#include "fsfw/health/HealthMessage.h" #include "fsfw/health/HealthMessage.h"
@ -8,15 +7,13 @@
#include "fsfw/pus/servicepackets/Service201Packets.h" #include "fsfw/pus/servicepackets/Service201Packets.h"
#include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/serviceinterface/ServiceInterface.h"
CService201HealthCommanding::CService201HealthCommanding(object_id_t objectId, uint16_t apid, CServiceHealthCommanding::CServiceHealthCommanding(HealthServiceCfg args)
uint8_t serviceId, HealthTable &table, : CommandingServiceBase(args.objectId, args.apid, "PUS 201 Health MGMT", args.service,
uint8_t numParallelCommands, args.numParallelCommands, args.commandTimeoutSeconds),
uint16_t commandTimeoutSeconds) healthTable(args.table),
: CommandingServiceBase(objectId, apid, "PUS 201 Health MGMT", serviceId, numParallelCommands, maxNumHealthInfoPerCycle(args.maxNumHealthInfoPerCycle) {}
commandTimeoutSeconds),
healthTable(table) {}
ReturnValue_t CService201HealthCommanding::isValidSubservice(uint8_t subservice) { ReturnValue_t CServiceHealthCommanding::isValidSubservice(uint8_t subservice) {
switch (subservice) { switch (subservice) {
case (Subservice::COMMAND_SET_HEALTH): case (Subservice::COMMAND_SET_HEALTH):
case (Subservice::COMMAND_ANNOUNCE_HEALTH): case (Subservice::COMMAND_ANNOUNCE_HEALTH):
@ -30,13 +27,14 @@ ReturnValue_t CService201HealthCommanding::isValidSubservice(uint8_t subservice)
} }
} }
ReturnValue_t CService201HealthCommanding::getMessageQueueAndObject(uint8_t subservice, ReturnValue_t CServiceHealthCommanding::getMessageQueueAndObject(uint8_t subservice,
const uint8_t *tcData, const uint8_t *tcData,
size_t tcDataLen, size_t tcDataLen,
MessageQueueId_t *id, MessageQueueId_t *id,
object_id_t *objectId) { object_id_t *objectId) {
if (subservice == Subservice::COMMAND_SET_HEALTH and switch (subservice) {
subservice == Subservice::COMMAND_ANNOUNCE_HEALTH) { case (Subservice::COMMAND_SET_HEALTH):
case (Subservice::COMMAND_ANNOUNCE_HEALTH): {
if (tcDataLen < sizeof(object_id_t)) { if (tcDataLen < sizeof(object_id_t)) {
return CommandingServiceBase::INVALID_TC; return CommandingServiceBase::INVALID_TC;
} }
@ -44,10 +42,16 @@ ReturnValue_t CService201HealthCommanding::getMessageQueueAndObject(uint8_t subs
return checkInterfaceAndAcquireMessageQueue(id, objectId); return checkInterfaceAndAcquireMessageQueue(id, objectId);
} }
case (Subservice::COMMAND_ANNOUNCE_HEALTH_ALL): {
return returnvalue::OK; return returnvalue::OK;
}
default: {
return returnvalue::FAILED;
}
}
} }
ReturnValue_t CService201HealthCommanding::checkInterfaceAndAcquireMessageQueue( ReturnValue_t CServiceHealthCommanding::checkInterfaceAndAcquireMessageQueue(
MessageQueueId_t *messageQueueToSet, const object_id_t *objectId) { MessageQueueId_t *messageQueueToSet, const object_id_t *objectId) {
auto *destination = ObjectManager::instance()->get<HasHealthIF>(*objectId); auto *destination = ObjectManager::instance()->get<HasHealthIF>(*objectId);
if (destination == nullptr) { if (destination == nullptr) {
@ -58,10 +62,9 @@ ReturnValue_t CService201HealthCommanding::checkInterfaceAndAcquireMessageQueue(
return returnvalue::OK; return returnvalue::OK;
} }
ReturnValue_t CService201HealthCommanding::prepareCommand(CommandMessage *message, ReturnValue_t CServiceHealthCommanding::prepareCommand(CommandMessage *message, uint8_t subservice,
uint8_t subservice, const uint8_t *tcData, const uint8_t *tcData, size_t tcDataLen,
size_t tcDataLen, uint32_t *state, uint32_t *state, object_id_t objectId) {
object_id_t objectId) {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
switch (subservice) { switch (subservice) {
case (Subservice::COMMAND_SET_HEALTH): { case (Subservice::COMMAND_SET_HEALTH): {
@ -80,6 +83,11 @@ ReturnValue_t CService201HealthCommanding::prepareCommand(CommandMessage *messag
} }
case (Subservice::COMMAND_ANNOUNCE_HEALTH_ALL): { case (Subservice::COMMAND_ANNOUNCE_HEALTH_ALL): {
ReturnValue_t result = iterateHealthTable(true); ReturnValue_t result = iterateHealthTable(true);
if (result == returnvalue::OK) {
reportAllHealth = true;
return EXECUTION_COMPLETE;
}
return result;
while (true) { while (true) {
ReturnValue_t result = iterateHealthTable(false); ReturnValue_t result = iterateHealthTable(false);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
@ -97,7 +105,7 @@ ReturnValue_t CService201HealthCommanding::prepareCommand(CommandMessage *messag
return result; return result;
} }
ReturnValue_t CService201HealthCommanding::handleReply(const CommandMessage *reply, ReturnValue_t CServiceHealthCommanding::handleReply(const CommandMessage *reply,
Command_t previousCommand, uint32_t *state, Command_t previousCommand, uint32_t *state,
CommandMessage *optionalNextCommand, CommandMessage *optionalNextCommand,
object_id_t objectId, bool *isStep) { object_id_t objectId, bool *isStep) {
@ -110,8 +118,20 @@ ReturnValue_t CService201HealthCommanding::handleReply(const CommandMessage *rep
return CommandingServiceBase::INVALID_REPLY; return CommandingServiceBase::INVALID_REPLY;
} }
void CServiceHealthCommanding::doPeriodicOperation() {
if (reportAllHealth) {
for (uint8_t i = 0; i < maxNumHealthInfoPerCycle; i++) {
ReturnValue_t result = iterateHealthTable(true);
if (result != returnvalue::OK) {
reportAllHealth = false;
break;
}
}
}
}
// Not used for now, health state already reported by event // Not used for now, health state already reported by event
[[maybe_unused]] ReturnValue_t CService201HealthCommanding::prepareHealthSetReply( [[maybe_unused]] ReturnValue_t CServiceHealthCommanding::prepareHealthSetReply(
const CommandMessage *reply) { const CommandMessage *reply) {
auto health = static_cast<uint8_t>(HealthMessage::getHealth(reply)); auto health = static_cast<uint8_t>(HealthMessage::getHealth(reply));
auto oldHealth = static_cast<uint8_t>(HealthMessage::getOldHealth(reply)); auto oldHealth = static_cast<uint8_t>(HealthMessage::getOldHealth(reply));
@ -119,7 +139,7 @@ ReturnValue_t CService201HealthCommanding::handleReply(const CommandMessage *rep
return sendTmPacket(Subservice::REPLY_HEALTH_SET, healthSetReply); return sendTmPacket(Subservice::REPLY_HEALTH_SET, healthSetReply);
} }
ReturnValue_t CService201HealthCommanding::iterateHealthTable(bool reset) { ReturnValue_t CServiceHealthCommanding::iterateHealthTable(bool reset) {
std::pair<object_id_t, HasHealthIF::HealthState> pair; std::pair<object_id_t, HasHealthIF::HealthState> pair;
ReturnValue_t result = healthTable.iterate(&pair, reset); ReturnValue_t result = healthTable.iterate(&pair, reset);

View File

@ -5,6 +5,22 @@
#include "fsfw/tmtcservices/CommandingServiceBase.h" #include "fsfw/tmtcservices/CommandingServiceBase.h"
struct HealthServiceCfg {
HealthServiceCfg(object_id_t objectId, uint16_t apid, HealthTable &healthTable,
uint16_t maxNumHealthInfoPerCycle)
: objectId(objectId),
apid(apid),
table(healthTable),
maxNumHealthInfoPerCycle(maxNumHealthInfoPerCycle) {}
object_id_t objectId;
uint16_t apid;
HealthTable &table;
uint16_t maxNumHealthInfoPerCycle;
uint8_t service = 201;
uint8_t numParallelCommands = 4;
uint16_t commandTimeoutSeconds = 60;
};
/** /**
* @brief Custom PUS service to set health of all objects * @brief Custom PUS service to set health of all objects
* implementing hasHealthIF. * implementing hasHealthIF.
@ -19,12 +35,10 @@
* child class like this service * child class like this service
* *
*/ */
class CService201HealthCommanding : public CommandingServiceBase { class CServiceHealthCommanding : public CommandingServiceBase {
public: public:
CService201HealthCommanding(object_id_t objectId, uint16_t apid, uint8_t serviceId, CServiceHealthCommanding(HealthServiceCfg args);
HealthTable &table, uint8_t numParallelCommands = 4, ~CServiceHealthCommanding() override = default;
uint16_t commandTimeoutSeconds = 60);
~CService201HealthCommanding() override = default;
protected: protected:
/* CSB abstract function implementations */ /* CSB abstract function implementations */
@ -40,8 +54,12 @@ class CService201HealthCommanding : public CommandingServiceBase {
CommandMessage *optionalNextCommand, object_id_t objectId, CommandMessage *optionalNextCommand, object_id_t objectId,
bool *isStep) override; bool *isStep) override;
void doPeriodicOperation() override;
private: private:
HealthTable &healthTable; HealthTable &healthTable;
uint16_t maxNumHealthInfoPerCycle = 0;
bool reportAllHealth = false;
ReturnValue_t iterateHealthTable(bool reset); ReturnValue_t iterateHealthTable(bool reset);
static ReturnValue_t checkInterfaceAndAcquireMessageQueue(MessageQueueId_t *MessageQueueToSet, static ReturnValue_t checkInterfaceAndAcquireMessageQueue(MessageQueueId_t *MessageQueueToSet,
const object_id_t *objectId); const object_id_t *objectId);