From 96e56ddc64909981b4e73ca72cd4d32ff4b6eade Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 20 Oct 2021 16:57:04 +0200 Subject: [PATCH] update tmtcservices module --- .../tmtcservices/CommandingServiceBase.cpp | 591 +++++++++--------- src/fsfw/tmtcservices/CommandingServiceBase.h | 560 ++++++++--------- src/fsfw/tmtcservices/PusServiceBase.cpp | 156 ++--- src/fsfw/tmtcservices/PusServiceBase.h | 226 +++---- src/fsfw/tmtcservices/PusVerificationReport.h | 2 +- .../tmtcservices/VerificationReporter.cpp | 4 +- src/fsfw/tmtcservices/VerificationReporter.h | 4 +- 7 files changed, 772 insertions(+), 771 deletions(-) diff --git a/src/fsfw/tmtcservices/CommandingServiceBase.cpp b/src/fsfw/tmtcservices/CommandingServiceBase.cpp index 10805b473..00fed415d 100644 --- a/src/fsfw/tmtcservices/CommandingServiceBase.cpp +++ b/src/fsfw/tmtcservices/CommandingServiceBase.cpp @@ -13,300 +13,300 @@ object_id_t CommandingServiceBase::defaultPacketSource = objects::NO_OBJECT; object_id_t CommandingServiceBase::defaultPacketDestination = objects::NO_OBJECT; CommandingServiceBase::CommandingServiceBase(object_id_t setObjectId, - uint16_t apid, uint8_t service, uint8_t numberOfParallelCommands, - uint16_t commandTimeoutSeconds, size_t queueDepth) : - SystemObject(setObjectId), apid(apid), service(service), - timeoutSeconds(commandTimeoutSeconds), - commandMap(numberOfParallelCommands) { - commandQueue = QueueFactory::instance()->createMessageQueue(queueDepth); - requestQueue = QueueFactory::instance()->createMessageQueue(queueDepth); + uint16_t apid, uint8_t service, uint8_t numberOfParallelCommands, + uint16_t commandTimeoutSeconds, size_t queueDepth) : + SystemObject(setObjectId), apid(apid), service(service), + timeoutSeconds(commandTimeoutSeconds), + commandMap(numberOfParallelCommands) { + commandQueue = QueueFactory::instance()->createMessageQueue(queueDepth); + requestQueue = QueueFactory::instance()->createMessageQueue(queueDepth); } void CommandingServiceBase::setPacketSource(object_id_t packetSource) { - this->packetSource = packetSource; + this->packetSource = packetSource; } void CommandingServiceBase::setPacketDestination( - object_id_t packetDestination) { - this->packetDestination = packetDestination; + object_id_t packetDestination) { + this->packetDestination = packetDestination; } CommandingServiceBase::~CommandingServiceBase() { - QueueFactory::instance()->deleteMessageQueue(commandQueue); - QueueFactory::instance()->deleteMessageQueue(requestQueue); + QueueFactory::instance()->deleteMessageQueue(commandQueue); + QueueFactory::instance()->deleteMessageQueue(requestQueue); } ReturnValue_t CommandingServiceBase::performOperation(uint8_t opCode) { - handleCommandQueue(); - handleRequestQueue(); - checkTimeout(); - doPeriodicOperation(); - return RETURN_OK; + handleCommandQueue(); + handleRequestQueue(); + checkTimeout(); + doPeriodicOperation(); + return RETURN_OK; } uint16_t CommandingServiceBase::getIdentifier() { - return service; + return service; } MessageQueueId_t CommandingServiceBase::getRequestQueue() { - return requestQueue->getId(); + return requestQueue->getId(); } ReturnValue_t CommandingServiceBase::initialize() { - ReturnValue_t result = SystemObject::initialize(); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } + ReturnValue_t result = SystemObject::initialize(); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } - if(packetDestination == objects::NO_OBJECT) { - packetDestination = defaultPacketDestination; - } - AcceptsTelemetryIF* packetForwarding = - ObjectManager::instance()->get(packetDestination); + if(packetDestination == objects::NO_OBJECT) { + packetDestination = defaultPacketDestination; + } + AcceptsTelemetryIF* packetForwarding = + ObjectManager::instance()->get(packetDestination); - if(packetSource == objects::NO_OBJECT) { - packetSource = defaultPacketSource; - } - PUSDistributorIF* distributor = ObjectManager::instance()->get( - packetSource); + if(packetSource == objects::NO_OBJECT) { + packetSource = defaultPacketSource; + } + PUSDistributorIF* distributor = ObjectManager::instance()->get( + packetSource); - if (packetForwarding == nullptr or distributor == nullptr) { + if (packetForwarding == nullptr or distributor == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "CommandingServiceBase::intialize: Packet source or " - "packet destination invalid!" << std::endl; + sif::error << "CommandingServiceBase::intialize: Packet source or " + "packet destination invalid!" << std::endl; #endif - return ObjectManagerIF::CHILD_INIT_FAILED; - } + return ObjectManagerIF::CHILD_INIT_FAILED; + } - distributor->registerService(this); - requestQueue->setDefaultDestination( - packetForwarding->getReportReceptionQueue()); + distributor->registerService(this); + requestQueue->setDefaultDestination( + packetForwarding->getReportReceptionQueue()); - IPCStore = ObjectManager::instance()->get(objects::IPC_STORE); - TCStore = ObjectManager::instance()->get(objects::TC_STORE); + IPCStore = ObjectManager::instance()->get(objects::IPC_STORE); + TCStore = ObjectManager::instance()->get(objects::TC_STORE); - if (IPCStore == nullptr or TCStore == nullptr) { + if (IPCStore == nullptr or TCStore == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "CommandingServiceBase::intialize: IPC store or TC store " - "not initialized yet!" << std::endl; + sif::error << "CommandingServiceBase::intialize: IPC store or TC store " + "not initialized yet!" << std::endl; #endif - return ObjectManagerIF::CHILD_INIT_FAILED; - } + return ObjectManagerIF::CHILD_INIT_FAILED; + } - return RETURN_OK; + return RETURN_OK; } void CommandingServiceBase::handleCommandQueue() { - CommandMessage reply; - ReturnValue_t result = RETURN_FAILED; - while(true) { - result = commandQueue->receiveMessage(&reply); - if (result == HasReturnvaluesIF::RETURN_OK) { - handleCommandMessage(&reply); - continue; - } - else if(result == MessageQueueIF::EMPTY) { - break; - } - else { + CommandMessage reply; + ReturnValue_t result = RETURN_FAILED; + while(true) { + result = commandQueue->receiveMessage(&reply); + if (result == HasReturnvaluesIF::RETURN_OK) { + handleCommandMessage(&reply); + continue; + } + else if(result == MessageQueueIF::EMPTY) { + break; + } + else { #if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "CommandingServiceBase::handleCommandQueue: Receiving message failed" - "with code" << result << std::endl; + sif::warning << "CommandingServiceBase::handleCommandQueue: Receiving message failed" + "with code" << result << std::endl; #else - sif::printWarning("CommandingServiceBase::handleCommandQueue: Receiving message " - "failed with code %d\n", result); + sif::printWarning("CommandingServiceBase::handleCommandQueue: Receiving message " + "failed with code %d\n", result); #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ #endif /* FSFW_VERBOSE_LEVEL >= 1 */ - break; - } - } + break; + } + } } void CommandingServiceBase::handleCommandMessage(CommandMessage* reply) { - bool isStep = false; - CommandMessage nextCommand; - CommandMapIter iter = commandMap.find(reply->getSender()); + bool isStep = false; + CommandMessage nextCommand; + CommandMapIter iter = commandMap.find(reply->getSender()); - // handle unrequested reply first - if (reply->getSender() == MessageQueueIF::NO_QUEUE or - iter == commandMap.end()) { - handleUnrequestedReply(reply); - return; - } - nextCommand.setCommand(CommandMessage::CMD_NONE); + // handle unrequested reply first + if (reply->getSender() == MessageQueueIF::NO_QUEUE or + iter == commandMap.end()) { + handleUnrequestedReply(reply); + return; + } + nextCommand.setCommand(CommandMessage::CMD_NONE); - // Implemented by child class, specifies what to do with reply. - ReturnValue_t result = handleReply(reply, iter->second.command, &iter->second.state, - &nextCommand, iter->second.objectId, &isStep); + // Implemented by child class, specifies what to do with reply. + ReturnValue_t result = handleReply(reply, iter->second.command, &iter->second.state, + &nextCommand, iter->second.objectId, &isStep); - /* If the child implementation does not implement special handling for - * rejected replies (RETURN_FAILED or INVALID_REPLY is returned), a - * failure verification will be generated with the reason as the - * return code and the initial command as failure parameter 1 */ - if((reply->getCommand() == CommandMessage::REPLY_REJECTED) and - (result == RETURN_FAILED or result == INVALID_REPLY)) { - result = reply->getReplyRejectedReason(); - failureParameter1 = iter->second.command; - } + /* If the child implementation does not implement special handling for + * rejected replies (RETURN_FAILED or INVALID_REPLY is returned), a + * failure verification will be generated with the reason as the + * return code and the initial command as failure parameter 1 */ + if((reply->getCommand() == CommandMessage::REPLY_REJECTED) and + (result == RETURN_FAILED or result == INVALID_REPLY)) { + result = reply->getReplyRejectedReason(); + failureParameter1 = iter->second.command; + } - switch (result) { - case EXECUTION_COMPLETE: - case RETURN_OK: - case NO_STEP_MESSAGE: - // handle result of reply handler implemented by developer. - handleReplyHandlerResult(result, iter, &nextCommand, reply, isStep); - break; - case INVALID_REPLY: - //might be just an unrequested reply at a bad moment - handleUnrequestedReply(reply); - break; - default: - if (isStep) { - verificationReporter.sendFailureReport( - tc_verification::PROGRESS_FAILURE, iter->second.tcInfo.ackFlags, - iter->second.tcInfo.tcPacketId, iter->second.tcInfo.tcSequenceControl, - result, ++iter->second.step, failureParameter1, - failureParameter2); - } else { - verificationReporter.sendFailureReport( - tc_verification::COMPLETION_FAILURE, iter->second.tcInfo.ackFlags, - iter->second.tcInfo.tcPacketId, iter->second.tcInfo.tcSequenceControl, - result, 0, failureParameter1, failureParameter2); - } - failureParameter1 = 0; - failureParameter2 = 0; - checkAndExecuteFifo(iter); - break; - } + switch (result) { + case EXECUTION_COMPLETE: + case RETURN_OK: + case NO_STEP_MESSAGE: + // handle result of reply handler implemented by developer. + handleReplyHandlerResult(result, iter, &nextCommand, reply, isStep); + break; + case INVALID_REPLY: + //might be just an unrequested reply at a bad moment + handleUnrequestedReply(reply); + break; + default: + if (isStep) { + verificationReporter.sendFailureReport( + tc_verification::PROGRESS_FAILURE, iter->second.tcInfo.ackFlags, + iter->second.tcInfo.tcPacketId, iter->second.tcInfo.tcSequenceControl, + result, ++iter->second.step, failureParameter1, + failureParameter2); + } else { + verificationReporter.sendFailureReport( + tc_verification::COMPLETION_FAILURE, iter->second.tcInfo.ackFlags, + iter->second.tcInfo.tcPacketId, iter->second.tcInfo.tcSequenceControl, + result, 0, failureParameter1, failureParameter2); + } + failureParameter1 = 0; + failureParameter2 = 0; + checkAndExecuteFifo(iter); + break; + } } void CommandingServiceBase::handleReplyHandlerResult(ReturnValue_t result, - CommandMapIter iter, CommandMessage* nextCommand, - CommandMessage* reply, bool& isStep) { - iter->second.command = nextCommand->getCommand(); + CommandMapIter iter, CommandMessage* nextCommand, + CommandMessage* reply, bool& isStep) { + iter->second.command = nextCommand->getCommand(); - // In case a new command is to be sent immediately, this is performed here. - // If no new command is sent, only analyse reply result by initializing - // sendResult as RETURN_OK - ReturnValue_t sendResult = RETURN_OK; - if (nextCommand->getCommand() != CommandMessage::CMD_NONE) { - sendResult = commandQueue->sendMessage(reply->getSender(), - nextCommand); - } + // In case a new command is to be sent immediately, this is performed here. + // If no new command is sent, only analyse reply result by initializing + // sendResult as RETURN_OK + ReturnValue_t sendResult = RETURN_OK; + if (nextCommand->getCommand() != CommandMessage::CMD_NONE) { + sendResult = commandQueue->sendMessage(reply->getSender(), + nextCommand); + } - if (sendResult == RETURN_OK) { - if (isStep and result != NO_STEP_MESSAGE) { - verificationReporter.sendSuccessReport( - tc_verification::PROGRESS_SUCCESS, - iter->second.tcInfo.ackFlags, iter->second.tcInfo.tcPacketId, - iter->second.tcInfo.tcSequenceControl, ++iter->second.step); - } - else { - verificationReporter.sendSuccessReport( - tc_verification::COMPLETION_SUCCESS, - iter->second.tcInfo.ackFlags, iter->second.tcInfo.tcPacketId, - iter->second.tcInfo.tcSequenceControl, 0); - checkAndExecuteFifo(iter); - } - } - else { - if (isStep) { - nextCommand->clearCommandMessage(); - verificationReporter.sendFailureReport( - tc_verification::PROGRESS_FAILURE, iter->second.tcInfo.ackFlags, - iter->second.tcInfo.tcPacketId, - iter->second.tcInfo.tcSequenceControl, sendResult, - ++iter->second.step, failureParameter1, failureParameter2); - } else { - nextCommand->clearCommandMessage(); - verificationReporter.sendFailureReport( - tc_verification::COMPLETION_FAILURE, - iter->second.tcInfo.ackFlags, iter->second.tcInfo.tcPacketId, - iter->second.tcInfo.tcSequenceControl, sendResult, 0, - failureParameter1, failureParameter2); - } - failureParameter1 = 0; - failureParameter2 = 0; - checkAndExecuteFifo(iter); - } + if (sendResult == RETURN_OK) { + if (isStep and result != NO_STEP_MESSAGE) { + verificationReporter.sendSuccessReport( + tc_verification::PROGRESS_SUCCESS, + iter->second.tcInfo.ackFlags, iter->second.tcInfo.tcPacketId, + iter->second.tcInfo.tcSequenceControl, ++iter->second.step); + } + else { + verificationReporter.sendSuccessReport( + tc_verification::COMPLETION_SUCCESS, + iter->second.tcInfo.ackFlags, iter->second.tcInfo.tcPacketId, + iter->second.tcInfo.tcSequenceControl, 0); + checkAndExecuteFifo(iter); + } + } + else { + if (isStep) { + nextCommand->clearCommandMessage(); + verificationReporter.sendFailureReport( + tc_verification::PROGRESS_FAILURE, iter->second.tcInfo.ackFlags, + iter->second.tcInfo.tcPacketId, + iter->second.tcInfo.tcSequenceControl, sendResult, + ++iter->second.step, failureParameter1, failureParameter2); + } else { + nextCommand->clearCommandMessage(); + verificationReporter.sendFailureReport( + tc_verification::COMPLETION_FAILURE, + iter->second.tcInfo.ackFlags, iter->second.tcInfo.tcPacketId, + iter->second.tcInfo.tcSequenceControl, sendResult, 0, + failureParameter1, failureParameter2); + } + failureParameter1 = 0; + failureParameter2 = 0; + checkAndExecuteFifo(iter); + } } void CommandingServiceBase::handleRequestQueue() { - TmTcMessage message; - ReturnValue_t result; - store_address_t address; - TcPacketStoredPus packet; - MessageQueueId_t queue; - object_id_t objectId; - for (result = requestQueue->receiveMessage(&message); result == RETURN_OK; - result = requestQueue->receiveMessage(&message)) { - address = message.getStorageId(); - packet.setStoreAddress(address); + TmTcMessage message; + ReturnValue_t result; + store_address_t address; + TcPacketStoredPus packet; + MessageQueueId_t queue; + object_id_t objectId; + for (result = requestQueue->receiveMessage(&message); result == RETURN_OK; + result = requestQueue->receiveMessage(&message)) { + address = message.getStorageId(); + packet.setStoreAddress(address, &packet); - if ((packet.getSubService() == 0) - or (isValidSubservice(packet.getSubService()) != RETURN_OK)) { - rejectPacket(tc_verification::START_FAILURE, &packet, INVALID_SUBSERVICE); - continue; - } + if ((packet.getSubService() == 0) + or (isValidSubservice(packet.getSubService()) != RETURN_OK)) { + rejectPacket(tc_verification::START_FAILURE, &packet, INVALID_SUBSERVICE); + continue; + } - result = getMessageQueueAndObject(packet.getSubService(), - packet.getApplicationData(), packet.getApplicationDataSize(), - &queue, &objectId); - if (result != HasReturnvaluesIF::RETURN_OK) { - rejectPacket(tc_verification::START_FAILURE, &packet, result); - continue; - } + result = getMessageQueueAndObject(packet.getSubService(), + packet.getApplicationData(), packet.getApplicationDataSize(), + &queue, &objectId); + if (result != HasReturnvaluesIF::RETURN_OK) { + rejectPacket(tc_verification::START_FAILURE, &packet, result); + continue; + } - //Is a command already active for the target object? - CommandMapIter iter; - iter = commandMap.find(queue); + //Is a command already active for the target object? + CommandMapIter iter; + iter = commandMap.find(queue); - if (iter != commandMap.end()) { - result = iter->second.fifo.insert(address); - if (result != RETURN_OK) { - rejectPacket(tc_verification::START_FAILURE, &packet, OBJECT_BUSY); - } - } else { - CommandInfo newInfo; //Info will be set by startExecution if neccessary - newInfo.objectId = objectId; - result = commandMap.insert(queue, newInfo, &iter); - if (result != RETURN_OK) { - rejectPacket(tc_verification::START_FAILURE, &packet, BUSY); - } else { - startExecution(&packet, iter); - } - } + if (iter != commandMap.end()) { + result = iter->second.fifo.insert(address); + if (result != RETURN_OK) { + rejectPacket(tc_verification::START_FAILURE, &packet, OBJECT_BUSY); + } + } else { + CommandInfo newInfo; //Info will be set by startExecution if neccessary + newInfo.objectId = objectId; + result = commandMap.insert(queue, newInfo, &iter); + if (result != RETURN_OK) { + rejectPacket(tc_verification::START_FAILURE, &packet, BUSY); + } else { + startExecution(&packet, iter); + } + } - } + } } ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice, - const uint8_t* data, size_t dataLen, const uint8_t* headerData, - size_t headerSize) { + const uint8_t* data, size_t dataLen, const uint8_t* headerData, + size_t headerSize) { #if FSFW_USE_PUS_C_TELEMETRY == 0 - TmPacketStoredPusA tmPacketStored(this->apid, this->service, subservice, - this->tmPacketCounter, data, dataLen, headerData, headerSize); + TmPacketStoredPusA tmPacketStored(this->apid, this->service, subservice, + this->tmPacketCounter, data, dataLen, headerData, headerSize); #else - TmPacketStoredPusC tmPacketStored(this->apid, this->service, subservice, + TmPacketStoredPusC tmPacketStored(this->apid, this->service, subservice, this->tmPacketCounter, data, dataLen, headerData, headerSize); #endif - ReturnValue_t result = tmPacketStored.sendPacket( - requestQueue->getDefaultDestination(), requestQueue->getId()); - if (result == HasReturnvaluesIF::RETURN_OK) { - this->tmPacketCounter++; - } - return result; + ReturnValue_t result = tmPacketStored.sendPacket( + requestQueue->getDefaultDestination(), requestQueue->getId()); + if (result == HasReturnvaluesIF::RETURN_OK) { + this->tmPacketCounter++; + } + return result; } @@ -316,7 +316,7 @@ ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice, uint8_t* pBuffer = buffer; size_t size = 0; SerializeAdapter::serialize(&objectId, &pBuffer, &size, - sizeof(object_id_t), SerializeIF::Endianness::BIG); + sizeof(object_id_t), SerializeIF::Endianness::BIG); #if FSFW_USE_PUS_C_TELEMETRY == 0 TmPacketStoredPusA tmPacketStored(this->apid, this->service, subservice, this->tmPacketCounter, data, dataLen, buffer, size); @@ -351,95 +351,96 @@ ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice, } -void CommandingServiceBase::startExecution(TcPacketStoredBase *storedPacket, +void CommandingServiceBase::startExecution(TcPacketStoredPus* storedPacket, CommandMapIter iter) { ReturnValue_t result = RETURN_OK; CommandMessage command; - TcPacketBase* tcPacketBase = storedPacket->getPacketBase(); - if(tcPacketBase == nullptr) { + //TcPacketPusBase* tcPacketBase = storedPacket->getPacketBase(); + if(storedPacket == nullptr) { return; } - iter->second.subservice = tcPacketBase->getSubService(); + iter->second.subservice = storedPacket->getSubService(); result = prepareCommand(&command, iter->second.subservice, - tcPacketBase->getApplicationData(), - tcPacketBase->getApplicationDataSize(), &iter->second.state, + storedPacket->getApplicationData(), + storedPacket->getApplicationDataSize(), &iter->second.state, iter->second.objectId); ReturnValue_t sendResult = RETURN_OK; - switch (result) { - case RETURN_OK: - if (command.getCommand() != CommandMessage::CMD_NONE) { - sendResult = commandQueue->sendMessage(iter.value->first, - &command); - } - if (sendResult == RETURN_OK) { - Clock::getUptime(&iter->second.uptimeOfStart); - iter->second.step = 0; - iter->second.subservice = tcPacketBase->getSubService(); - iter->second.command = command.getCommand(); - iter->second.tcInfo.ackFlags = tcPacketBase->getAcknowledgeFlags(); - iter->second.tcInfo.tcPacketId = tcPacketBase->getPacketId(); - iter->second.tcInfo.tcSequenceControl = - tcPacketBase->getPacketSequenceControl(); - acceptPacket(tc_verification::START_SUCCESS, storedPacket); - } else { - command.clearCommandMessage(); - rejectPacket(tc_verification::START_FAILURE, storedPacket, sendResult); - checkAndExecuteFifo(iter); - } - break; - case EXECUTION_COMPLETE: - if (command.getCommand() != CommandMessage::CMD_NONE) { - //Fire-and-forget command. - sendResult = commandQueue->sendMessage(iter.value->first, - &command); - } - if (sendResult == RETURN_OK) { - verificationReporter.sendSuccessReport(tc_verification::START_SUCCESS, - storedPacket->getPacketBase()); - acceptPacket(tc_verification::COMPLETION_SUCCESS, storedPacket); - checkAndExecuteFifo(iter); - } else { - command.clearCommandMessage(); - rejectPacket(tc_verification::START_FAILURE, storedPacket, sendResult); - checkAndExecuteFifo(iter); - } - break; - default: - rejectPacket(tc_verification::START_FAILURE, storedPacket, result); - checkAndExecuteFifo(iter); - break; - } + switch (result) { + case RETURN_OK: + if (command.getCommand() != CommandMessage::CMD_NONE) { + sendResult = commandQueue->sendMessage(iter.value->first, + &command); + } + if (sendResult == RETURN_OK) { + Clock::getUptime(&iter->second.uptimeOfStart); + iter->second.step = 0; + iter->second.subservice = storedPacket->getSubService(); + iter->second.command = command.getCommand(); + iter->second.tcInfo.ackFlags = storedPacket->getAcknowledgeFlags(); + iter->second.tcInfo.tcPacketId = storedPacket->getPacketId(); + iter->second.tcInfo.tcSequenceControl = + storedPacket->getPacketSequenceControl(); + acceptPacket(tc_verification::START_SUCCESS, storedPacket); + } else { + command.clearCommandMessage(); + rejectPacket(tc_verification::START_FAILURE, storedPacket, sendResult); + checkAndExecuteFifo(iter); + } + break; + case EXECUTION_COMPLETE: + if (command.getCommand() != CommandMessage::CMD_NONE) { + //Fire-and-forget command. + sendResult = commandQueue->sendMessage(iter.value->first, + &command); + } + if (sendResult == RETURN_OK) { + verificationReporter.sendSuccessReport(tc_verification::START_SUCCESS, + storedPacket->getPacketBase()); + acceptPacket(tc_verification::COMPLETION_SUCCESS, storedPacket); + checkAndExecuteFifo(iter); + } else { + command.clearCommandMessage(); + rejectPacket(tc_verification::START_FAILURE, storedPacket, sendResult); + checkAndExecuteFifo(iter); + } + break; + default: + rejectPacket(tc_verification::START_FAILURE, storedPacket, result); + checkAndExecuteFifo(iter); + break; + } } void CommandingServiceBase::rejectPacket(uint8_t reportId, - TcPacketStoredBase* packet, ReturnValue_t errorCode) { - verificationReporter.sendFailureReport(reportId, packet->getPacketBase(), errorCode); - packet->deletePacket(); + TcPacketStoredPus* packet, ReturnValue_t errorCode) { + verificationReporter.sendFailureReport(reportId, dynamic_cast(packet), + errorCode); + packet->deletePacket(); } void CommandingServiceBase::acceptPacket(uint8_t reportId, - TcPacketStoredBase* packet) { - verificationReporter.sendSuccessReport(reportId, packet->getPacketBase()); - packet->deletePacket(); + TcPacketStoredPus* packet) { + verificationReporter.sendSuccessReport(reportId, dynamic_cast(packet)); + packet->deletePacket(); } void CommandingServiceBase::checkAndExecuteFifo(CommandMapIter& iter) { - store_address_t address; - if (iter->second.fifo.retrieve(&address) != RETURN_OK) { - commandMap.erase(&iter); - } else { - TcPacketStoredPus newPacket(address); - startExecution(&newPacket, iter); - } + store_address_t address; + if (iter->second.fifo.retrieve(&address) != RETURN_OK) { + commandMap.erase(&iter); + } else { + TcPacketStoredPus newPacket(address); + startExecution(&newPacket, iter); + } } void CommandingServiceBase::handleUnrequestedReply(CommandMessage* reply) { - reply->clearCommandMessage(); + reply->clearCommandMessage(); } @@ -447,22 +448,22 @@ inline void CommandingServiceBase::doPeriodicOperation() { } MessageQueueId_t CommandingServiceBase::getCommandQueue() { - return commandQueue->getId(); + return commandQueue->getId(); } void CommandingServiceBase::checkTimeout() { - uint32_t uptime; - Clock::getUptime(&uptime); - CommandMapIter iter; - for (iter = commandMap.begin(); iter != commandMap.end(); ++iter) { - if ((iter->second.uptimeOfStart + (timeoutSeconds * 1000)) < uptime) { - verificationReporter.sendFailureReport( - tc_verification::COMPLETION_FAILURE, iter->second.tcInfo.ackFlags, - iter->second.tcInfo.tcPacketId, iter->second.tcInfo.tcSequenceControl, - TIMEOUT); - checkAndExecuteFifo(iter); - } - } + uint32_t uptime; + Clock::getUptime(&uptime); + CommandMapIter iter; + for (iter = commandMap.begin(); iter != commandMap.end(); ++iter) { + if ((iter->second.uptimeOfStart + (timeoutSeconds * 1000)) < uptime) { + verificationReporter.sendFailureReport( + tc_verification::COMPLETION_FAILURE, iter->second.tcInfo.ackFlags, + iter->second.tcInfo.tcPacketId, iter->second.tcInfo.tcSequenceControl, + TIMEOUT); + checkAndExecuteFifo(iter); + } + } } void CommandingServiceBase::setTaskIF(PeriodicTaskIF* task_) { diff --git a/src/fsfw/tmtcservices/CommandingServiceBase.h b/src/fsfw/tmtcservices/CommandingServiceBase.h index b6709693e..d9b1b5eff 100644 --- a/src/fsfw/tmtcservices/CommandingServiceBase.h +++ b/src/fsfw/tmtcservices/CommandingServiceBase.h @@ -14,8 +14,8 @@ #include "fsfw/container/FIFO.h" #include "fsfw/serialize/SerializeIF.h" -class TcPacketStored; class TcPacketStoredBase; +class TcPacketStoredPus; namespace Factory{ void setStaticFrameworkObjectIds(); @@ -36,333 +36,333 @@ void setStaticFrameworkObjectIds(); * @ingroup pus_services */ class CommandingServiceBase: public SystemObject, - public AcceptsTelecommandsIF, - public ExecutableObjectIF, - public HasReturnvaluesIF { - friend void (Factory::setStaticFrameworkObjectIds)(); +public AcceptsTelecommandsIF, +public ExecutableObjectIF, +public HasReturnvaluesIF { + friend void (Factory::setStaticFrameworkObjectIds)(); public: - // We could make this configurable via preprocessor and the FSFWConfig file. - static constexpr uint8_t COMMAND_INFO_FIFO_DEPTH = - fsfwconfig::FSFW_CSB_FIFO_DEPTH; + // We could make this configurable via preprocessor and the FSFWConfig file. + static constexpr uint8_t COMMAND_INFO_FIFO_DEPTH = + fsfwconfig::FSFW_CSB_FIFO_DEPTH; - static const uint8_t INTERFACE_ID = CLASS_ID::COMMAND_SERVICE_BASE; + static const uint8_t INTERFACE_ID = CLASS_ID::COMMAND_SERVICE_BASE; - static const ReturnValue_t EXECUTION_COMPLETE = MAKE_RETURN_CODE(1); - static const ReturnValue_t NO_STEP_MESSAGE = MAKE_RETURN_CODE(2); - static const ReturnValue_t OBJECT_BUSY = MAKE_RETURN_CODE(3); - static const ReturnValue_t BUSY = MAKE_RETURN_CODE(4); - static const ReturnValue_t INVALID_TC = MAKE_RETURN_CODE(5); - static const ReturnValue_t INVALID_OBJECT = MAKE_RETURN_CODE(6); - static const ReturnValue_t INVALID_REPLY = MAKE_RETURN_CODE(7); + static const ReturnValue_t EXECUTION_COMPLETE = MAKE_RETURN_CODE(1); + static const ReturnValue_t NO_STEP_MESSAGE = MAKE_RETURN_CODE(2); + static const ReturnValue_t OBJECT_BUSY = MAKE_RETURN_CODE(3); + static const ReturnValue_t BUSY = MAKE_RETURN_CODE(4); + static const ReturnValue_t INVALID_TC = MAKE_RETURN_CODE(5); + static const ReturnValue_t INVALID_OBJECT = MAKE_RETURN_CODE(6); + static const ReturnValue_t INVALID_REPLY = MAKE_RETURN_CODE(7); - /** - * Class constructor. Initializes two important MessageQueues: - * commandQueue for command reception and requestQueue for device reception - * @param setObjectId - * @param apid - * @param service - * @param numberOfParallelCommands - * @param commandTimeout_seconds - * @param setPacketSource - * @param setPacketDestination - * @param queueDepth - */ - CommandingServiceBase(object_id_t setObjectId, uint16_t apid, - uint8_t service, uint8_t numberOfParallelCommands, - uint16_t commandTimeoutSeconds, size_t queueDepth = 20); - virtual ~CommandingServiceBase(); + /** + * Class constructor. Initializes two important MessageQueues: + * commandQueue for command reception and requestQueue for device reception + * @param setObjectId + * @param apid + * @param service + * @param numberOfParallelCommands + * @param commandTimeout_seconds + * @param setPacketSource + * @param setPacketDestination + * @param queueDepth + */ + CommandingServiceBase(object_id_t setObjectId, uint16_t apid, + uint8_t service, uint8_t numberOfParallelCommands, + uint16_t commandTimeoutSeconds, size_t queueDepth = 20); + virtual ~CommandingServiceBase(); - /** - * This setter can be used to set the packet source individually instead - * of using the default static framework ID set in the factory. - * This should be called at object initialization and not during run-time! - * @param packetSource - */ - void setPacketSource(object_id_t packetSource); - /** - * This setter can be used to set the packet destination individually - * instead of using the default static framework ID set in the factory. - * This should be called at object initialization and not during run-time! - * @param packetDestination - */ - void setPacketDestination(object_id_t packetDestination); + /** + * This setter can be used to set the packet source individually instead + * of using the default static framework ID set in the factory. + * This should be called at object initialization and not during run-time! + * @param packetSource + */ + void setPacketSource(object_id_t packetSource); + /** + * This setter can be used to set the packet destination individually + * instead of using the default static framework ID set in the factory. + * This should be called at object initialization and not during run-time! + * @param packetDestination + */ + void setPacketDestination(object_id_t packetDestination); - /*** - * This is the periodically called function. - * Handle request queue for external commands. - * Handle command Queue for internal commands. - * @param opCode is unused here at the moment - * @return RETURN_OK - */ - virtual ReturnValue_t performOperation(uint8_t opCode) override; + /*** + * This is the periodically called function. + * Handle request queue for external commands. + * Handle command Queue for internal commands. + * @param opCode is unused here at the moment + * @return RETURN_OK + */ + virtual ReturnValue_t performOperation(uint8_t opCode) override; - virtual uint16_t getIdentifier(); + virtual uint16_t getIdentifier(); - /** - * Returns the requestQueue MessageQueueId_t - * - * The requestQueue is the queue for external commands (TC) - * - * @return requestQueue messageQueueId_t - */ - virtual MessageQueueId_t getRequestQueue(); + /** + * Returns the requestQueue MessageQueueId_t + * + * The requestQueue is the queue for external commands (TC) + * + * @return requestQueue messageQueueId_t + */ + virtual MessageQueueId_t getRequestQueue(); - /** - * Returns the commandQueue MessageQueueId_t - * - * Remember the CommandQueue is the queue for internal communication - * @return commandQueue messageQueueId_t - */ - virtual MessageQueueId_t getCommandQueue(); + /** + * Returns the commandQueue MessageQueueId_t + * + * Remember the CommandQueue is the queue for internal communication + * @return commandQueue messageQueueId_t + */ + virtual MessageQueueId_t getCommandQueue(); - virtual ReturnValue_t initialize() override; + virtual ReturnValue_t initialize() override; - /** - * Implementation of ExecutableObjectIF function - * - * Used to setup the reference of the task, that executes this component - * @param task Pointer to the taskIF of this task - */ - virtual void setTaskIF(PeriodicTaskIF* task) override; + /** + * Implementation of ExecutableObjectIF function + * + * Used to setup the reference of the task, that executes this component + * @param task Pointer to the taskIF of this task + */ + virtual void setTaskIF(PeriodicTaskIF* task) override; protected: - /** - * Check the target subservice - * @param subservice[in] - * @return - * -@c RETURN_OK Subservice valid, continue message handling + /** + * Check the target subservice + * @param subservice[in] + * @return + * -@c RETURN_OK Subservice valid, continue message handling * -@c INVALID_SUBSERVICE if service is not known, rejects packet. - */ - virtual ReturnValue_t isValidSubservice(uint8_t subservice) = 0; + */ + virtual ReturnValue_t isValidSubservice(uint8_t subservice) = 0; - /** - * Once a TC Request is valid, the existence of the destination and its - * target interface is checked and retrieved. The target message queue ID - * can then be acquired by using the target interface. - * @param subservice - * @param tcData Application Data of TC Packet - * @param tcDataLen - * @param id MessageQueue ID is stored here - * @param objectId Object ID is extracted and stored here - * @return - * - @c RETURN_OK Cotinue message handling - * - @c RETURN_FAILED Reject the packet and generates a start failure - * verification - */ - virtual ReturnValue_t getMessageQueueAndObject(uint8_t subservice, - const uint8_t *tcData, size_t tcDataLen, MessageQueueId_t *id, - object_id_t *objectId) = 0; + /** + * Once a TC Request is valid, the existence of the destination and its + * target interface is checked and retrieved. The target message queue ID + * can then be acquired by using the target interface. + * @param subservice + * @param tcData Application Data of TC Packet + * @param tcDataLen + * @param id MessageQueue ID is stored here + * @param objectId Object ID is extracted and stored here + * @return + * - @c RETURN_OK Cotinue message handling + * - @c RETURN_FAILED Reject the packet and generates a start failure + * verification + */ + virtual ReturnValue_t getMessageQueueAndObject(uint8_t subservice, + const uint8_t *tcData, size_t tcDataLen, MessageQueueId_t *id, + object_id_t *objectId) = 0; - /** - * After the Message Queue and Object ID are determined, the command is - * prepared by using an implementation specific CommandMessage type - * which is sent to the target object. It contains all necessary information - * for the device to execute telecommands. - * @param message [out] message which can be set and is sent to the object - * @param subservice Subservice of the current communication - * @param tcData Application data of command - * @param tcDataLen Application data length - * @param state [out/in] Setable state of the communication. - * communication - * @param objectId Target object ID - * @return - * - @c RETURN_OK to generate a verification start message - * - @c EXECUTION_COMPELTE Fire-and-forget command. Generate a completion - * verification message. - * - @c Anything else rejects the packets and generates a start failure - * verification. - */ - virtual ReturnValue_t prepareCommand(CommandMessage* message, - uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, - uint32_t *state, object_id_t objectId) = 0; + /** + * After the Message Queue and Object ID are determined, the command is + * prepared by using an implementation specific CommandMessage type + * which is sent to the target object. It contains all necessary information + * for the device to execute telecommands. + * @param message [out] message which can be set and is sent to the object + * @param subservice Subservice of the current communication + * @param tcData Application data of command + * @param tcDataLen Application data length + * @param state [out/in] Setable state of the communication. + * communication + * @param objectId Target object ID + * @return + * - @c RETURN_OK to generate a verification start message + * - @c EXECUTION_COMPELTE Fire-and-forget command. Generate a completion + * verification message. + * - @c Anything else rejects the packets and generates a start failure + * verification. + */ + virtual ReturnValue_t prepareCommand(CommandMessage* message, + uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, + uint32_t *state, object_id_t objectId) = 0; - /** - * This function is implemented by child services to specify how replies - * to a command from another software component are handled. - * @param reply - * This is the reply in form of a generic read-only command message. - * @param previousCommand - * Command_t of related command - * @param state [out/in] - * Additional parameter which can be used to pass state information. - * State of the communication - * @param optionalNextCommand [out] - * An optional next command which can be set in this function - * @param objectId Source object ID - * @param isStep Flag value to mark steps of command execution - * @return - * - @c RETURN_OK, @c EXECUTION_COMPLETE or @c NO_STEP_MESSAGE to - * generate TC verification success - * - @c INVALID_REPLY Calls handleUnrequestedReply - * - Anything else triggers a TC verification failure. If RETURN_FAILED or - * INVALID_REPLY is returned and the command ID is - * CommandMessage::REPLY_REJECTED, a failure verification message with - * the reason as the error parameter and the initial command as - * failure parameter 1 is generated. - */ - virtual ReturnValue_t handleReply(const CommandMessage* reply, - Command_t previousCommand, uint32_t *state, - CommandMessage* optionalNextCommand, object_id_t objectId, - bool *isStep) = 0; + /** + * This function is implemented by child services to specify how replies + * to a command from another software component are handled. + * @param reply + * This is the reply in form of a generic read-only command message. + * @param previousCommand + * Command_t of related command + * @param state [out/in] + * Additional parameter which can be used to pass state information. + * State of the communication + * @param optionalNextCommand [out] + * An optional next command which can be set in this function + * @param objectId Source object ID + * @param isStep Flag value to mark steps of command execution + * @return + * - @c RETURN_OK, @c EXECUTION_COMPLETE or @c NO_STEP_MESSAGE to + * generate TC verification success + * - @c INVALID_REPLY Calls handleUnrequestedReply + * - Anything else triggers a TC verification failure. If RETURN_FAILED or + * INVALID_REPLY is returned and the command ID is + * CommandMessage::REPLY_REJECTED, a failure verification message with + * the reason as the error parameter and the initial command as + * failure parameter 1 is generated. + */ + virtual ReturnValue_t handleReply(const CommandMessage* reply, + Command_t previousCommand, uint32_t *state, + CommandMessage* optionalNextCommand, object_id_t objectId, + bool *isStep) = 0; - /** - * This function can be overidden to handle unrequested reply, - * when the reply sender ID is unknown or is not found is the command map. - * The default implementation will clear the command message and all - * its contents. - * @param reply - * Reply which is non-const so the default implementation can clear the - * message. - */ - virtual void handleUnrequestedReply(CommandMessage* reply); + /** + * This function can be overidden to handle unrequested reply, + * when the reply sender ID is unknown or is not found is the command map. + * The default implementation will clear the command message and all + * its contents. + * @param reply + * Reply which is non-const so the default implementation can clear the + * message. + */ + virtual void handleUnrequestedReply(CommandMessage* reply); - virtual void doPeriodicOperation(); + virtual void doPeriodicOperation(); - struct CommandInfo: public SerializeIF{ - struct tcInfo { - uint8_t ackFlags; - uint16_t tcPacketId; - uint16_t tcSequenceControl; - } tcInfo; - uint32_t uptimeOfStart; - uint8_t step; - uint8_t subservice; - uint32_t state; - Command_t command; - object_id_t objectId; - FIFO fifo; + struct CommandInfo: public SerializeIF{ + struct tcInfo { + uint8_t ackFlags; + uint16_t tcPacketId; + uint16_t tcSequenceControl; + } tcInfo; + uint32_t uptimeOfStart; + uint8_t step; + uint8_t subservice; + uint32_t state; + Command_t command; + object_id_t objectId; + FIFO fifo; - virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, - size_t maxSize, Endianness streamEndianness) const override{ - return HasReturnvaluesIF::RETURN_FAILED; - }; + virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, + size_t maxSize, Endianness streamEndianness) const override{ + return HasReturnvaluesIF::RETURN_FAILED; + }; - virtual size_t getSerializedSize() const override { - return 0; - }; + virtual size_t getSerializedSize() const override { + return 0; + }; - virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, - Endianness streamEndianness) override { - return HasReturnvaluesIF::RETURN_FAILED; - }; - }; + virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, + Endianness streamEndianness) override { + return HasReturnvaluesIF::RETURN_FAILED; + }; + }; - using CommandMapIter = FixedMap::Iterator; + using CommandMapIter = FixedMap::Iterator; - const uint16_t apid; + const uint16_t apid; - const uint8_t service; + const uint8_t service; - const uint16_t timeoutSeconds; + const uint16_t timeoutSeconds; - uint8_t tmPacketCounter = 0; + uint8_t tmPacketCounter = 0; - StorageManagerIF *IPCStore = nullptr; + StorageManagerIF *IPCStore = nullptr; - StorageManagerIF *TCStore = nullptr; + StorageManagerIF *TCStore = nullptr; - MessageQueueIF* commandQueue = nullptr; + MessageQueueIF* commandQueue = nullptr; - MessageQueueIF* requestQueue = nullptr; + MessageQueueIF* requestQueue = nullptr; - VerificationReporter verificationReporter; + VerificationReporter verificationReporter; - FixedMap commandMap; + FixedMap commandMap; - /* May be set be children to return a more precise failure condition. */ - uint32_t failureParameter1 = 0; - uint32_t failureParameter2 = 0; + /* May be set be children to return a more precise failure condition. */ + uint32_t failureParameter1 = 0; + uint32_t failureParameter2 = 0; - static object_id_t defaultPacketSource; - object_id_t packetSource = objects::NO_OBJECT; - static object_id_t defaultPacketDestination; - object_id_t packetDestination = objects::NO_OBJECT; + static object_id_t defaultPacketSource; + object_id_t packetSource = objects::NO_OBJECT; + static object_id_t defaultPacketDestination; + object_id_t packetDestination = objects::NO_OBJECT; - /** - * Pointer to the task which executes this component, - * is invalid before setTaskIF was called. - */ - PeriodicTaskIF* executingTask = nullptr; + /** + * Pointer to the task which executes this component, + * is invalid before setTaskIF was called. + */ + PeriodicTaskIF* executingTask = nullptr; - /** - * @brief Send TM data from pointer to data. - * If a header is supplied it is added before data - * @param subservice Number of subservice - * @param data Pointer to the data in the Packet - * @param dataLen Lenght of data in the Packet - * @param headerData HeaderData will be placed before data - * @param headerSize Size of HeaderData - */ - ReturnValue_t sendTmPacket(uint8_t subservice, const uint8_t *data, - size_t dataLen, const uint8_t* headerData = nullptr, - size_t headerSize = 0); + /** + * @brief Send TM data from pointer to data. + * If a header is supplied it is added before data + * @param subservice Number of subservice + * @param data Pointer to the data in the Packet + * @param dataLen Lenght of data in the Packet + * @param headerData HeaderData will be placed before data + * @param headerSize Size of HeaderData + */ + ReturnValue_t sendTmPacket(uint8_t subservice, const uint8_t *data, + size_t dataLen, const uint8_t* headerData = nullptr, + size_t headerSize = 0); - /** - * @brief To send TM packets of objects that still need to be serialized - * and consist of an object ID with appended data. - * @param subservice Number of subservice - * @param objectId ObjectId is placed before data - * @param data Data to append to the packet - * @param dataLen Length of Data - */ - ReturnValue_t sendTmPacket(uint8_t subservice, object_id_t objectId, - const uint8_t *data, size_t dataLen); + /** + * @brief To send TM packets of objects that still need to be serialized + * and consist of an object ID with appended data. + * @param subservice Number of subservice + * @param objectId ObjectId is placed before data + * @param data Data to append to the packet + * @param dataLen Length of Data + */ + ReturnValue_t sendTmPacket(uint8_t subservice, object_id_t objectId, + const uint8_t *data, size_t dataLen); - /** - * @brief To send packets which are contained inside a class implementing - * SerializeIF. - * @param subservice Number of subservice - * @param content This is a pointer to the serialized packet - * @param header Serialize IF header which will be placed before content - */ - ReturnValue_t sendTmPacket(uint8_t subservice, SerializeIF* content, - SerializeIF* header = nullptr); + /** + * @brief To send packets which are contained inside a class implementing + * SerializeIF. + * @param subservice Number of subservice + * @param content This is a pointer to the serialized packet + * @param header Serialize IF header which will be placed before content + */ + ReturnValue_t sendTmPacket(uint8_t subservice, SerializeIF* content, + SerializeIF* header = nullptr); - void checkAndExecuteFifo(CommandMapIter& iter); + void checkAndExecuteFifo(CommandMapIter& iter); -private: - /** - * This method handles internal execution of a command, - * once it has been started by @sa{startExecution()} in the request - * queue handler. - * It handles replies generated by the devices and relayed by the specific - * service implementation. This means that it determines further course of - * action depending on the return values specified in the service - * implementation. - * This includes the generation of TC verification messages. Note that - * the static framework object ID @c VerificationReporter::messageReceiver - * needs to be set. - * - TM[1,5] Step Successs - * - TM[1,6] Step Failure - * - TM[1,7] Completion Success - * - TM[1,8] Completion Failure - */ - void handleCommandQueue(); + private: + /** + * This method handles internal execution of a command, + * once it has been started by @sa{startExecution()} in the request + * queue handler. + * It handles replies generated by the devices and relayed by the specific + * service implementation. This means that it determines further course of + * action depending on the return values specified in the service + * implementation. + * This includes the generation of TC verification messages. Note that + * the static framework object ID @c VerificationReporter::messageReceiver + * needs to be set. + * - TM[1,5] Step Successs + * - TM[1,6] Step Failure + * - TM[1,7] Completion Success + * - TM[1,8] Completion Failure + */ + void handleCommandQueue(); - /** - * @brief Handler function for request queue - * @details - * Sequence of request queue handling: - * isValidSubservice -> getMessageQueueAndObject -> startExecution - * Generates a Start Success Reports TM[1,3] in subfunction - * @sa{startExecution()} or a Start Failure Report TM[1,4] by using the - * TC Verification Service. - */ - void handleRequestQueue(); + /** + * @brief Handler function for request queue + * @details + * Sequence of request queue handling: + * isValidSubservice -> getMessageQueueAndObject -> startExecution + * Generates a Start Success Reports TM[1,3] in subfunction + * @sa{startExecution()} or a Start Failure Report TM[1,4] by using the + * TC Verification Service. + */ + void handleRequestQueue(); - void rejectPacket(uint8_t reportId, TcPacketStoredBase* packet, - ReturnValue_t errorCode); + void rejectPacket(uint8_t reportId, TcPacketStoredPus* packet, + ReturnValue_t errorCode); - void acceptPacket(uint8_t reportId, TcPacketStoredBase* packet); + void acceptPacket(uint8_t reportId, TcPacketStoredPus* packet); - void startExecution(TcPacketStoredBase *storedPacket, CommandMapIter iter); + void startExecution(TcPacketStoredPus* storedPacket, CommandMapIter iter); - void handleCommandMessage(CommandMessage* reply); - void handleReplyHandlerResult(ReturnValue_t result, CommandMapIter iter, - CommandMessage* nextCommand, CommandMessage* reply, bool& isStep); + void handleCommandMessage(CommandMessage* reply); + void handleReplyHandlerResult(ReturnValue_t result, CommandMapIter iter, + CommandMessage* nextCommand, CommandMessage* reply, bool& isStep); - void checkTimeout(); + void checkTimeout(); }; #endif /* FSFW_TMTCSERVICES_COMMANDINGSERVICEBASE_H_ */ diff --git a/src/fsfw/tmtcservices/PusServiceBase.cpp b/src/fsfw/tmtcservices/PusServiceBase.cpp index 866e0844a..191acd9cc 100644 --- a/src/fsfw/tmtcservices/PusServiceBase.cpp +++ b/src/fsfw/tmtcservices/PusServiceBase.cpp @@ -12,28 +12,28 @@ object_id_t PusServiceBase::packetSource = 0; object_id_t PusServiceBase::packetDestination = 0; PusServiceBase::PusServiceBase(object_id_t setObjectId, uint16_t setApid, - uint8_t setServiceId) : - SystemObject(setObjectId), apid(setApid), serviceId(setServiceId) { - requestQueue = QueueFactory::instance()-> - createMessageQueue(PUS_SERVICE_MAX_RECEPTION); + uint8_t setServiceId): + SystemObject(setObjectId), apid(setApid), serviceId(setServiceId) { + requestQueue = QueueFactory::instance()-> + createMessageQueue(PUS_SERVICE_MAX_RECEPTION); } PusServiceBase::~PusServiceBase() { - QueueFactory::instance()->deleteMessageQueue(requestQueue); + QueueFactory::instance()->deleteMessageQueue(requestQueue); } ReturnValue_t PusServiceBase::performOperation(uint8_t opCode) { - handleRequestQueue(); - ReturnValue_t result = this->performService(); - if (result != RETURN_OK) { + handleRequestQueue(); + ReturnValue_t result = this->performService(); + if (result != RETURN_OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PusService " << (uint16_t) this->serviceId - << ": performService returned with " << (int16_t) result - << std::endl; + sif::error << "PusService " << (uint16_t) this->serviceId + << ": performService returned with " << (int16_t) result + << std::endl; #endif - return RETURN_FAILED; - } - return RETURN_OK; + return RETURN_FAILED; + } + return RETURN_OK; } void PusServiceBase::setTaskIF(PeriodicTaskIF* taskHandle) { @@ -41,88 +41,88 @@ void PusServiceBase::setTaskIF(PeriodicTaskIF* taskHandle) { } void PusServiceBase::handleRequestQueue() { - TmTcMessage message; - ReturnValue_t result = RETURN_FAILED; - for (uint8_t count = 0; count < PUS_SERVICE_MAX_RECEPTION; count++) { - ReturnValue_t status = this->requestQueue->receiveMessage(&message); -// if(status != MessageQueueIF::EMPTY) { + TmTcMessage message; + ReturnValue_t result = RETURN_FAILED; + for (uint8_t count = 0; count < PUS_SERVICE_MAX_RECEPTION; count++) { + ReturnValue_t status = this->requestQueue->receiveMessage(&message); + // if(status != MessageQueueIF::EMPTY) { #if FSFW_CPP_OSTREAM_ENABLED == 1 -// sif::debug << "PusServiceBase::performOperation: Receiving from " -// << "MQ ID: " << std::hex << "0x" << std::setw(8) -// << std::setfill('0') << this->requestQueue->getId() -// << std::dec << " returned: " << status << std::setfill(' ') -// << std::endl; + // sif::debug << "PusServiceBase::performOperation: Receiving from " + // << "MQ ID: " << std::hex << "0x" << std::setw(8) + // << std::setfill('0') << this->requestQueue->getId() + // << std::dec << " returned: " << status << std::setfill(' ') + // << std::endl; #endif -// } + // } - if (status == RETURN_OK) { - this->currentPacket.setStoreAddress(message.getStorageId()); - //info << "Service " << (uint16_t) this->serviceId << - // ": new packet!" << std::endl; + if (status == RETURN_OK) { + this->currentPacket.setStoreAddress(message.getStorageId(), ¤tPacket); + //info << "Service " << (uint16_t) this->serviceId << + // ": new packet!" << std::endl; - result = this->handleRequest(currentPacket.getSubService()); + result = this->handleRequest(currentPacket.getSubService()); - // debug << "Service " << (uint16_t)this->serviceId << - // ": handleRequest returned: " << (int)return_code << std::endl; - if (result == RETURN_OK) { - this->verifyReporter.sendSuccessReport( - tc_verification::COMPLETION_SUCCESS, &this->currentPacket); - } - else { - this->verifyReporter.sendFailureReport( - tc_verification::COMPLETION_FAILURE, &this->currentPacket, - result, 0, errorParameter1, errorParameter2); - } - this->currentPacket.deletePacket(); - errorParameter1 = 0; - errorParameter2 = 0; - } - else if (status == MessageQueueIF::EMPTY) { - status = RETURN_OK; - // debug << "PusService " << (uint16_t)this->serviceId << - // ": no new packet." << std::endl; - break; - } - else { + // debug << "Service " << (uint16_t)this->serviceId << + // ": handleRequest returned: " << (int)return_code << std::endl; + if (result == RETURN_OK) { + this->verifyReporter.sendSuccessReport( + tc_verification::COMPLETION_SUCCESS, &this->currentPacket); + } + else { + this->verifyReporter.sendFailureReport( + tc_verification::COMPLETION_FAILURE, &this->currentPacket, + result, 0, errorParameter1, errorParameter2); + } + this->currentPacket.deletePacket(); + errorParameter1 = 0; + errorParameter2 = 0; + } + else if (status == MessageQueueIF::EMPTY) { + status = RETURN_OK; + // debug << "PusService " << (uint16_t)this->serviceId << + // ": no new packet." << std::endl; + break; + } + else { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PusServiceBase::performOperation: Service " - << this->serviceId << ": Error receiving packet. Code: " - << std::hex << status << std::dec << std::endl; + sif::error << "PusServiceBase::performOperation: Service " + << this->serviceId << ": Error receiving packet. Code: " + << std::hex << status << std::dec << std::endl; #endif - } - } + } + } } uint16_t PusServiceBase::getIdentifier() { - return this->serviceId; + return this->serviceId; } MessageQueueId_t PusServiceBase::getRequestQueue() { - return this->requestQueue->getId(); + return this->requestQueue->getId(); } ReturnValue_t PusServiceBase::initialize() { - ReturnValue_t result = SystemObject::initialize(); - if (result != RETURN_OK) { - return result; - } - AcceptsTelemetryIF* destService = ObjectManager::instance()->get( - packetDestination); - PUSDistributorIF* distributor = ObjectManager::instance()->get( - packetSource); - if (destService == nullptr or distributor == nullptr) { + ReturnValue_t result = SystemObject::initialize(); + if (result != RETURN_OK) { + return result; + } + AcceptsTelemetryIF* destService = ObjectManager::instance()->get( + packetDestination); + PUSDistributorIF* distributor = ObjectManager::instance()->get( + packetSource); + if (destService == nullptr or distributor == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PusServiceBase::PusServiceBase: Service " - << this->serviceId << ": Configuration error. Make sure " - << "packetSource and packetDestination are defined correctly" - << std::endl; + sif::error << "PusServiceBase::PusServiceBase: Service " + << this->serviceId << ": Configuration error. Make sure " + << "packetSource and packetDestination are defined correctly" + << std::endl; #endif - return ObjectManagerIF::CHILD_INIT_FAILED; - } - this->requestQueue->setDefaultDestination( - destService->getReportReceptionQueue()); - distributor->registerService(this); - return HasReturnvaluesIF::RETURN_OK; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + this->requestQueue->setDefaultDestination( + destService->getReportReceptionQueue()); + distributor->registerService(this); + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t PusServiceBase::initializeAfterTaskCreation() { diff --git a/src/fsfw/tmtcservices/PusServiceBase.h b/src/fsfw/tmtcservices/PusServiceBase.h index ea4147fe8..ec3383311 100644 --- a/src/fsfw/tmtcservices/PusServiceBase.h +++ b/src/fsfw/tmtcservices/PusServiceBase.h @@ -35,126 +35,126 @@ void setStaticFrameworkObjectIds(); * @ingroup pus_services */ class PusServiceBase : public ExecutableObjectIF, - public AcceptsTelecommandsIF, - public SystemObject, - public HasReturnvaluesIF { - friend void (Factory::setStaticFrameworkObjectIds)(); +public AcceptsTelecommandsIF, +public SystemObject, +public HasReturnvaluesIF { + friend void (Factory::setStaticFrameworkObjectIds)(); public: - /** - * @brief The passed values are set, but inter-object initialization is - * done in the initialize method. - * @param setObjectId - * The system object identifier of this Service instance. - * @param setApid - * The APID the Service is instantiated for. - * @param setServiceId - * The Service Identifier as specified in ECSS PUS. - */ - PusServiceBase( object_id_t setObjectId, uint16_t setApid, - uint8_t setServiceId); - /** - * The destructor is empty. - */ - virtual ~PusServiceBase(); - /** - * @brief The handleRequest method shall handle any kind of Telecommand - * Request immediately. - * @details - * Implemetations can take the Telecommand in currentPacket and perform - * any kind of operation. - * They may send additional "Start Success (1,3)" messages with the - * verifyReporter, but Completion Success or Failure Reports are generated - * automatically after execution of this method. - * - * If a Telecommand can not be executed within one call cycle, - * this Base class is not the right parent. - * - * The child class may add additional error information by setting - * #errorParameters which aren attached to the generated verification - * message. - * - * Subservice checking should be implemented in this method. - * - * @return The returned status_code is directly taken as main error code - * in the Verification Report. - * On success, RETURN_OK shall be returned. - */ - virtual ReturnValue_t handleRequest(uint8_t subservice) = 0; - /** - * In performService, implementations can handle periodic, - * non-TC-triggered activities. - * The performService method is always called. - * @return Currently, everything other that RETURN_OK only triggers - * diagnostic output. - */ - virtual ReturnValue_t performService() = 0; - /** - * This method implements the typical activity of a simple PUS Service. - * It checks for new requests, and, if found, calls handleRequest, sends - * completion verification messages and deletes - * the TC requests afterwards. - * performService is always executed afterwards. - * @return @c RETURN_OK if the periodic performService was successful. - * @c RETURN_FAILED else. - */ - ReturnValue_t performOperation(uint8_t opCode) override; - virtual uint16_t getIdentifier() override; - MessageQueueId_t getRequestQueue() override; - virtual ReturnValue_t initialize() override; + /** + * @brief The passed values are set, but inter-object initialization is + * done in the initialize method. + * @param setObjectId + * The system object identifier of this Service instance. + * @param setApid + * The APID the Service is instantiated for. + * @param setServiceId + * The Service Identifier as specified in ECSS PUS. + */ + PusServiceBase( object_id_t setObjectId, uint16_t setApid, + uint8_t setServiceId); + /** + * The destructor is empty. + */ + virtual ~PusServiceBase(); + /** + * @brief The handleRequest method shall handle any kind of Telecommand + * Request immediately. + * @details + * Implemetations can take the Telecommand in currentPacket and perform + * any kind of operation. + * They may send additional "Start Success (1,3)" messages with the + * verifyReporter, but Completion Success or Failure Reports are generated + * automatically after execution of this method. + * + * If a Telecommand can not be executed within one call cycle, + * this Base class is not the right parent. + * + * The child class may add additional error information by setting + * #errorParameters which aren attached to the generated verification + * message. + * + * Subservice checking should be implemented in this method. + * + * @return The returned status_code is directly taken as main error code + * in the Verification Report. + * On success, RETURN_OK shall be returned. + */ + virtual ReturnValue_t handleRequest(uint8_t subservice) = 0; + /** + * In performService, implementations can handle periodic, + * non-TC-triggered activities. + * The performService method is always called. + * @return Currently, everything other that RETURN_OK only triggers + * diagnostic output. + */ + virtual ReturnValue_t performService() = 0; + /** + * This method implements the typical activity of a simple PUS Service. + * It checks for new requests, and, if found, calls handleRequest, sends + * completion verification messages and deletes + * the TC requests afterwards. + * performService is always executed afterwards. + * @return @c RETURN_OK if the periodic performService was successful. + * @c RETURN_FAILED else. + */ + ReturnValue_t performOperation(uint8_t opCode) override; + virtual uint16_t getIdentifier() override; + MessageQueueId_t getRequestQueue() override; + virtual ReturnValue_t initialize() override; - virtual void setTaskIF(PeriodicTaskIF* taskHandle) override; - virtual ReturnValue_t initializeAfterTaskCreation() override; + virtual void setTaskIF(PeriodicTaskIF* taskHandle) override; + virtual ReturnValue_t initializeAfterTaskCreation() override; protected: - /** - * @brief Handle to the underlying task - * @details - * Will be set by setTaskIF(), which is called on task creation. - */ - PeriodicTaskIF* taskHandle = nullptr; - /** - * The APID of this instance of the Service. - */ - uint16_t apid; - /** - * The Service Identifier. - */ - uint8_t serviceId; - /** - * One of two error parameters for additional error information. - */ - uint32_t errorParameter1 = 0; - /** - * One of two error parameters for additional error information. - */ - uint32_t errorParameter2 = 0; - /** - * This is a complete instance of the telecommand reception queue - * of the class. It is initialized on construction of the class. - */ - MessageQueueIF* requestQueue = nullptr; - /** - * An instance of the VerificationReporter class, that simplifies - * sending any kind of verification message to the TC Verification Service. - */ - VerificationReporter verifyReporter; - /** - * The current Telecommand to be processed. - * It is deleted after handleRequest was executed. - */ - TcPacketStoredPus currentPacket; + /** + * @brief Handle to the underlying task + * @details + * Will be set by setTaskIF(), which is called on task creation. + */ + PeriodicTaskIF* taskHandle = nullptr; + /** + * The APID of this instance of the Service. + */ + uint16_t apid; + /** + * The Service Identifier. + */ + uint8_t serviceId; + /** + * One of two error parameters for additional error information. + */ + uint32_t errorParameter1 = 0; + /** + * One of two error parameters for additional error information. + */ + uint32_t errorParameter2 = 0; + /** + * This is a complete instance of the telecommand reception queue + * of the class. It is initialized on construction of the class. + */ + MessageQueueIF* requestQueue = nullptr; + /** + * An instance of the VerificationReporter class, that simplifies + * sending any kind of verification message to the TC Verification Service. + */ + VerificationReporter verifyReporter; + /** + * The current Telecommand to be processed. + * It is deleted after handleRequest was executed. + */ + TcPacketStoredPus currentPacket; - static object_id_t packetSource; + static object_id_t packetSource; - static object_id_t packetDestination; + static object_id_t packetDestination; private: - /** - * This constant sets the maximum number of packets accepted per call. - * Remember that one packet must be completely handled in one - * #handleRequest call. - */ - static const uint8_t PUS_SERVICE_MAX_RECEPTION = 10; + /** + * This constant sets the maximum number of packets accepted per call. + * Remember that one packet must be completely handled in one + * #handleRequest call. + */ + static const uint8_t PUS_SERVICE_MAX_RECEPTION = 10; - void handleRequestQueue(); + void handleRequestQueue(); }; #endif /* FSFW_TMTCSERVICES_PUSSERVICEBASE_H_ */ diff --git a/src/fsfw/tmtcservices/PusVerificationReport.h b/src/fsfw/tmtcservices/PusVerificationReport.h index c22ba535e..bc9793d9d 100644 --- a/src/fsfw/tmtcservices/PusVerificationReport.h +++ b/src/fsfw/tmtcservices/PusVerificationReport.h @@ -4,7 +4,7 @@ #include "VerificationCodes.h" #include "fsfw/ipc/MessageQueueMessage.h" -#include "fsfw/tmtcpacket/pus/tc/TcPacketBase.h" +#include "fsfw/tmtcpacket/pus/tc/TcPacketPusBase.h" #include "fsfw/returnvalues/HasReturnvaluesIF.h" class PusVerificationMessage: public MessageQueueMessage { diff --git a/src/fsfw/tmtcservices/VerificationReporter.cpp b/src/fsfw/tmtcservices/VerificationReporter.cpp index 2b371d1e7..b885cccf2 100644 --- a/src/fsfw/tmtcservices/VerificationReporter.cpp +++ b/src/fsfw/tmtcservices/VerificationReporter.cpp @@ -17,7 +17,7 @@ VerificationReporter::VerificationReporter() : VerificationReporter::~VerificationReporter() {} void VerificationReporter::sendSuccessReport(uint8_t set_report_id, - TcPacketBase* currentPacket, uint8_t set_step) { + TcPacketPusBase* currentPacket, uint8_t set_step) { if (acknowledgeQueue == MessageQueueIF::NO_QUEUE) { this->initialize(); } @@ -59,7 +59,7 @@ void VerificationReporter::sendSuccessReport(uint8_t set_report_id, } void VerificationReporter::sendFailureReport(uint8_t report_id, - TcPacketBase* currentPacket, ReturnValue_t error_code, uint8_t step, + TcPacketPusBase* currentPacket, ReturnValue_t error_code, uint8_t step, uint32_t parameter1, uint32_t parameter2) { if (acknowledgeQueue == MessageQueueIF::NO_QUEUE) { this->initialize(); diff --git a/src/fsfw/tmtcservices/VerificationReporter.h b/src/fsfw/tmtcservices/VerificationReporter.h index 4a64d3df1..d57cc791e 100644 --- a/src/fsfw/tmtcservices/VerificationReporter.h +++ b/src/fsfw/tmtcservices/VerificationReporter.h @@ -25,13 +25,13 @@ public: VerificationReporter(); virtual ~VerificationReporter(); - void sendSuccessReport( uint8_t set_report_id, TcPacketBase* current_packet, + void sendSuccessReport( uint8_t set_report_id, TcPacketPusBase* current_packet, uint8_t set_step = 0 ); void sendSuccessReport(uint8_t set_report_id, uint8_t ackFlags, uint16_t tcPacketId, uint16_t tcSequenceControl, uint8_t set_step = 0); - void sendFailureReport( uint8_t report_id, TcPacketBase* current_packet, + void sendFailureReport( uint8_t report_id, TcPacketPusBase* current_packet, ReturnValue_t error_code = 0, uint8_t step = 0, uint32_t parameter1 = 0, uint32_t parameter2 = 0 );