fsfw/src/fsfw/action/CommandActionHelper.cpp

113 lines
4.1 KiB
C++
Raw Normal View History

2021-07-13 20:22:54 +02:00
#include "fsfw/action.h"
#include "fsfw/objectmanager/ObjectManager.h"
2022-02-02 10:29:30 +01:00
CommandActionHelper::CommandActionHelper(CommandsActionsIF *setOwner)
2022-07-04 11:44:26 +02:00
: owner(setOwner), queueToUse(nullptr), ipcStore(nullptr), commandCount(0), lastTarget(0) {}
2022-07-04 11:44:26 +02:00
CommandActionHelper::~CommandActionHelper() = default;
2022-02-02 10:29:30 +01:00
ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo, ActionId_t actionId,
SerializeIF *data) {
2022-07-04 11:44:26 +02:00
auto *receiver = ObjectManager::instance()->get<HasActionsIF>(commandTo);
if (receiver == nullptr) {
2022-02-02 10:29:30 +01:00
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
}
store_address_t storeId;
uint8_t *storePointer;
size_t maxSize = data->getSerializedSize();
ReturnValue_t result = ipcStore->getFreeElement(&storeId, maxSize, &storePointer);
2022-08-16 01:08:26 +02:00
if (result != returnvalue::OK) {
2022-02-02 10:29:30 +01:00
return result;
}
size_t size = 0;
result = data->serialize(&storePointer, &size, maxSize, SerializeIF::Endianness::BIG);
2022-08-16 01:08:26 +02:00
if (result != returnvalue::OK) {
2022-02-02 10:29:30 +01:00
return result;
}
return sendCommand(receiver->getCommandQueue(), actionId, storeId);
}
2022-02-02 10:29:30 +01:00
ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo, ActionId_t actionId,
const uint8_t *data, uint32_t size) {
2022-07-04 11:44:26 +02:00
auto *receiver = ObjectManager::instance()->get<HasActionsIF>(commandTo);
if (receiver == nullptr) {
2022-02-02 10:29:30 +01:00
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
}
store_address_t storeId;
ReturnValue_t result = ipcStore->addData(&storeId, data, size);
2022-08-16 01:08:26 +02:00
if (result != returnvalue::OK) {
2022-02-02 10:29:30 +01:00
return result;
}
return sendCommand(receiver->getCommandQueue(), actionId, storeId);
}
2022-02-02 10:29:30 +01:00
ReturnValue_t CommandActionHelper::sendCommand(MessageQueueId_t queueId, ActionId_t actionId,
store_address_t storeId) {
CommandMessage command;
ActionMessage::setCommand(&command, actionId, storeId);
ReturnValue_t result = queueToUse->sendMessage(queueId, &command);
2022-08-16 01:08:26 +02:00
if (result != returnvalue::OK) {
2022-02-02 10:29:30 +01:00
ipcStore->deleteData(storeId);
}
lastTarget = queueId;
commandCount++;
return result;
}
ReturnValue_t CommandActionHelper::initialize() {
2022-02-02 10:29:30 +01:00
ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
2022-07-04 11:44:26 +02:00
if (ipcStore == nullptr) {
2022-08-16 01:08:26 +02:00
return returnvalue::FAILED;
2022-02-02 10:29:30 +01:00
}
2018-07-13 18:28:26 +02:00
2022-02-02 10:29:30 +01:00
queueToUse = owner->getCommandQueuePtr();
2022-07-04 11:44:26 +02:00
if (queueToUse == nullptr) {
2022-08-16 01:08:26 +02:00
return returnvalue::FAILED;
2022-02-02 10:29:30 +01:00
}
2022-08-16 01:08:26 +02:00
return returnvalue::OK;
}
ReturnValue_t CommandActionHelper::handleReply(CommandMessage *reply) {
2022-02-02 10:29:30 +01:00
if (reply->getSender() != lastTarget) {
2022-08-16 01:08:26 +02:00
return returnvalue::FAILED;
2022-02-02 10:29:30 +01:00
}
switch (reply->getCommand()) {
case ActionMessage::COMPLETION_SUCCESS:
2022-02-02 10:29:30 +01:00
commandCount--;
owner->completionSuccessfulReceived(ActionMessage::getActionId(reply));
2022-08-16 01:08:26 +02:00
return returnvalue::OK;
case ActionMessage::COMPLETION_FAILED:
2022-02-02 10:29:30 +01:00
commandCount--;
owner->completionFailedReceived(ActionMessage::getActionId(reply),
ActionMessage::getReturnCode(reply));
2022-08-16 01:08:26 +02:00
return returnvalue::OK;
case ActionMessage::STEP_SUCCESS:
2022-02-02 10:29:30 +01:00
owner->stepSuccessfulReceived(ActionMessage::getActionId(reply),
ActionMessage::getStep(reply));
2022-08-16 01:08:26 +02:00
return returnvalue::OK;
case ActionMessage::STEP_FAILED:
2022-02-02 10:29:30 +01:00
commandCount--;
owner->stepFailedReceived(ActionMessage::getActionId(reply), ActionMessage::getStep(reply),
ActionMessage::getReturnCode(reply));
2022-08-16 01:08:26 +02:00
return returnvalue::OK;
case ActionMessage::DATA_REPLY:
2022-02-02 10:29:30 +01:00
extractDataForOwner(ActionMessage::getActionId(reply), ActionMessage::getStoreId(reply));
2022-08-16 01:08:26 +02:00
return returnvalue::OK;
default:
2022-08-16 01:08:26 +02:00
return returnvalue::FAILED;
2022-02-02 10:29:30 +01:00
}
}
2022-02-02 10:29:30 +01:00
uint8_t CommandActionHelper::getCommandCount() const { return commandCount; }
void CommandActionHelper::extractDataForOwner(ActionId_t actionId, store_address_t storeId) {
2022-07-04 11:44:26 +02:00
const uint8_t *data = nullptr;
2022-02-02 10:29:30 +01:00
size_t size = 0;
ReturnValue_t result = ipcStore->getData(storeId, &data, &size);
2022-08-16 01:08:26 +02:00
if (result != returnvalue::OK) {
2022-02-02 10:29:30 +01:00
return;
}
owner->dataReceived(actionId, data, size);
ipcStore->deleteData(storeId);
}