2016-06-15 23:48:41 +02:00
|
|
|
#include <framework/datapool/DataPool.h>
|
|
|
|
#include <framework/datapool/DataPoolAdmin.h>
|
|
|
|
#include <framework/datapool/DataSet.h>
|
|
|
|
#include <framework/datapool/PoolRawAccess.h>
|
|
|
|
#include <framework/ipc/CommandMessage.h>
|
2018-07-12 16:29:32 +02:00
|
|
|
#include <framework/ipc/QueueFactory.h>
|
|
|
|
#include <framework/parameters/ParameterMessage.h>
|
2016-06-15 23:48:41 +02:00
|
|
|
|
2018-07-12 16:29:32 +02:00
|
|
|
DataPoolAdmin::DataPoolAdmin(object_id_t objectId) :
|
|
|
|
SystemObject(objectId), storage(NULL), commandQueue(NULL), memoryHelper(
|
2018-07-13 18:28:26 +02:00
|
|
|
this, NULL), actionHelper(this, NULL) {
|
2018-07-12 16:29:32 +02:00
|
|
|
commandQueue = QueueFactory::instance()->createMessageQueue();
|
|
|
|
}
|
2016-06-15 23:48:41 +02:00
|
|
|
|
2018-07-12 16:29:32 +02:00
|
|
|
DataPoolAdmin::~DataPoolAdmin() {
|
|
|
|
QueueFactory::instance()->deleteMessageQueue(commandQueue);
|
2016-06-15 23:48:41 +02:00
|
|
|
}
|
|
|
|
|
2018-07-12 16:29:32 +02:00
|
|
|
ReturnValue_t DataPoolAdmin::performOperation(uint8_t opCode) {
|
2016-06-15 23:48:41 +02:00
|
|
|
handleCommand();
|
|
|
|
return RETURN_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
MessageQueueId_t DataPoolAdmin::getCommandQueue() const {
|
2018-07-12 16:29:32 +02:00
|
|
|
return commandQueue->getId();
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t DataPoolAdmin::executeAction(ActionId_t actionId,
|
2020-03-24 14:21:57 +01:00
|
|
|
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) {
|
2018-07-12 16:29:32 +02:00
|
|
|
if (actionId != SET_VALIDITY) {
|
|
|
|
return INVALID_ACTION_ID;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (size != 5) {
|
|
|
|
return INVALID_PARAMETERS;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t address = (data[0] << 24) | (data[1] << 16) | (data[2] << 8)
|
|
|
|
| data[3];
|
|
|
|
|
|
|
|
uint8_t valid = data[4];
|
|
|
|
|
|
|
|
uint32_t poolId = ::dataPool.PIDToDataPoolId(address);
|
|
|
|
|
|
|
|
DataSet mySet;
|
|
|
|
PoolRawAccess variable(poolId, 0, &mySet, PoolVariableIF::VAR_READ_WRITE);
|
|
|
|
ReturnValue_t status = mySet.read();
|
|
|
|
if (status != RETURN_OK) {
|
|
|
|
return INVALID_ADDRESS;
|
|
|
|
}
|
|
|
|
if (valid != 0) {
|
|
|
|
variable.setValid(PoolVariableIF::VALID);
|
|
|
|
} else {
|
|
|
|
variable.setValid(PoolVariableIF::INVALID);
|
|
|
|
}
|
|
|
|
|
|
|
|
mySet.commit();
|
|
|
|
|
|
|
|
return EXECUTION_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t DataPoolAdmin::getParameter(uint8_t domainId,
|
|
|
|
uint16_t parameterId, ParameterWrapper* parameterWrapper,
|
|
|
|
const ParameterWrapper* newValues, uint16_t startAtIndex) {
|
|
|
|
return HasReturnvaluesIF::RETURN_FAILED;
|
2016-06-15 23:48:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void DataPoolAdmin::handleCommand() {
|
|
|
|
CommandMessage command;
|
2018-07-12 16:29:32 +02:00
|
|
|
ReturnValue_t result = commandQueue->receiveMessage(&command);
|
2016-06-15 23:48:41 +02:00
|
|
|
if (result != RETURN_OK) {
|
|
|
|
return;
|
|
|
|
}
|
2018-07-12 16:29:32 +02:00
|
|
|
|
|
|
|
result = actionHelper.handleActionMessage(&command);
|
|
|
|
|
|
|
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = handleParameterCommand(&command);
|
|
|
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-06-15 23:48:41 +02:00
|
|
|
result = memoryHelper.handleMemoryCommand(&command);
|
|
|
|
if (result != RETURN_OK) {
|
2018-07-12 16:29:32 +02:00
|
|
|
command.setToUnknownCommand();
|
|
|
|
commandQueue->reply(&command);
|
2016-06-15 23:48:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t DataPoolAdmin::handleMemoryLoad(uint32_t address,
|
|
|
|
const uint8_t* data, uint32_t size, uint8_t** dataPointer) {
|
2018-07-12 16:29:32 +02:00
|
|
|
uint32_t poolId = ::dataPool.PIDToDataPoolId(address);
|
|
|
|
uint8_t arrayIndex = ::dataPool.PIDToArrayIndex(address);
|
2016-06-15 23:48:41 +02:00
|
|
|
DataSet testSet;
|
2018-07-12 16:29:32 +02:00
|
|
|
PoolRawAccess varToGetSize(poolId, arrayIndex, &testSet,
|
|
|
|
PoolVariableIF::VAR_READ);
|
2016-06-15 23:48:41 +02:00
|
|
|
ReturnValue_t status = testSet.read();
|
|
|
|
if (status != RETURN_OK) {
|
|
|
|
return INVALID_ADDRESS;
|
|
|
|
}
|
|
|
|
uint8_t typeSize = varToGetSize.getSizeOfType();
|
2018-07-12 16:29:32 +02:00
|
|
|
|
|
|
|
if (size % typeSize != 0) {
|
|
|
|
return INVALID_SIZE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (size > varToGetSize.getSizeTillEnd()) {
|
2016-06-15 23:48:41 +02:00
|
|
|
return INVALID_SIZE;
|
|
|
|
}
|
|
|
|
const uint8_t* readPosition = data;
|
2018-07-12 16:29:32 +02:00
|
|
|
|
|
|
|
for (; size > 0; size -= typeSize) {
|
2016-06-15 23:48:41 +02:00
|
|
|
DataSet rawSet;
|
2018-07-12 16:29:32 +02:00
|
|
|
PoolRawAccess variable(poolId, arrayIndex, &rawSet,
|
|
|
|
PoolVariableIF::VAR_READ_WRITE);
|
2016-06-15 23:48:41 +02:00
|
|
|
status = rawSet.read();
|
|
|
|
if (status == RETURN_OK) {
|
2018-07-12 16:29:32 +02:00
|
|
|
status = variable.setEntryFromBigEndian(readPosition, typeSize);
|
2016-06-15 23:48:41 +02:00
|
|
|
if (status == RETURN_OK) {
|
2018-07-12 16:29:32 +02:00
|
|
|
status = rawSet.commit();
|
2016-06-15 23:48:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
arrayIndex += 1;
|
|
|
|
readPosition += typeSize;
|
|
|
|
}
|
|
|
|
return ACTIVITY_COMPLETED;
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t DataPoolAdmin::handleMemoryDump(uint32_t address, uint32_t size,
|
|
|
|
uint8_t** dataPointer, uint8_t* copyHere) {
|
2018-07-12 16:29:32 +02:00
|
|
|
uint32_t poolId = ::dataPool.PIDToDataPoolId(address);
|
|
|
|
uint8_t arrayIndex = ::dataPool.PIDToArrayIndex(address);
|
2016-06-15 23:48:41 +02:00
|
|
|
DataSet testSet;
|
2018-07-12 16:29:32 +02:00
|
|
|
PoolRawAccess varToGetSize(poolId, arrayIndex, &testSet,
|
|
|
|
PoolVariableIF::VAR_READ);
|
2016-06-15 23:48:41 +02:00
|
|
|
ReturnValue_t status = testSet.read();
|
|
|
|
if (status != RETURN_OK) {
|
|
|
|
return INVALID_ADDRESS;
|
|
|
|
}
|
|
|
|
uint8_t typeSize = varToGetSize.getSizeOfType();
|
2018-07-12 16:29:32 +02:00
|
|
|
if (size > varToGetSize.getSizeTillEnd()) {
|
2016-06-15 23:48:41 +02:00
|
|
|
return INVALID_SIZE;
|
|
|
|
}
|
|
|
|
uint8_t* ptrToCopy = copyHere;
|
2018-07-12 16:29:32 +02:00
|
|
|
for (; size > 0; size -= typeSize) {
|
2016-06-15 23:48:41 +02:00
|
|
|
DataSet rawSet;
|
2018-07-12 16:29:32 +02:00
|
|
|
PoolRawAccess variable(poolId, arrayIndex, &rawSet,
|
|
|
|
PoolVariableIF::VAR_READ);
|
2016-06-15 23:48:41 +02:00
|
|
|
status = rawSet.read();
|
|
|
|
if (status == RETURN_OK) {
|
|
|
|
uint32_t temp = 0;
|
2018-07-12 16:29:32 +02:00
|
|
|
status = variable.getEntryEndianSafe(ptrToCopy, &temp, size);
|
|
|
|
if (status != RETURN_OK) {
|
2016-06-15 23:48:41 +02:00
|
|
|
return RETURN_FAILED;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
//Error reading parameter.
|
|
|
|
}
|
|
|
|
arrayIndex += 1;
|
|
|
|
ptrToCopy += typeSize;
|
|
|
|
}
|
|
|
|
return ACTIVITY_COMPLETED;
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t DataPoolAdmin::initialize() {
|
2018-07-12 16:29:32 +02:00
|
|
|
ReturnValue_t result = SystemObject::initialize();
|
|
|
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2018-07-13 18:28:26 +02:00
|
|
|
result = memoryHelper.initialize(commandQueue);
|
2018-07-12 16:29:32 +02:00
|
|
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
storage = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
|
|
|
|
if (storage == NULL) {
|
|
|
|
return HasReturnvaluesIF::RETURN_FAILED;
|
|
|
|
}
|
|
|
|
|
2018-07-13 18:28:26 +02:00
|
|
|
result = actionHelper.initialize(commandQueue);
|
2018-07-12 16:29:32 +02:00
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
//mostly identical to ParameterHelper::handleParameterMessage()
|
|
|
|
ReturnValue_t DataPoolAdmin::handleParameterCommand(CommandMessage* command) {
|
|
|
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
|
|
|
|
switch (command->getCommand()) {
|
|
|
|
case ParameterMessage::CMD_PARAMETER_DUMP: {
|
|
|
|
uint8_t domain = HasParametersIF::getDomain(
|
|
|
|
ParameterMessage::getParameterId(command));
|
|
|
|
uint16_t parameterId = HasParametersIF::getMatrixId(
|
|
|
|
ParameterMessage::getParameterId(command));
|
|
|
|
|
|
|
|
DataPoolParameterWrapper wrapper;
|
|
|
|
result = wrapper.set(domain, parameterId);
|
|
|
|
|
|
|
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
|
|
|
result = sendParameter(command->getSender(),
|
|
|
|
ParameterMessage::getParameterId(command), &wrapper);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ParameterMessage::CMD_PARAMETER_LOAD: {
|
|
|
|
|
|
|
|
uint8_t domain = HasParametersIF::getDomain(
|
|
|
|
ParameterMessage::getParameterId(command));
|
|
|
|
uint16_t parameterId = HasParametersIF::getMatrixId(
|
|
|
|
ParameterMessage::getParameterId(command));
|
|
|
|
uint8_t index = HasParametersIF::getIndex(
|
|
|
|
ParameterMessage::getParameterId(command));
|
|
|
|
|
|
|
|
const uint8_t *storedStream;
|
2020-03-23 17:58:23 +01:00
|
|
|
size_t storedStreamSize;
|
2018-07-12 16:29:32 +02:00
|
|
|
result = storage->getData(ParameterMessage::getStoreId(command),
|
|
|
|
&storedStream, &storedStreamSize);
|
|
|
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
ParameterWrapper streamWrapper;
|
|
|
|
result = streamWrapper.set(storedStream, storedStreamSize);
|
|
|
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
|
|
storage->deleteData(ParameterMessage::getStoreId(command));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
DataPoolParameterWrapper poolWrapper;
|
|
|
|
result = poolWrapper.set(domain, parameterId);
|
|
|
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
|
|
storage->deleteData(ParameterMessage::getStoreId(command));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = poolWrapper.copyFrom(&streamWrapper, index);
|
|
|
|
|
|
|
|
storage->deleteData(ParameterMessage::getStoreId(command));
|
|
|
|
|
|
|
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
|
|
|
result = sendParameter(command->getSender(),
|
|
|
|
ParameterMessage::getParameterId(command), &poolWrapper);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return HasReturnvaluesIF::RETURN_FAILED;
|
2016-06-15 23:48:41 +02:00
|
|
|
}
|
2018-07-12 16:29:32 +02:00
|
|
|
|
|
|
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
|
|
rejectCommand(command->getSender(), result, command->getCommand());
|
|
|
|
}
|
|
|
|
|
|
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//identical to ParameterHelper::sendParameter()
|
|
|
|
ReturnValue_t DataPoolAdmin::sendParameter(MessageQueueId_t to, uint32_t id,
|
|
|
|
const DataPoolParameterWrapper* wrapper) {
|
|
|
|
uint32_t serializedSize = wrapper->getSerializedSize();
|
|
|
|
|
|
|
|
uint8_t *storeElement;
|
|
|
|
store_address_t address;
|
|
|
|
|
|
|
|
ReturnValue_t result = storage->getFreeElement(&address, serializedSize,
|
|
|
|
&storeElement);
|
|
|
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2020-04-05 17:58:39 +02:00
|
|
|
size_t storeElementSize = 0;
|
2018-07-12 16:29:32 +02:00
|
|
|
|
|
|
|
result = wrapper->serialize(&storeElement, &storeElementSize,
|
|
|
|
serializedSize, true);
|
|
|
|
|
|
|
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
|
|
storage->deleteData(address);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
CommandMessage reply;
|
|
|
|
|
|
|
|
ParameterMessage::setParameterDumpReply(&reply, id, address);
|
|
|
|
|
|
|
|
commandQueue->sendMessage(to, &reply);
|
|
|
|
|
|
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//identical to ParameterHelper::rejectCommand()
|
|
|
|
void DataPoolAdmin::rejectCommand(MessageQueueId_t to, ReturnValue_t reason,
|
|
|
|
Command_t initialCommand) {
|
|
|
|
CommandMessage reply;
|
|
|
|
reply.setReplyRejected(reason, initialCommand);
|
|
|
|
commandQueue->sendMessage(to, &reply);
|
2016-06-15 23:48:41 +02:00
|
|
|
}
|