#include <framework/action/ActionHelper.h> #include <framework/action/HasActionsIF.h> #include <framework/objectmanager/ObjectManagerIF.h> ActionHelper::ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue) : owner(setOwner), queueToUse(useThisQueue), ipcStore( NULL) { } ActionHelper::~ActionHelper() { } ReturnValue_t ActionHelper::handleActionMessage(CommandMessage* command) { if (command->getCommand() == ActionMessage::EXECUTE_ACTION) { ActionId_t currentAction = ActionMessage::getActionId(command); prepareExecution(command->getSender(), currentAction, ActionMessage::getStoreId(command)); return HasReturnvaluesIF::RETURN_OK; } else { return CommandMessage::UNKNOW_COMMAND; } } ReturnValue_t ActionHelper::initialize(MessageQueueIF* queueToUse_) { ipcStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE); if (ipcStore == NULL) { return HasReturnvaluesIF::RETURN_FAILED; } setQueueToUse(queueToUse_); return HasReturnvaluesIF::RETURN_OK; } void ActionHelper::step(uint8_t step, MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result) { CommandMessage reply; ActionMessage::setStepReply(&reply, commandId, step + STEP_OFFSET, result); queueToUse->sendMessage(reportTo, &reply); } void ActionHelper::finish(MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result) { CommandMessage reply; ActionMessage::setCompletionReply(&reply, commandId, result); queueToUse->sendMessage(reportTo, &reply); } void ActionHelper::setQueueToUse(MessageQueueIF* queue) { queueToUse = queue; } void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId, store_address_t dataAddress) { const uint8_t* dataPtr = NULL; uint32_t size = 0; ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size); if (result != HasReturnvaluesIF::RETURN_OK) { CommandMessage reply; ActionMessage::setStepReply(&reply, actionId, 0, result); queueToUse->sendMessage(commandedBy, &reply); return; } result = owner->executeAction(actionId, commandedBy, dataPtr, size); ipcStore->deleteData(dataAddress); if (result != HasReturnvaluesIF::RETURN_OK) { CommandMessage reply; ActionMessage::setStepReply(&reply, actionId, 0, result); queueToUse->sendMessage(commandedBy, &reply); return; } } ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, ActionId_t replyId, SerializeIF* data, bool hideSender) { CommandMessage reply; store_address_t storeAddress; uint8_t *dataPtr; uint32_t maxSize = data->getSerializedSize(); if (maxSize == 0) { //No error, there's simply nothing to report. return HasReturnvaluesIF::RETURN_OK; } uint32_t size = 0; ReturnValue_t result = ipcStore->getFreeElement(&storeAddress, maxSize, &dataPtr); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } result = data->serialize(&dataPtr, &size, maxSize, true); if (result != HasReturnvaluesIF::RETURN_OK) { ipcStore->deleteData(storeAddress); return result; } //We don't need to report the objectId, as we receive REQUESTED data before the completion success message. //True aperiodic replies need to be reported with another dedicated message. ActionMessage::setDataReply(&reply, replyId, storeAddress); //TODO Service Implementation sucks at the moment if (hideSender){ result = MessageQueueSenderIF::sendMessage(reportTo, &reply); } else { result = queueToUse->sendMessage(reportTo, &reply); } if ( result != HasReturnvaluesIF::RETURN_OK){ ipcStore->deleteData(storeAddress); } return result; } void ActionHelper::resetHelper() { }