added srv3

This commit is contained in:
Robin Müller 2020-09-14 18:29:19 +02:00
parent 2d2316a0c7
commit e8de2fc47a
5 changed files with 388 additions and 3 deletions

View File

@ -19,6 +19,7 @@ enum {
SYSTEM_MANAGER_1 = 75,
SYSTEM_1 = 79,
PUS_SERVICE_1 = 80,
PUS_SERVICE_17 = 83,
FW_SUBSYSTEM_ID_RANGE
};
}

View File

@ -1,5 +1,5 @@
#ifndef MISSION_PUS_SERVICE17TEST_H_
#define MISSION_PUS_SERVICE17TEST_H_
#ifndef FSFW_PUS_SERVICE17TEST_H_
#define FSFW_PUS_SERVICE17TEST_H_
#include "../tmtcservices/PusServiceBase.h"
#include "../objectmanager/SystemObject.h"
@ -41,4 +41,4 @@ protected:
uint16_t packetSubCounter = 0;
};
#endif /* MISSION_PUS_SERVICE17TEST_H_ */
#endif /* FSFW_PUS_SERVICE17TEST_H_ */

View File

@ -0,0 +1,262 @@
#include "Service3Housekeeping.h"
#include "servicepackets/Service3Packets.h"
#include "../datapoollocal/HasLocalDataPoolIF.h"
Service3Housekeeping::Service3Housekeeping(object_id_t objectId, uint16_t apid,
uint8_t serviceId):
CommandingServiceBase(objectId, apid, serviceId,
NUM_OF_PARALLEL_COMMANDS, COMMAND_TIMEOUT_SECONDS) {}
Service3Housekeeping::~Service3Housekeeping() {}
ReturnValue_t Service3Housekeeping::isValidSubservice(uint8_t subservice) {
switch(static_cast<Subservice>(subservice)) {
case Subservice::ENABLE_PERIODIC_HK_REPORT_GENERATION:
case Subservice::DISABLE_PERIODIC_HK_REPORT_GENERATION:
case Subservice::ENABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION:
case Subservice::DISABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION:
case Subservice::REPORT_HK_REPORT_STRUCTURES:
case Subservice::REPORT_DIAGNOSTICS_REPORT_STRUCTURES :
case Subservice::GENERATE_ONE_PARAMETER_REPORT:
case Subservice::GENERATE_ONE_DIAGNOSTICS_REPORT:
case Subservice::MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL:
case Subservice::MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL:
return HasReturnvaluesIF::RETURN_OK;
// Telemetry or invalid subservice.
case Subservice::HK_DEFINITIONS_REPORT:
case Subservice::DIAGNOSTICS_DEFINITION_REPORT:
case Subservice::HK_REPORT:
case Subservice::DIAGNOSTICS_REPORT:
default:
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
}
}
ReturnValue_t Service3Housekeeping::getMessageQueueAndObject(uint8_t subservice,
const uint8_t *tcData, size_t tcDataLen,
MessageQueueId_t *id, object_id_t *objectId) {
return HasReturnvaluesIF::RETURN_OK;
ReturnValue_t result = checkAndAcquireTargetID(objectId,tcData,tcDataLen);
if(result != RETURN_OK) {
return result;
}
return checkInterfaceAndAcquireMessageQueue(id,objectId);
}
ReturnValue_t Service3Housekeeping::checkAndAcquireTargetID(
object_id_t* objectIdToSet, const uint8_t* tcData, size_t tcDataLen) {
if(SerializeAdapter::deSerialize(objectIdToSet, &tcData, &tcDataLen,
SerializeIF::Endianness::BIG) != HasReturnvaluesIF::RETURN_OK) {
return CommandingServiceBase::INVALID_TC;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t Service3Housekeeping::checkInterfaceAndAcquireMessageQueue(
MessageQueueId_t* messageQueueToSet, object_id_t* objectId) {
// check OwnsLocalDataPoolIF property of target
HasLocalDataPoolIF* possibleTarget =
objectManager->get<HasLocalDataPoolIF>(*objectId);
if(possibleTarget == nullptr){
return CommandingServiceBase::INVALID_OBJECT;
}
*messageQueueToSet = possibleTarget->getCommandQueue();
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t Service3Housekeeping::prepareCommand(CommandMessage* message,
uint8_t subservice, const uint8_t *tcData, size_t tcDataLen,
uint32_t *state, object_id_t objectId) {
switch(static_cast<Subservice>(subservice)) {
case Subservice::ENABLE_PERIODIC_HK_REPORT_GENERATION:
return prepareReportingTogglingCommand(message, true, false,
tcData, tcDataLen);
case Subservice::DISABLE_PERIODIC_HK_REPORT_GENERATION:
return prepareReportingTogglingCommand(message, false, false,
tcData, tcDataLen);
case Subservice::ENABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION:
return prepareReportingTogglingCommand(message, true, true,
tcData, tcDataLen);
case Subservice::DISABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION:
return prepareReportingTogglingCommand(message, false, true,
tcData, tcDataLen);
case Subservice::REPORT_HK_REPORT_STRUCTURES:
return prepareStructureReportingCommand(message, false, tcData,
tcDataLen);
case Subservice::REPORT_DIAGNOSTICS_REPORT_STRUCTURES:
return prepareStructureReportingCommand(message, true, tcData,
tcDataLen);
case Subservice::GENERATE_ONE_PARAMETER_REPORT:
return prepareOneShotReportCommand(message, false, tcData, tcDataLen);
case Subservice::GENERATE_ONE_DIAGNOSTICS_REPORT:
return prepareOneShotReportCommand(message, true, tcData, tcDataLen);
case Subservice::MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL:
return prepareCollectionIntervalModificationCommand(message, false,
tcData, tcDataLen);
case Subservice::MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL:
return prepareCollectionIntervalModificationCommand(message, true,
tcData, tcDataLen);
case Subservice::HK_DEFINITIONS_REPORT:
case Subservice::DIAGNOSTICS_DEFINITION_REPORT:
case Subservice::HK_REPORT:
case Subservice::DIAGNOSTICS_REPORT:
// Those are telemetry packets.
return CommandingServiceBase::INVALID_TC;
default:
// should never happen, subservice was already checked.
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t Service3Housekeeping::handleReply(const CommandMessage* reply,
Command_t previousCommand, uint32_t *state,
CommandMessage* optionalNextCommand, object_id_t objectId,
bool *isStep) {
switch(reply->getCommand()) {
case(HousekeepingMessage::HK_REQUEST_SUCCESS): {
return CommandingServiceBase::EXECUTION_COMPLETE;
}
case(HousekeepingMessage::HK_REQUEST_FAILURE): {
failureParameter1 = objectId;
// also provide failure reason (returnvalue)
// will be most commonly invalid SID or the set already has the desired
// reporting status.
return CommandingServiceBase::EXECUTION_COMPLETE;
}
default:
sif::error << "Service3Housekeeping::handleReply: Invalid reply!"
<< std::endl;
return CommandingServiceBase::INVALID_REPLY;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t Service3Housekeeping::prepareReportingTogglingCommand(
CommandMessage *command, bool enableReporting, bool isDiagnostics,
const uint8_t* tcData, size_t tcDataLen) {
if(tcDataLen < sizeof(sid_t)) {
// It is assumed the full SID is sent for now (even if that means
// 4 bytes are redundant)
return CommandingServiceBase::INVALID_TC;
}
sid_t targetSid;
SerializeAdapter::deSerialize(&targetSid.objectId, &tcData, &tcDataLen,
SerializeIF::Endianness::BIG);
SerializeAdapter::deSerialize(&targetSid.ownerSetId, &tcData, &tcDataLen,
SerializeIF::Endianness::BIG);
HousekeepingMessage::setToggleReportingCommand(command, targetSid,
enableReporting, isDiagnostics);
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t Service3Housekeeping::prepareStructureReportingCommand(
CommandMessage *command, bool isDiagnostics, const uint8_t* tcData,
size_t tcDataLen) {
if(tcDataLen < sizeof(sid_t)) {
// It is assumed the full SID is sent for now (even if that means
// 4 bytes are redundant)
return CommandingServiceBase::INVALID_TC;
}
sid_t targetSid;
SerializeAdapter::deSerialize(&targetSid.objectId, &tcData, &tcDataLen,
SerializeIF::Endianness::BIG);
SerializeAdapter::deSerialize(&targetSid.ownerSetId, &tcData, &tcDataLen,
SerializeIF::Endianness::BIG);
HousekeepingMessage::setStructureReportingCommand(command, targetSid,
isDiagnostics);
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t Service3Housekeeping::prepareOneShotReportCommand(
CommandMessage *command, bool isDiagnostics, const uint8_t *tcData,
size_t tcDataLen) {
if(tcDataLen < sizeof(sid_t)) {
// It is assumed the full SID is sent for now (even if that means
// 4 bytes are redundant)
return CommandingServiceBase::INVALID_TC;
}
sid_t targetSid;
SerializeAdapter::deSerialize(&targetSid.objectId, &tcData, &tcDataLen,
SerializeIF::Endianness::BIG);
SerializeAdapter::deSerialize(&targetSid.ownerSetId, &tcData, &tcDataLen,
SerializeIF::Endianness::BIG);
HousekeepingMessage::setOneShotReportCommand(command, targetSid,
isDiagnostics);
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t Service3Housekeeping::prepareCollectionIntervalModificationCommand(
CommandMessage *command, bool isDiagnostics, const uint8_t *tcData,
size_t tcDataLen) {
if(tcDataLen < sizeof(sid_t) + sizeof(float)) {
// It is assumed the full SID and the new collection interval as a float
// is sent for now (even if that means 4 bytes are redundant)
return CommandingServiceBase::INVALID_TC;
}
sid_t targetSid;
float newCollectionInterval = 0;
SerializeAdapter::deSerialize(&targetSid.objectId, &tcData, &tcDataLen,
SerializeIF::Endianness::BIG);
SerializeAdapter::deSerialize(&targetSid.ownerSetId, &tcData, &tcDataLen,
SerializeIF::Endianness::BIG);
SerializeAdapter::deSerialize(&newCollectionInterval, &tcData, &tcDataLen,
SerializeIF::Endianness::BIG);
HousekeepingMessage::setCollectionIntervalModificationCommand(command,
targetSid, newCollectionInterval, isDiagnostics);
return HasReturnvaluesIF::RETURN_OK;
}
void Service3Housekeeping::handleUnrequestedReply(
CommandMessage* reply) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
switch(reply->getCommand()) {
case(HousekeepingMessage::DIAGNOSTICS_REPORT): {
result = generateHkReport(reply,
static_cast<uint8_t>(Subservice::DIAGNOSTICS_REPORT));
break;
}
case(HousekeepingMessage::HK_REPORT): {
result = generateHkReport(reply,
static_cast<uint8_t>(Subservice::HK_REPORT));
break;
}
default: {
sif::error << "Service3Housekeeping::handleUnrequestedReply: "
<< "Invalid reply!" << std::endl;
}
}
if(result != HasReturnvaluesIF::RETURN_OK) {
// Configuration error
sif::debug << "Service3Housekeeping::handleUnrequestedReply:"
<< "Could not generate reply!" << std::endl;
}
}
MessageQueueId_t Service3Housekeeping::getHkQueue() const {
return commandQueue->getId();
}
ReturnValue_t Service3Housekeeping::generateHkReport(
const CommandMessage* hkMessage, uint8_t subserviceId) {
store_address_t storeId;
sid_t sid = HousekeepingMessage::getHkDataReply(hkMessage, &storeId);
auto resultPair = IPCStore->getData(storeId);
if(resultPair.first != HasReturnvaluesIF::RETURN_OK) {
return resultPair.first;
}
HkPacket hkPacket(sid, resultPair.second.data(), resultPair.second.size());
return sendTmPacket(static_cast<uint8_t>(subserviceId),
hkPacket.hkData, hkPacket.hkSize, nullptr, 0);
}

101
pus/Service3Housekeeping.h Normal file
View File

@ -0,0 +1,101 @@
#ifndef FSFW_PUS_SERVICE3HOUSEKEEPINGSERVICE_H_
#define FSFW_PUS_SERVICE3HOUSEKEEPINGSERVICE_H_
#include "../housekeeping/AcceptsHkPacketsIF.h"
#include "../housekeeping/HousekeepingMessage.h"
#include "../tmtcservices/CommandingServiceBase.h"
/**
* @brief Manges spacecraft housekeeping reports and
* sends pool variables (temperature, GPS data ...) to ground.
*
* @details Full Documentation: ECSS-E70-41A or ECSS-E-ST-70-41C.
* Implementation based on PUS-C
*
* The housekeeping service type provides means to control and adapt the
* spacecraft reporting plan according to the mission phases.
* The housekeeping service type provides the visibility of any
* on-board parameters assembled in housekeeping parameter report structures
* or diagnostic parameter report structures as required for the mission.
* The parameter report structures used by the housekeeping service can
* be predefined on-board or created when needed.
*
* @author R. Mueller
* @ingroup pus_services
*/
class Service3Housekeeping: public CommandingServiceBase,
public AcceptsHkPacketsIF {
public:
static constexpr uint8_t NUM_OF_PARALLEL_COMMANDS = 4;
static constexpr uint16_t COMMAND_TIMEOUT_SECONDS = 60;
Service3Housekeeping(object_id_t objectId, uint16_t apid, uint8_t serviceId);
virtual~ Service3Housekeeping();
protected:
/* CSB abstract functions implementation . See CSB documentation. */
ReturnValue_t isValidSubservice(uint8_t subservice) override;
ReturnValue_t getMessageQueueAndObject(uint8_t subservice,
const uint8_t *tcData, size_t tcDataLen, MessageQueueId_t *id,
object_id_t *objectId) override;
ReturnValue_t prepareCommand(CommandMessage* message,
uint8_t subservice, const uint8_t *tcData, size_t tcDataLen,
uint32_t *state, object_id_t objectId) override;
ReturnValue_t handleReply(const CommandMessage* reply,
Command_t previousCommand, uint32_t *state,
CommandMessage* optionalNextCommand, object_id_t objectId,
bool *isStep) override;
virtual MessageQueueId_t getHkQueue() const;
private:
enum class Subservice {
ENABLE_PERIODIC_HK_REPORT_GENERATION = 5, //!< [EXPORT] : [TC]
DISABLE_PERIODIC_HK_REPORT_GENERATION = 6, //!< [EXPORT] : [TC]
ENABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION = 7, //!< [EXPORT] : [TC]
DISABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION = 8, //!< [EXPORT] : [TC]
//! [EXPORT] : [TC] Report HK structure by supplying SID
REPORT_HK_REPORT_STRUCTURES = 9,
//! [EXPORT] : [TC] Report Diagnostics structure by supplying SID
REPORT_DIAGNOSTICS_REPORT_STRUCTURES = 11,
//! [EXPORT] : [TM] Report corresponding to Subservice 9 TC
HK_DEFINITIONS_REPORT = 10,
//! [EXPORT] : [TM] Report corresponding to Subservice 11 TC
DIAGNOSTICS_DEFINITION_REPORT = 12,
//! [EXPORT] : [TM] Core packet. Contains Housekeeping data
HK_REPORT = 25,
//! [EXPORT] : [TM] Core packet. Contains diagnostics data
DIAGNOSTICS_REPORT = 26,
/* PUS-C */
GENERATE_ONE_PARAMETER_REPORT = 27, //!< [EXPORT] : [TC]
GENERATE_ONE_DIAGNOSTICS_REPORT = 28, //!< [EXPORT] : [TC]
MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL = 31, //!< [EXPORT] : [TC]
MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL = 32, //!< [EXPORT] : [TC]
};
ReturnValue_t checkAndAcquireTargetID(object_id_t* objectIdToSet,
const uint8_t* tcData, size_t tcDataLen);
ReturnValue_t checkInterfaceAndAcquireMessageQueue(
MessageQueueId_t* messageQueueToSet, object_id_t* objectId);
ReturnValue_t generateHkReport(const CommandMessage* hkMessage,
uint8_t subserviceId);
ReturnValue_t prepareReportingTogglingCommand(CommandMessage* command,
bool enableReporting, bool isDiagnostics, const uint8_t* tcData,
size_t tcDataLen);
ReturnValue_t prepareStructureReportingCommand(CommandMessage* command,
bool isDiagnostics, const uint8_t* tcData, size_t tcDataLen);
ReturnValue_t prepareOneShotReportCommand(CommandMessage* command,
bool isDiagnostics, const uint8_t* tcData, size_t tcDataLen);
ReturnValue_t prepareCollectionIntervalModificationCommand(
CommandMessage* command, bool isDiagnostics, const uint8_t* tcData,
size_t tcDataLen);
void handleUnrequestedReply(CommandMessage* reply) override;
};
#endif /* FSFW_PUS_SERVICE3HOUSEKEEPINGSERVICE_H_ */

View File

@ -0,0 +1,21 @@
#ifndef FSFW_PUS_SERVICEPACKETS_SERVICE3PACKETS_H_
#define FSFW_PUS_SERVICEPACKETS_SERVICE3PACKETS_H_
#include <fsfw/housekeeping/HousekeepingMessage.h>
#include <cstdint>
/**
* @brief Subservices 25 and 26: TM packets
* @ingroup spacepackets
*/
class HkPacket { //!< [EXPORT] : [SUBSERVICE] 25, 26
public:
sid_t sid; //!< [EXPORT] : [COMMENT] Structure ID (SID) of housekeeping data.
const uint8_t* hkData; //!< [EXPORT] : [MAXSIZE] Deduced size
size_t hkSize; //!< [EXPORT] : [IGNORE]
HkPacket(sid_t sid, const uint8_t* data, size_t size):
sid(sid), hkData(data), hkSize(size) {}
};
#endif /* FSFW_PUS_SERVICEPACKETS_SERVICE3PACKETS_H_ */