diff --git a/inc/ECSS_Definitions.hpp b/inc/ECSS_Definitions.hpp index 2fe9218df54d72b0c965e75983ec99bb312d0f7d..184e969afa195bf6fc1003da4d745abd5255e4fd 100644 --- a/inc/ECSS_Definitions.hpp +++ b/inc/ECSS_Definitions.hpp @@ -53,4 +53,8 @@ #define ECSS_MAX_DELTA_OF_RELEASE_TIME 60 // release time and the actual release time +/** + * @brief Size of the map holding the Parameter objects for the ST[20] parameter service + */ +#define ECSS_ST_20_MAX_PARAMETERS 5 #endif // ECSS_SERVICES_ECSS_DEFINITIONS_H diff --git a/inc/ErrorHandler.hpp b/inc/ErrorHandler.hpp index 97732f38de00cfe4011e8e163102fcf24cbbfcbc..5dd1c6fb2064dd31a0ac893dda282493bf69b9a3 100644 --- a/inc/ErrorHandler.hpp +++ b/inc/ErrorHandler.hpp @@ -70,9 +70,13 @@ public: */ OtherMessageType = 9, /** - * Attempt to insert new function in a full function map (ST[08]) + * Attempt to insert new element in a full map (ST[08], ST[20]) */ - FunctionMapFull = 10, + MapFull = 10, + /** + * Attempt to overwrite an existing parameter (ST[20]) + */ + ExistingParameterId = 11 }; /** diff --git a/inc/Services/Parameter.hpp b/inc/Services/Parameter.hpp index 66916fbd0c56552e137442855dd9d83b4b455e0d..54a40bb1e086a73d755f0c954b73979b662ebb1f 100644 --- a/inc/Services/Parameter.hpp +++ b/inc/Services/Parameter.hpp @@ -4,7 +4,7 @@ #include "etl/bitset.h" // Number of binary flags in every parameter. Final number TBD. -#define NUM_OF_FLAGS 5 +#define NUM_OF_FLAGS 3 /** * Implementation of a Parameter field, as specified in ECSS-E-ST-70-41C. @@ -20,10 +20,12 @@ * @typedef ParamId: the unique ID of a parameter, used for searching * @typedef ValueType: the type of the parameter's value (changing types is WIP) * @typedef UpdatePtr: pointer to a void function, with a single ValueType* argument (return address) + * @typedef Flags: container for the binary flags */ typedef uint16_t ParamId; typedef uint32_t ValueType; typedef void(*UpdatePtr)(ValueType*); +typedef etl::bitset<NUM_OF_FLAGS> Flags; /** * Parameter class - Breakdown of fields @@ -36,18 +38,20 @@ typedef void(*UpdatePtr)(ValueType*); * @todo: Find a way to store arbitrary types in currentValue * * Additional features (not included in standard): - * @private flags: Various binary flags (number and meaning TBD). Ideas: - * update with priority, do not poll, do not allow manual manipulation etc. + * @private flags: Various binary flags (number and meaning TBD). + * @warning Current flag meanings (starting from LSB, big-endian): + * Index 0: update with priority + * Index 1: manual update available + * Index 2: automatic update available * * * Methods: - * @public Parameter(): default constructor, do not use. * @public Parameter(uint8_t newPtc, uint8_t newPfc, uint32_t initialValue = 0, UpdatePtr newPtr = nullptr): * Create a new Parameter object with newPtc PTC, newPfc PFC, initialValue as its starting value and newPtr * as its update function pointer. Arguments initialValue and newPtr are optional, and have default values of * 0 and nullptr respectively. * - * @public setCurrentValue(): Changes the current value of the parameter (todo: if the respective flag is not set) + * @public setCurrentValue(): Changes the current value of the parameter * @public getCurrentValue(): Gets the current value of the parameter * @public getPTC(), getPFC(): Returns the PFC and PTC of the parameter */ @@ -55,15 +59,14 @@ class Parameter { uint8_t ptc; uint8_t pfc; UpdatePtr ptr; - etl::bitset<NUM_OF_FLAGS> flags; + Flags flags; ValueType currentValue = 0; public: - Parameter(); Parameter(uint8_t newPtc, uint8_t newPfc, uint32_t initialValue = 0, UpdatePtr newPtr = nullptr); void setCurrentValue(ValueType newVal); - //void setFlag(); + void setFlags(const char* flags); ValueType getCurrentValue(); uint8_t getPTC(); diff --git a/inc/Services/ParameterService.hpp b/inc/Services/ParameterService.hpp index f214f7640b09edad829c2d4ecc584271842b2483..3d473103009f0da4bfd90ceb88121edee80e6226 100644 --- a/inc/Services/ParameterService.hpp +++ b/inc/Services/ParameterService.hpp @@ -1,18 +1,12 @@ #ifndef ECSS_SERVICES_PARAMETERSERVICE_HPP #define ECSS_SERVICES_PARAMETERSERVICE_HPP +#include "ECSS_Definitions.hpp" #include "Service.hpp" #include "ErrorHandler.hpp" #include "Parameter.hpp" #include "etl/map.h" - -// Number of stored parameters. MAX_PARAMS is just a dummy number for now. -#define MAX_PARAMS 5 -// TODO: 1) Rework the parameter setting and report functions -// TODO: 2) Implement flags and use them above -// TODO: 3) Write more and better tests -// TODO: 4) Make sure that docs are up to date -// TODO: 5) Optimize stuff if possible +#include "etl/vector.h" /** * Implementation of the ST[20] parameter management service, @@ -27,45 +21,44 @@ * for parameter reporting and modification. * * The parameter list is stored in a map with the parameter IDs as keys and values - * corresponding Parameter structs containing the PTC, PFC and the parameter's value. + * corresponding Parameter classes containing the PTC, PFC and the parameter's value. */ class ParameterService : public Service { private: - etl::map<ParamId, Parameter, MAX_PARAMS> paramsList; - uint16_t numOfValidIds(Message idMsg); // count the valid ids in a given TC[20, 1] + etl::map<ParamId, Parameter, ECSS_ST_20_MAX_PARAMETERS> paramsList; public: /** - * Initializes the parameter list. + * @brief Initializes the parameter list. */ ParameterService(); /** - * Adds a new parameter. If the parameter has not been added (either because the map is full or because it already - * exists in it) then returns false. + * @brief Adds a new parameter. Emits an InternalError::MapFull if an attempt is made to insert + * parameters in a full map or an InternalError::ExistingParameterId if the given parameter ID + * exists already. + * @param id: the desired ID for this parameter + * @param param: the parameter field to be included + * @param flags: the flags to be set for this field (see Parameter.hpp) */ - bool addNewParameter(uint8_t ptc, uint8_t pfc, uint32_t initialValue = 0, UpdatePtr ptr = nullptr); + void addNewParameter(uint16_t id, Parameter param, const char* flags = "110"); /** * This function receives a TC[20, 1] packet and returns a TM[20, 2] packet * containing the current configuration * **for the parameters specified in the carried valid IDs**. * - * No sophisticated error checking for now, just whether the packet is of the correct type - * and whether the requested IDs are valid, ignoring the invalid ones. - * If the packet has an incorrect header, an InternalError::UnacceptablePacket is raised. + * The packet is checked for errors in service and message type, as well as for the + * validity of the IDs contained. For every invalid ID an ExecutionStartErrorType::UnknownExecutionStartError + * is raised. + * If the packet has an incorrect header and service type, an InternalError::UnacceptableMessage is raised. * If no IDs are correct, the returned message shall be empty. * - * @param paramId: a valid TC[20, 1] packet carrying the requested parameter IDs + * @param paramId: a TC[20, 1] packet carrying the requested parameter IDs * @return None (messages are stored using storeMessage()) * - * - * NOTES: - * Method for valid ID counting is a hack (clones the message and figures out the number - * separately, due to message access being non-random). Should be enough for now. - * * Everything apart from the setting data is uint16 (setting data are uint32 for now) */ void reportParameterIds(Message& paramIds); @@ -73,7 +66,8 @@ public: /** * This function receives a TC[20, 3] message and after checking whether its type is correct, * iterates over all contained parameter IDs and replaces the settings for each valid parameter, - * while ignoring all invalid IDs. + * while ignoring all invalid IDs. If the manual update flag is not set, the parameter's value should + * not change. * * @param newParamValues: a valid TC[20, 3] message carrying parameter ID and replacement value * @return None diff --git a/src/Services/FunctionManagementService.cpp b/src/Services/FunctionManagementService.cpp index c3831872f501acff1be628955cfb262499df2b62..b6d5638b6efd990136f8173beced1618be85f247 100644 --- a/src/Services/FunctionManagementService.cpp +++ b/src/Services/FunctionManagementService.cpp @@ -42,7 +42,7 @@ void FunctionManagementService::include(String<FUNC_NAME_LENGTH> funcName, void funcName.append(FUNC_NAME_LENGTH - funcName.length(), 0); funcPtrIndex.insert(std::make_pair(funcName, ptr)); } else { - ErrorHandler::reportInternalError(ErrorHandler::InternalErrorType::FunctionMapFull); + ErrorHandler::reportInternalError(ErrorHandler::InternalErrorType::MapFull); } } diff --git a/src/Services/Parameter.cpp b/src/Services/Parameter.cpp index c101d6ae8d2f1cb894e0b337231680e54eabda88..2ab9227164583af68f9a4ead572dd6f7e06cc429 100644 --- a/src/Services/Parameter.cpp +++ b/src/Services/Parameter.cpp @@ -1,16 +1,13 @@ #include "Services/Parameter.hpp" -Parameter::Parameter() { - ptc = 0; - pfc = 0; - ptr = nullptr; -} - -Parameter::Parameter(uint8_t newPtc, uint8_t newPfc, uint32_t initialValue, UpdatePtr newPtr) { +Parameter::Parameter(uint8_t newPtc, uint8_t newPfc, ValueType initialValue, UpdatePtr newPtr) { ptc = newPtc; pfc = newPfc; ptr = newPtr; + // see Parameter.hpp for explanation on flags + // by default: no update priority, manual and automatic update available + if (ptr != nullptr) { (*ptr)(¤tValue); // call the update function for the initial value } else { @@ -19,7 +16,10 @@ Parameter::Parameter(uint8_t newPtc, uint8_t newPfc, uint32_t initialValue, Upda } void Parameter::setCurrentValue(ValueType newVal) { - currentValue = newVal; + // set the value only if the parameter can be updated manually + if (flags[1]) { + currentValue = newVal; + } } ValueType Parameter::getCurrentValue() { @@ -33,3 +33,7 @@ uint8_t Parameter::getPTC() { uint8_t Parameter::getPFC() { return pfc; } + +void Parameter::setFlags(const char* flags) { + this->flags = Flags(flags); +} diff --git a/src/Services/ParameterService.cpp b/src/Services/ParameterService.cpp index a1933cbca33fe41a1a72711bb0b785b603213568..2ac5d101a779f2090490fd78d18141bc5bfb9655 100644 --- a/src/Services/ParameterService.cpp +++ b/src/Services/ParameterService.cpp @@ -7,26 +7,35 @@ ParameterService::ParameterService() { // addNewParameter(3, 14); } -bool ParameterService::addNewParameter(uint8_t ptc, uint8_t pfc, uint32_t initialValue, UpdatePtr ptr) { - Parameter param = Parameter(ptc, pfc, initialValue, ptr); - try { - // second element of the returned std::pair is whether the given item was inserted or not - return paramsList.insert(std::make_pair(paramsList.size() + 1, param)).second; +void ParameterService::addNewParameter(uint16_t id, Parameter param, const char* flags) { + if (paramsList.full()) { + ErrorHandler::reportInternalError(ErrorHandler::InternalErrorType::MapFull); + return; } - catch(etl::map_full) { - return false; + else { + if (paramsList.find(id) == paramsList.end()) { + param.setFlags(flags); + paramsList.insert(std::make_pair(id, param)); + return; + } + else { + ErrorHandler::reportInternalError(ErrorHandler::InternalErrorType::ExistingParameterId); + return; + } } } void ParameterService::reportParameterIds(Message& paramIds) { - paramIds.assertTC(20, 1); - Message reqParam(20, 2, Message::TM, 1); // empty TM[20, 2] parameter report message + etl::vector<std::pair<uint16_t, ValueType>, ECSS_ST_20_MAX_PARAMETERS> validParams; + Message reqParam(20, 2, Message::TM, 1); + // empty TM[20, 2] parameter report message - paramIds.resetRead(); // since we're passing a reference, the reading position shall be reset + paramIds.resetRead(); + // since we're passing a reference, the reading position shall be reset // to its default before any read operations (to ensure the correct data is being read) // assertion: correct message, packet and service type (at failure throws an - // InternalError::UnacceptablePacket) + // InternalError::UnacceptableMessage) ErrorHandler::assertRequest(paramIds.packetType == Message::TC, paramIds, ErrorHandler::AcceptanceErrorType::UnacceptableMessage); ErrorHandler::assertRequest(paramIds.messageType == 1, paramIds, @@ -34,29 +43,35 @@ void ParameterService::reportParameterIds(Message& paramIds) { ErrorHandler::assertRequest(paramIds.serviceType == 20, paramIds, ErrorHandler::AcceptanceErrorType::UnacceptableMessage); - uint16_t numOfIds = paramIds.readUint16(); // number of parameter IDs carried in the message -// uint16_t numOfValidIds = 0; // number of IDs that are actually included in the list -// reqParam.skipBytes(2); // skip the first 16 bits where the number of valid IDs will be included - reqParam.appendUint16(numOfValidIds(paramIds)); // include the number of valid IDs + uint16_t numOfIds = paramIds.readUint16(); // total number of parameter IDs carried in the message + uint16_t validIds = 0; // number of valid IDs for (uint16_t i = 0; i < numOfIds; i++) { - uint16_t currId = paramIds.readUint16(); // current ID to be appended + uint16_t currId = paramIds.readUint16(); if (paramsList.find(currId) != paramsList.end()) { - reqParam.appendUint16(currId); - reqParam.appendUint32(paramsList[currId].getCurrentValue()); - } else { + std::pair<uint16_t, ValueType> p = std::make_pair(currId, paramsList.at(currId).getCurrentValue()); + // pair containing the parameter's ID as first element and its current value as second + validParams.push_back(p); + validIds++; + } + else { ErrorHandler::reportError(paramIds, ErrorHandler::ExecutionStartErrorType::UnknownExecutionStartError); continue; // generate failed start of execution notification & ignore } } - storeMessage(reqParam); + reqParam.appendUint16(validIds); // append the number of valid IDs + + for (auto i: validParams) { + reqParam.appendUint16(i.first); // append the parameter ID + reqParam.appendUint32(i.second); // and its value + } + + storeMessage(reqParam); // then store the message } void ParameterService::setParameterIds(Message& newParamValues) { - newParamValues.assertTC(20, 3); - // assertion: correct message, packet and service type (at failure throws an // InternalError::UnacceptablePacket which gets logged) @@ -71,39 +86,17 @@ void ParameterService::setParameterIds(Message& newParamValues) { for (uint16_t i = 0; i < numOfIds; i++) { uint16_t currId = newParamValues.readUint16(); - + // the parameter is checked for read-only status and manual update availability if (paramsList.find(currId) != paramsList.end()) { - paramsList[currId].setCurrentValue(newParamValues.readUint32()); // TODO: add a check here with the new - // flag functionality - } else { + paramsList.at(currId).setCurrentValue(newParamValues.readUint32()); + } + else { ErrorHandler::reportError(newParamValues, - ErrorHandler::ExecutionStartErrorType::UnknownExecutionStartError); + ErrorHandler::ExecutionStartErrorType::UnknownExecutionStartError); continue; // generate failed start of execution notification & ignore } } } -uint16_t ParameterService::numOfValidIds(Message idMsg) { - idMsg.resetRead(); - // start reading from the beginning of the idMsg object - // (original obj. will not be influenced if this is called by value) - - uint16_t ids = idMsg.readUint16(); // first 16bits of the packet are # of IDs - uint16_t validIds = 0; - - for (uint16_t i = 0; i < ids; i++) { - uint16_t currId = idMsg.readUint16(); - - if (idMsg.messageType == 3) { - idMsg.readUint32(); // skip the 32bit settings blocks, we need only the IDs - } - - if (paramsList.find(currId) != paramsList.end()) { - validIds++; - } - } - - return validIds; -} void ParameterService::execute(Message& message) { switch (message.messageType) { diff --git a/test/Services/FunctionManagementService.cpp b/test/Services/FunctionManagementService.cpp index 45088a8670351de5ca7efbe02057b739714565b8..64683103f21ee59c80db329077d148ca6e335266 100644 --- a/test/Services/FunctionManagementService.cpp +++ b/test/Services/FunctionManagementService.cpp @@ -71,6 +71,6 @@ TEST_CASE("ST[08] - Insert Tests") { name += std::to_string(i); // different names to fill up the map fms.include(String<FUNC_NAME_LENGTH>(name.c_str()), &test); } - CHECK(ServiceTests::thrownError(ErrorHandler::InternalErrorType::FunctionMapFull)); + CHECK(ServiceTests::thrownError(ErrorHandler::InternalErrorType::MapFull)); } } diff --git a/test/Services/ParameterService.cpp b/test/Services/ParameterService.cpp index 7c6f8caa47a83fbf0ecc0adc94aa4b3c6e4963f7..ee678cd5a5998f3a256e9283fb0f2362a14bbee8 100644 --- a/test/Services/ParameterService.cpp +++ b/test/Services/ParameterService.cpp @@ -9,114 +9,174 @@ void foo(ValueType* bar) { // sample function *bar = 0xDEADBEEF; } -/* test ideas: -* parameter setting while flag is active -* -* -*/ - TEST_CASE("Parameter Service - General") { - SECTION("Parameter Setup") { - pserv.addNewParameter(3, 14); // this one has ID 0 - pserv.addNewParameter(1, 7, 12); // this one has 1 - pserv.addNewParameter(4, 12, 3, nullptr); // this one has 2 - pserv.addNewParameter(12, 3, 6, &foo); // this one has 3 - pserv.addNewParameter(15, 7, 3, &foo); //and this one 4 + SECTION("Addition to full map") { + + Parameter param0 = Parameter(3, 14); + Parameter param1 = Parameter(1, 7, 12); + Parameter param2 = Parameter(4, 12, 3, nullptr); + Parameter param3 = Parameter(12, 3, 6, &foo); + Parameter param4 = Parameter(15, 7, 3, &foo); + + Parameter param5 = Parameter(15, 5, 4); + + pserv.addNewParameter(0, param0); + pserv.addNewParameter(1, param1); + pserv.addNewParameter(2, param2); + pserv.addNewParameter(3, param3); + pserv.addNewParameter(4, param4); + + pserv.addNewParameter(5, param5); // addNewParameter should return false + CHECK(ServiceTests::thrownError(ErrorHandler::InternalErrorType::MapFull)); + ServiceTests::reset(); + Services.reset(); // reset all services } - SECTION("Addition to full map") { - CHECK(pserv.addNewParameter(15, 5, 4)); + SECTION("Addition of already existing parameter") { + Parameter param0 = Parameter(1, 3); + pserv.addNewParameter(0, param0); + + pserv.addNewParameter(0, param0); + CHECK(ServiceTests::thrownError(ErrorHandler::InternalErrorType::ExistingParameterId)); + ServiceTests::reset(); + Services.reset(); } } TEST_CASE("Parameter Report Subservice") { + SECTION("All requested parameters invalid") { + Message request = Message(20, 1, Message::TC, 1); + request.appendUint16(3); + request.appendUint16(54432); + request.appendUint16(60000); + request.appendUint16(65535); - SECTION("Faulty Instruction Handling Test") { - Message request(20, 1, Message::TC, 1); - Message report(20, 2, Message::TM, 1); + MessageParser::execute(request); + CHECK(ServiceTests::get(0).serviceType == 1); + CHECK(ServiceTests::get(0).messageType == 4); + CHECK(ServiceTests::get(1).serviceType == 1); + CHECK(ServiceTests::get(1).messageType == 4); + CHECK(ServiceTests::get(2).serviceType == 1); + CHECK(ServiceTests::get(2).messageType == 4); + + Message report = ServiceTests::get(3); + CHECK(report.serviceType == 20); + CHECK(report.messageType == 2); + CHECK(report.readUint16() == 0); // the message shall be empty + + ServiceTests::reset(); + Services.reset(); + } + SECTION("Faulty instruction handling") { + Parameter param0 = Parameter(3, 14); + Parameter param1 = Parameter(1, 7, 12); + Parameter param2 = Parameter(4, 12, 3, nullptr); + pserv.addNewParameter(0, param0); + pserv.addNewParameter(1, param1); + pserv.addNewParameter(2, param2); + + Message request(20, 1, Message::TC, 1); request.appendUint16(2); // number of requested IDs - request.appendUint16(65535); // faulty ID in this context + request.appendUint16(65535); // invalid ID in this context request.appendUint16(1); // valid MessageParser::execute(request); + Message report = ServiceTests::get(1); - CHECK(((ServiceTests::get(0).messageType == 4) && (ServiceTests::get(0).serviceType == 1))); + CHECK(ServiceTests::get(0).messageType == 4); + CHECK(ServiceTests::get(0).serviceType == 1); // check for an ST[1,4] message caused by the faulty ID CHECK((ServiceTests::thrownError(ErrorHandler::ExecutionStartErrorType::UnknownExecutionStartError))); // check for the thrown UnknownExecutionStartError - CHECK(((ServiceTests::get(1).messageType == 2) && (ServiceTests::get(1).serviceType == 20))); + + CHECK(report.messageType == 2); + CHECK(report.serviceType == 20); // check for an ST[20,2] message (the one that contains the settings) - ServiceTests::reset(); - } + CHECK(report.readUint16() == 1); // only one parameter shall be contained + CHECK(report.readUint16() == 1); // check for parameter ID + CHECK(report.readUint32() == 12); // check for value (defined when adding parameters) + + ServiceTests::reset(); // clear all errors + Services.reset(); // reset the services + } - // **WARNING** - // TODO: Update this test (and all tests in general) to use the error handler's output when - // checking for assertions. SECTION("Wrong Message Type Handling Test") { - Message falseRequest(15, 3, Message::TM, 1); // a totally wrong message + Message falseRequest(62, 3, Message::TM, 1); // a totally wrong message MessageParser::execute(falseRequest); - Message errorNotif = ServiceTests::get(0); - CHECK(errorNotif.messageType == 4); // check for proper failed start of - // execution notification - CHECK(errorNotif.serviceType == 1); - - Message response = ServiceTests::get(1); - CHECK(response.messageType == 2); - CHECK(response.serviceType == 20); - CHECK(response.packetType == Message::TM); - CHECK(response.readPosition == 0); // if empty, this should't change from 0 + CHECK(ServiceTests::thrownError(ErrorHandler::InternalErrorType::OtherMessageType)); + + ServiceTests::reset(); + Services.reset(); } } TEST_CASE("Parameter Setting Subservice") { + SECTION("Faulty Instruction Handling Test") { - Message setRequest(20, 3, Message::TC, 1); - Message reportRequest(20, 1, Message::TC, 1); + Parameter param0 = Parameter(3, 14); + Parameter param1 = Parameter(1, 7, 12); + Parameter param2 = Parameter(4, 12, 3, nullptr); + pserv.addNewParameter(0, param0); + pserv.addNewParameter(1, param1); + pserv.addNewParameter(2, param2); + Message setRequest(20, 3, Message::TC, 1); setRequest.appendUint16(2); // total number of IDs setRequest.appendUint16(1); // correct ID in this context setRequest.appendUint32(3735928559); // 0xDEADBEEF in hex (new setting) - setRequest.appendUint16(16742); // faulty ID in this context + setRequest.appendUint16(65535); // faulty ID setRequest.appendUint32(3131746989); // 0xBAAAAAAD (this shouldn't be found in the report) - reportRequest.appendUint16(2); - reportRequest.appendUint16(16742); - reportRequest.appendUint16(1); // used to be 3, which pointed the bug with - // numOfValidIds out, now is 1 in order to be a valid ID (a separate test for - // numOfValidIds shall be introduced) + MessageParser::execute(setRequest); + + + CHECK(ServiceTests::get(0).serviceType == 1); + CHECK(ServiceTests::get(0).messageType == 4); + + Message reportRequest(20, 1, Message::TC, 1); + reportRequest.appendUint16(1); + reportRequest.appendUint16(1); // the changed parameter has ID 1 - // Since every reporting and setting is called with the same (sometimes faulty) parameters, - // and there are errors generated (as should be) it is important to catch and check for - // them in order to preserve the integrity of the test. MessageParser::execute(reportRequest); - Message errorNotif1 = ServiceTests::get(0); - CHECK(errorNotif1.messageType == 4); - CHECK(errorNotif1.serviceType == 1); + Message report = ServiceTests::get(1); + CHECK(report.serviceType == 20); + CHECK(report.messageType == 2); + CHECK(report.readUint16() == 1); // only 1 ID contained + CHECK(report.readUint16() == 1); // contained ID should be ID 1 + CHECK(report.readUint32() == 3735928559); // whose value is 0xDEADBEEF + + ServiceTests::reset(); + Services.reset(); + } + + SECTION("Attempt to set parameter with no manual update availability") { + Parameter param1 = Parameter(1, 7, 12); + pserv.addNewParameter(1, param1, "100"); - Message before = ServiceTests::get(1); + Message setRequest = Message(20, 3, Message::TC, 1); + setRequest.appendUint16(1); + setRequest.appendUint16(1); + setRequest.appendUint32(0xBAAAAAAD); MessageParser::execute(setRequest); - Message errorNotif2 = ServiceTests::get(2); - CHECK(errorNotif2.messageType == 4); - CHECK(errorNotif2.serviceType == 1); - MessageParser::execute(reportRequest); - Message errorNotif3 = ServiceTests::get(3); - CHECK(errorNotif3.messageType == 4); - CHECK(errorNotif3.serviceType == 1); + Message infoRequest = Message(20, 1, Message::TC, 1); + infoRequest.appendUint16(1); + infoRequest.appendUint16(1); - Message after = ServiceTests::get(4); + MessageParser::execute(infoRequest); - before.readUint16(); - after.readUint16(); // skip the number of IDs + Message report = ServiceTests::get(0); - while (after.readPosition <= after.dataSize) { - CHECK(before.readUint16() == after.readUint16()); // check if all IDs are present - CHECK_FALSE(after.readUint32() == 0xBAAAAAAD); // fail if any settings are BAAAAAAD :P - } + CHECK(report.readUint16() == 1); + CHECK(report.readUint16() == 1); + CHECK_FALSE(report.readUint32() == 0xBAAAAAAD); + + ServiceTests::reset(); + Services.reset(); } }