diff --git a/datapoolglob/DataPoolAdmin.cpp b/datapoolglob/DataPoolAdmin.cpp index 65ecdb16..2bae75f0 100644 --- a/datapoolglob/DataPoolAdmin.cpp +++ b/datapoolglob/DataPoolAdmin.cpp @@ -210,9 +210,9 @@ ReturnValue_t DataPoolAdmin::handleParameterCommand(CommandMessage* command) { uint8_t domain = HasParametersIF::getDomain( ParameterMessage::getParameterId(command)); - uint16_t parameterId = HasParametersIF::getUniqueIdentifierId( + uint8_t parameterId = HasParametersIF::getUniqueIdentifierId( ParameterMessage::getParameterId(command)); - uint8_t index = HasParametersIF::getIndex( + uint16_t index = HasParametersIF::getIndex( ParameterMessage::getParameterId(command)); const uint8_t *storedStream; diff --git a/parameters/ParameterHelper.cpp b/parameters/ParameterHelper.cpp index e2ea4eb6..d2193b28 100644 --- a/parameters/ParameterHelper.cpp +++ b/parameters/ParameterHelper.cpp @@ -10,6 +10,7 @@ ParameterHelper::~ParameterHelper() { ReturnValue_t ParameterHelper::handleParameterMessage(CommandMessage *message) { if(storage == nullptr) { + // ParameterHelper was not initialized return HasReturnvaluesIF::RETURN_FAILED; } @@ -30,48 +31,48 @@ ReturnValue_t ParameterHelper::handleParameterMessage(CommandMessage *message) { } break; case ParameterMessage::CMD_PARAMETER_LOAD: { - ParameterId_t parameterId = ParameterMessage::getParameterId(message); + ParameterId_t parameterId = 0; + uint8_t ptc = 0; + uint8_t pfc = 0; + uint8_t rows = 0; + uint8_t columns = 0; + store_address_t storeId = ParameterMessage::getParameterLoadCommand( + message, ¶meterId, &ptc, &pfc, &rows, &columns); + Type type(Type::getActualType(ptc, pfc)); + uint8_t domain = HasParametersIF::getDomain(parameterId); uint8_t uniqueIdentifier = HasParametersIF::getUniqueIdentifierId( parameterId); uint16_t linearIndex = HasParametersIF::getIndex(parameterId); - const uint8_t *storedStream = nullptr; - size_t storedStreamSize = 0; - result = storage->getData( - ParameterMessage::getStoreId(message), &storedStream, - &storedStreamSize); + ConstStorageAccessor accessor(storeId); + result = storage->getData(storeId, accessor); if (result != HasReturnvaluesIF::RETURN_OK) { sif::error << "ParameterHelper::handleParameterMessage: Getting" - " store data failed for load command." << std::endl; + << " store data failed for load command." << std::endl; break; } ParameterWrapper streamWrapper; - result = streamWrapper.set(storedStream, storedStreamSize); - if (result != HasReturnvaluesIF::RETURN_OK) { - storage->deleteData(ParameterMessage::getStoreId(message)); - break; + result = streamWrapper.set(type, rows, columns, accessor.data(), + accessor.size()); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; } ParameterWrapper ownerWrapper; result = owner->getParameter(domain, uniqueIdentifier, &ownerWrapper, &streamWrapper, linearIndex); - if (result != HasReturnvaluesIF::RETURN_OK) { - storage->deleteData(ParameterMessage::getStoreId(message)); - break; - } result = ownerWrapper.copyFrom(&streamWrapper, linearIndex); - - storage->deleteData(ParameterMessage::getStoreId(message)); - - if (result == HasReturnvaluesIF::RETURN_OK) { - result = sendParameter(message->getSender(), - ParameterMessage::getParameterId(message), &ownerWrapper); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; } - } + + result = sendParameter(message->getSender(), + ParameterMessage::getParameterId(message), &ownerWrapper); break; + } default: return HasReturnvaluesIF::RETURN_FAILED; } diff --git a/parameters/ParameterMessage.cpp b/parameters/ParameterMessage.cpp index 4a8545eb..af1f9ce8 100644 --- a/parameters/ParameterMessage.cpp +++ b/parameters/ParameterMessage.cpp @@ -35,6 +35,18 @@ void ParameterMessage::setParameterLoadCommand(CommandMessage* message, message->setParameter3(packedParameterSettings); } +store_address_t ParameterMessage::getParameterLoadCommand( + const CommandMessage *message, ParameterId_t* parameterId, uint8_t *ptc, + uint8_t *pfc, uint8_t *rows, uint8_t *columns) { + *parameterId = message->getParameter2(); + uint32_t packedParamSettings = message->getParameter3(); + *ptc = packedParamSettings >> 24 & 0xff; + *pfc = packedParamSettings >> 16 & 0xff; + *rows = packedParamSettings >> 8 & 0xff; + *columns = packedParamSettings & 0xff; + return message->getParameter2(); +} + void ParameterMessage::clear(CommandMessage* message) { switch (message->getCommand()) { case CMD_PARAMETER_LOAD: diff --git a/parameters/ParameterMessage.h b/parameters/ParameterMessage.h index c87c508c..fd4481ee 100644 --- a/parameters/ParameterMessage.h +++ b/parameters/ParameterMessage.h @@ -5,6 +5,20 @@ #include "../ipc/CommandMessage.h" #include "../storagemanager/StorageManagerIF.h" +/** + * @brief ParameterMessage interface + * @details + * General structure of a parameter message: + * 1. 4-byte Object ID + * 2. 4-byte Parameter ID, first byte is Domain ID, second byte is unique + * identifier, third and fourth byte is linear index to start from + * 3. 4-byte Parameter Settings. First byte and second byte are the PTC and PFC + * ECSS type identifiers (see ECSS-E-ST-70-41C15 p.428 or Type class in + * globalfunctions). Third byte is the number of rows and fourth byte + * is the number of columns. For single variable parameters, this will + * be [1, 1]. + * + */ class ParameterMessage { private: ParameterMessage(); @@ -36,6 +50,11 @@ public: static void setParameterLoadCommand(CommandMessage* message, ParameterId_t id, store_address_t storeId, uint8_t ptc, uint8_t pfc, uint8_t rows, uint8_t columns); + + static store_address_t getParameterLoadCommand( + const CommandMessage* message, ParameterId_t* parameterId, + uint8_t* ptc, uint8_t* pfc, uint8_t* rows, uint8_t* columns) ; + static void clear(CommandMessage* message); }; diff --git a/parameters/ParameterWrapper.cpp b/parameters/ParameterWrapper.cpp index 17fb3153..23955516 100644 --- a/parameters/ParameterWrapper.cpp +++ b/parameters/ParameterWrapper.cpp @@ -159,6 +159,23 @@ ReturnValue_t ParameterWrapper::deSerialize(const uint8_t **buffer, return copyFrom(&streamDescription, startWritingAtIndex); } +ReturnValue_t ParameterWrapper::set(Type type, uint8_t rows, uint8_t columns, + const void *data, size_t dataSize) { + this->type = type; + this->rows = rows; + this->columns = columns; + + size_t expectedSize = type.getSize() * rows * columns; + if (expectedSize < dataSize) { + return SerializeIF::STREAM_TOO_SHORT; + } + + this->data = nullptr; + this->readonlyData = data; + pointsToStream = true; + return HasReturnvaluesIF::RETURN_OK; +} + ReturnValue_t ParameterWrapper::set(const uint8_t *stream, size_t streamSize, const uint8_t **remainingStream, size_t *remainingSize) { ReturnValue_t result = SerializeAdapter::deSerialize(&type, &stream, @@ -289,11 +306,12 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from, return result; } -void ParameterWrapper::convertLinearIndexToRowAndColumn(uint16_t index, uint8_t *row, - uint8_t *column) { +void ParameterWrapper::convertLinearIndexToRowAndColumn(uint16_t index, + uint8_t *row, uint8_t *column) { if(row == nullptr or column == nullptr) { return; } + // Integer division. *row = index / columns; *column = index % columns; } diff --git a/parameters/ParameterWrapper.h b/parameters/ParameterWrapper.h index 46044f25..168a535f 100644 --- a/parameters/ParameterWrapper.h +++ b/parameters/ParameterWrapper.h @@ -108,6 +108,9 @@ public: sizeof(member[0])/sizeof(member[0][0])); } + ReturnValue_t set(Type type, uint8_t rows, uint8_t columns, + const void *data, size_t dataSize); + ReturnValue_t set(const uint8_t *stream, size_t streamSize, const uint8_t **remainingStream = nullptr, size_t *remainingSize = nullptr); @@ -158,9 +161,9 @@ inline ReturnValue_t ParameterWrapper::getElement(T *value, uint8_t row, if (pointsToStream) { const uint8_t *streamWithType = static_cast(readonlyData); streamWithType += (row * columns + column) * type.getSize(); - int32_t size = type.getSize(); + size_t size = type.getSize(); return SerializeAdapter::deSerialize(value, &streamWithType, - &size, true); + &size, SerializeIF::Endianness::BIG); } else { const T *dataWithType = static_cast(readonlyData);