diff --git a/inc/ECSS_Definitions.hpp b/inc/ECSS_Definitions.hpp index 01584367845db270942762e8dc52e0ededadb021..2fe9218df54d72b0c965e75983ec99bb312d0f7d 100644 --- a/inc/ECSS_Definitions.hpp +++ b/inc/ECSS_Definitions.hpp @@ -44,6 +44,11 @@ */ #define ECSS_TIME_MARGIN_FOR_ACTIVATION 60 +/** + * @brief Size of the multimap that holds every event-action definition + */ +#define ECSS_EVENT_ACTION_STRUCT_MAP_SIZE 256 + // todo: Define the maximum delta between the specified #define ECSS_MAX_DELTA_OF_RELEASE_TIME 60 // release time and the actual release time diff --git a/inc/ErrorHandler.hpp b/inc/ErrorHandler.hpp index 1f2fdbf6b68a65d2df08f2e312987693be2444c2..97732f38de00cfe4011e8e163102fcf24cbbfcbc 100644 --- a/inc/ErrorHandler.hpp +++ b/inc/ErrorHandler.hpp @@ -109,8 +109,29 @@ public: */ enum ExecutionStartErrorType { UnknownExecutionStartError = 0, - SubServiceExecutionStartError = 1, - InstructionExecutionStartError = 2, + /** + * In the Event Action Service, in the addEventActionDefinition function an attempt was + * made to add an event Action Definition with an eventActionDefinitionID that exists + */ + EventActionDefinitionIDExistsError = 1, + /** + * In the Event Action Service, in the deleteEventActionDefinition function, an attempt + * was made to delete an event action definition that was enabled + */ + EventActionDeleteEnabledDefinitionError = 2, + /** + * In the Event Action Service, an access attempt was made to an unknown event + * action definition + */ + EventActionUnknownEventDefinitionError = 3, + /** + * EventAction refers to the service, EventActionIDefinitionID refers to the variable + * In the Event Action Service, an access attempt was made to an unknown eventActionDefinitionID + */ + EventActionUnknownEventActionDefinitionIDError = 4, + SubServiceExecutionStartError = 5, + InstructionExecutionStartError = 6, + }; /** diff --git a/inc/Services/EventActionService.hpp b/inc/Services/EventActionService.hpp index 96f66c7cec731805e19b9ac41ba001f5aca7de6c..38166c4129bd7ecb9f99b5ba1e47b4f6b6e36717 100644 --- a/inc/Services/EventActionService.hpp +++ b/inc/Services/EventActionService.hpp @@ -1,26 +1,29 @@ #ifndef ECSS_SERVICES_EVENTACTIONSERVICE_HPP #define ECSS_SERVICES_EVENTACTIONSERVICE_HPP -#define ECSS_EVENT_ACTION_STRUCT_ARRAY_SIZE 256 - #include "Service.hpp" #include "MessageParser.hpp" #include "etl/String.hpp" -#include <Services/EventReportService.hpp> +#include "Services/EventReportService.hpp" +#include "etl/multimap.h" /** * Implementation of ST[19] event-action Service * * ECSS 8.19 && 6.19 * - * @todo: Use an etl::list instead of eventActionDefinitionArray - * @todo: (Possible) Use a etl::map for eventActionDefinitionArray - * @todo: check if executeAction should accept applicationID too + * @note: Make sure to check the note in the addEventActionDefinition() + * @note: A third variable was added, the eventActionDefinitionID. This was added for the purpose of identifying + * various eventActionDefinitions that correspond to the same eventDefinitionID. The goal is to have multiple actions + * be executed when one event takes place. This defies the standard. + * @note: The application ID was decided to be abolished as an identifier of the event-action + * definition + * @attention: Every event action definition ID should be different, regardless of the application ID + * * @todo: Since there are multiple actions per event and in delete/enable/disable functions are * multiple instances are accessed, should I find a more efficient way to access them? * @todo: check if eventActionFunctionStatus should be private or not - * @todo: check if eventAction array of definitions should be private or not - * @todo: check size of eventActionDefinitionArray + * @todo: check if eventAction map of definitions should be private or not */ class EventActionService : public Service { private: @@ -37,17 +40,18 @@ private: public: struct EventActionDefinition { - bool empty = true; // TODO: APID = 0 is the Ground Station APID. This should be changed uint16_t applicationId = 0; - uint16_t eventDefinitionID = 65535; + uint16_t eventDefinitionID = 65535; // The ID of the event that might take place + uint16_t eventActionDefinitionID = 0; // The ID of the event-action String<64> request = ""; bool enabled = false; }; friend EventReportService; - EventActionDefinition eventActionDefinitionArray[ECSS_EVENT_ACTION_STRUCT_ARRAY_SIZE]; + etl::multimap<uint16_t, EventActionDefinition, ECSS_EVENT_ACTION_STRUCT_MAP_SIZE> + eventActionDefinitionMap; EventActionService() { serviceType = 19; @@ -61,32 +65,32 @@ public: * event-action definition will be added per TC packet. That means there will be just an * application ID, an event definition ID and the TC request. */ - void addEventActionDefinitions(Message message); + void addEventActionDefinitions(Message& message); /** * TC[19,2] delete event-action definitions */ - void deleteEventActionDefinitions(Message message); + void deleteEventActionDefinitions(Message& message); /** * TC[19,3] delete all event-action definitions */ - void deleteAllEventActionDefinitions(Message message); + void deleteAllEventActionDefinitions(Message& message); /** * TC[19,4] enable event-action definitions */ - void enableEventActionDefinitions(Message message); + void enableEventActionDefinitions(Message& message); /** * TC[19,5] disable event-action definitions */ - void disableEventActionDefinitions(Message message); + void disableEventActionDefinitions(Message& message); /** * TC[19,6] report the status of each event-action definition */ - void requestEventActionDefinitionStatus(Message message); + void requestEventActionDefinitionStatus(Message& message); /** * TM[19,7] event-action status report @@ -96,12 +100,12 @@ public: /** * TC[19,8] enable the event-action function */ - void enableEventActionFunction(Message message); + void enableEventActionFunction(Message& message); /** * TC[19,9] disable the event-actioni function */ - void disableEventActionFunction(Message message); + void disableEventActionFunction(Message& message); /** * Setter for event-action function status diff --git a/src/Services/EventActionService.cpp b/src/Services/EventActionService.cpp index a24671594c993fe51ed944a39d5c52e6d9d32c28..a78f2b56c4136f3945e0152e790cca00a63294fb 100644 --- a/src/Services/EventActionService.cpp +++ b/src/Services/EventActionService.cpp @@ -2,137 +2,143 @@ #include "Message.hpp" #include "MessageParser.hpp" -/** - * @todo: Check if a uint16_t is needed (in case of changing the size of - * eventActionDefinitionArray) - */ -void EventActionService::addEventActionDefinitions(Message message) { + +void EventActionService::addEventActionDefinitions(Message& message) { // TC[19,1] message.assertTC(19, 1); - - uint16_t index; uint16_t applicationID = message.readEnum16(); uint16_t eventDefinitionID = message.readEnum16(); - bool accepted = true; - for (index = 0; index < ECSS_EVENT_ACTION_STRUCT_ARRAY_SIZE; index++) { - if ((eventActionDefinitionArray[index].applicationId == applicationID) && - (eventActionDefinitionArray[index].eventDefinitionID == eventDefinitionID) && - eventActionDefinitionArray[index].enabled) { - // @todo: throw a failed start of execution error - accepted = false; - } - } - if (accepted) { - for (index = 0; index < ECSS_EVENT_ACTION_STRUCT_ARRAY_SIZE; index++) { - // @todo: throw an error if it's full - if (eventActionDefinitionArray[index].empty) { - break; - } - } - if (index < ECSS_EVENT_ACTION_STRUCT_ARRAY_SIZE) { - eventActionDefinitionArray[index].empty = false; - eventActionDefinitionArray[index].enabled = true; - eventActionDefinitionArray[index].applicationId = applicationID; - eventActionDefinitionArray[index].eventDefinitionID = eventDefinitionID; - if ((message.dataSize - 4) > ECSS_TC_REQUEST_STRING_SIZE) { - ErrorHandler::reportInternalError(ErrorHandler::InternalErrorType::MessageTooLarge); - } else { - char data[ECSS_TC_REQUEST_STRING_SIZE]; - message.readString(data, message.dataSize - 4); - eventActionDefinitionArray[index].request = String<ECSS_TC_REQUEST_STRING_SIZE>(data); + uint16_t eventActionDefinitionID = message.readEnum16(); + bool canBeAdded = true; + if (eventActionDefinitionMap.find(eventDefinitionID) != eventActionDefinitionMap.end()) { + auto range = eventActionDefinitionMap.equal_range(eventDefinitionID); + for (auto& element = range.first; element != range.second; ++element) { + if (element->second.eventActionDefinitionID == eventActionDefinitionID) { + canBeAdded = false; + ErrorHandler::reportError(message, ErrorHandler::EventActionDefinitionIDExistsError); } } } + if ((message.dataSize - 6) > ECSS_TC_REQUEST_STRING_SIZE) { + canBeAdded = false; + ErrorHandler::reportInternalError(ErrorHandler::MessageTooLarge); + } + if (canBeAdded) { + char data[ECSS_TC_REQUEST_STRING_SIZE]; + message.readString(data, message.dataSize - 6); + EventActionDefinition temp; + temp.enabled = false; + temp.applicationId = applicationID; + temp.eventDefinitionID = eventDefinitionID; + temp.eventActionDefinitionID = eventActionDefinitionID; + temp.request = String<ECSS_TC_REQUEST_STRING_SIZE>(data); + eventActionDefinitionMap.insert(std::make_pair(eventDefinitionID, temp)); + } } -void EventActionService::deleteEventActionDefinitions(Message message) { +void EventActionService::deleteEventActionDefinitions(Message& message) { message.assertTC(19, 2); - uint16_t numberOfEventActionDefinitions = message.readUint16(); + bool definitionIDexists = false; for (uint16_t i = 0; i < numberOfEventActionDefinitions; i++) { - uint16_t applicationID = message.readEnum16(); + message.skipBytes(2); uint16_t eventDefinitionID = message.readEnum16(); - for (uint16_t index = 0; index < ECSS_EVENT_ACTION_STRUCT_ARRAY_SIZE; index++) { - if ((eventActionDefinitionArray[index].applicationId == applicationID) && - (eventActionDefinitionArray[index].eventDefinitionID == eventDefinitionID) && - eventActionDefinitionArray[index].enabled) { - eventActionDefinitionArray[index].empty = true; - eventActionDefinitionArray[index].eventDefinitionID = 65535; - eventActionDefinitionArray[index].request = ""; - eventActionDefinitionArray[index].applicationId = 0; - eventActionDefinitionArray[index].enabled = false; + uint16_t eventActionDefinitionID = message.readEnum16(); + if (eventActionDefinitionMap.find(eventDefinitionID) != eventActionDefinitionMap.end()) { + auto range = eventActionDefinitionMap.equal_range(eventDefinitionID); + for (auto& element = range.first; element != range.second; ++element) { + if (element->second.eventActionDefinitionID == eventActionDefinitionID) { + definitionIDexists = true; + if (element->second.enabled) { + ErrorHandler::reportError(message, ErrorHandler::EventActionDeleteEnabledDefinitionError); + } else { + eventActionDefinitionMap.erase(element); + } + } + } + if (not definitionIDexists) { + ErrorHandler::reportError(message, ErrorHandler::EventActionUnknownEventActionDefinitionIDError); } + } else { + ErrorHandler::reportError(message, ErrorHandler::EventActionUnknownEventDefinitionError); } } } -void EventActionService::deleteAllEventActionDefinitions(Message message) { +void EventActionService::deleteAllEventActionDefinitions(Message& message) { // TC[19,3] message.assertTC(19, 3); setEventActionFunctionStatus(false); - for (uint16_t index = 0; index < ECSS_EVENT_ACTION_STRUCT_ARRAY_SIZE; index++) { - if (not eventActionDefinitionArray[index].empty) { - eventActionDefinitionArray[index].empty = true; - eventActionDefinitionArray[index].enabled = false; - eventActionDefinitionArray[index].eventDefinitionID = 65535; - eventActionDefinitionArray[index].request = ""; - eventActionDefinitionArray[index].applicationId = 0; - } - } + eventActionDefinitionMap.clear(); } -void EventActionService::enableEventActionDefinitions(Message message) { +void EventActionService::enableEventActionDefinitions(Message& message) { // TC[19,4] message.assertTC(19, 4); - uint16_t numberOfEventActionDefinitions = message.readUint16(); if (numberOfEventActionDefinitions != 0u) { for (uint16_t i = 0; i < numberOfEventActionDefinitions; i++) { - uint16_t applicationID = message.readEnum16(); + message.skipBytes(2); // Skips reading the application ID uint16_t eventDefinitionID = message.readEnum16(); - for (uint16_t index = 0; index < ECSS_EVENT_ACTION_STRUCT_ARRAY_SIZE; index++) { - if ((eventActionDefinitionArray[index].applicationId == applicationID) && - (eventActionDefinitionArray[index].eventDefinitionID == eventDefinitionID)) { - eventActionDefinitionArray[index].enabled = true; + uint16_t eventActionDefinitionID = message.readEnum16(); + if (eventActionDefinitionMap.find(eventDefinitionID) != eventActionDefinitionMap.end()) { + bool definitionIDexists = false; + auto range = eventActionDefinitionMap.equal_range(eventDefinitionID); + for (auto& element = range.first; element != range.second; ++element) { + if (element->second.eventActionDefinitionID == eventActionDefinitionID) { + element->second.enabled = true; + definitionIDexists = true; + break; + } } + if (not definitionIDexists) { + ErrorHandler::reportError(message, ErrorHandler::EventActionUnknownEventActionDefinitionIDError); + } + } else { + ErrorHandler::reportError(message, ErrorHandler::EventActionUnknownEventDefinitionError); } } } else { - for (uint16_t index = 0; index < ECSS_EVENT_ACTION_STRUCT_ARRAY_SIZE; index++) { - if (not eventActionDefinitionArray[index].empty) { - eventActionDefinitionArray[index].enabled = true; - } + for (auto& element : eventActionDefinitionMap) { + element.second.enabled = true; } } } -void EventActionService::disableEventActionDefinitions(Message message) { +void EventActionService::disableEventActionDefinitions(Message& message) { // TC[19,5] message.assertTC(19, 5); - uint16_t numberOfEventActionDefinitions = message.readUint16(); if (numberOfEventActionDefinitions != 0u) { for (uint16_t i = 0; i < numberOfEventActionDefinitions; i++) { - uint16_t applicationID = message.readEnum16(); + message.skipBytes(2); // Skips reading applicationID uint16_t eventDefinitionID = message.readEnum16(); - for (uint16_t index = 0; index < ECSS_EVENT_ACTION_STRUCT_ARRAY_SIZE; index++) { - if ((eventActionDefinitionArray[index].applicationId == applicationID) && - (eventActionDefinitionArray[index].eventDefinitionID == eventDefinitionID)) { - eventActionDefinitionArray[index].enabled = false; + uint16_t eventActionDefinitionID = message.readEnum16(); + if (eventActionDefinitionMap.find(eventDefinitionID) != eventActionDefinitionMap.end()) { + bool definitionIDexists = false; + auto range = eventActionDefinitionMap.equal_range(eventDefinitionID); + for (auto& element = range.first; element != range.second; ++element) { + if (element->second.eventActionDefinitionID == eventActionDefinitionID) { + element->second.enabled = false; + definitionIDexists = true; + } + } + if (not definitionIDexists) { + ErrorHandler::reportError(message, ErrorHandler::EventActionUnknownEventActionDefinitionIDError); } + } else { + ErrorHandler::reportError(message, ErrorHandler::EventActionUnknownEventDefinitionError); } } } else { - for (uint16_t index = 0; index < ECSS_EVENT_ACTION_STRUCT_ARRAY_SIZE; index++) { - if (not eventActionDefinitionArray[index].empty) { - eventActionDefinitionArray[index].enabled = false; - } + for (auto& element : eventActionDefinitionMap) { + element.second.enabled = false; } } } -void EventActionService::requestEventActionDefinitionStatus(Message message) { +void EventActionService::requestEventActionDefinitionStatus(Message& message) { // TC[19,6] message.assertTC(19, 6); @@ -142,31 +148,25 @@ void EventActionService::requestEventActionDefinitionStatus(Message message) { void EventActionService::eventActionStatusReport() { // TM[19,7] Message report = createTM(7); - uint8_t count = 0; - for (uint16_t i = 0; i < ECSS_EVENT_ACTION_STRUCT_ARRAY_SIZE; i++) { - if (not eventActionDefinitionArray[i].empty) { - count++; - } - } - report.appendUint8(count); - for (const auto& definition : eventActionDefinitionArray) { - if (not definition.empty) { - report.appendEnum16(definition.applicationId); - report.appendEnum16(definition.eventDefinitionID); - report.appendBoolean(definition.enabled); - } + uint16_t count = eventActionDefinitionMap.size(); + report.appendUint16(count); + for (const auto& element : eventActionDefinitionMap) { + report.appendEnum16(element.second.applicationId); + report.appendEnum16(element.second.eventDefinitionID); + report.appendEnum16(element.second.eventActionDefinitionID); + report.appendBoolean(element.second.enabled); } storeMessage(report); } -void EventActionService::enableEventActionFunction(Message message) { +void EventActionService::enableEventActionFunction(Message& message) { // TC[19,8] message.assertTC(19, 8); setEventActionFunctionStatus(true); } -void EventActionService::disableEventActionFunction(Message message) { +void EventActionService::disableEventActionFunction(Message& message) { // TC[19,9] message.assertTC(19, 9); @@ -177,13 +177,12 @@ void EventActionService::disableEventActionFunction(Message message) { void EventActionService::executeAction(uint16_t eventID) { // Custom function if (eventActionFunctionStatus) { - for (const auto& definition : eventActionDefinitionArray) { - if (not definition.empty && definition.enabled) { - if (definition.eventDefinitionID == eventID) { - MessageParser messageParser; - Message message = messageParser.parseRequestTC(definition.request); - messageParser.execute(message); - } + auto range = eventActionDefinitionMap.equal_range(eventID); + for (auto& element = range.first; element != range.second; ++element) { + if (element->second.enabled) { + MessageParser messageParser; + Message message = messageParser.parseRequestTC(element->second.request); + messageParser.execute(message); } } } diff --git a/src/main.cpp b/src/main.cpp index 1b60cb421ada610351bce0e2b904e275304a5234..26fc994542f2c31f3b82915d55fa79a5c26b3994 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -222,66 +222,101 @@ int main() { // ST[19] test - EventActionService& eventActionService = Services.eventAction; + EventActionService & eventActionService = Services.eventAction; + Message eventActionDefinition(19, 1, Message::TC, 1); eventActionDefinition.appendEnum16(0); eventActionDefinition.appendEnum16(2); - String<64> TCdata = "hi"; + eventActionDefinition.appendEnum16(1); + String<64> TCdata = "0123456789123456789123456789123456789123456789123456789123456789"; eventActionDefinition.appendString(TCdata); eventActionService.addEventActionDefinitions(eventActionDefinition); + Message eventActionDefinition1(19, 1, Message::TC, 1); eventActionDefinition1.appendEnum16(0); - eventActionDefinition1.appendEnum16(3); + eventActionDefinition1.appendEnum16(2); + eventActionDefinition1.appendEnum16(1); TCdata = "hi1"; eventActionDefinition1.appendString(TCdata); + std::cout << "After this message there should be a failed start of execution error \n"; eventActionService.addEventActionDefinitions(eventActionDefinition1); + Message eventActionDefinition2(19, 1, Message::TC, 1); eventActionDefinition2.appendEnum16(0); eventActionDefinition2.appendEnum16(4); + eventActionDefinition2.appendEnum16(2); TCdata = "hi2"; eventActionDefinition2.appendString(TCdata); eventActionService.addEventActionDefinitions(eventActionDefinition2); + + Message eventActionDefinition7(19, 1, Message::TC, 1); + eventActionDefinition7.appendEnum16(0); + eventActionDefinition7.appendEnum16(4); + eventActionDefinition7.appendEnum16(4); + TCdata = "hi2"; + eventActionDefinition7.appendString(TCdata); + eventActionService.addEventActionDefinitions(eventActionDefinition7); + + std::cout << "Status should be 000:"; + for (auto& element : eventActionService.eventActionDefinitionMap){ + std::cout << element.second.enabled; + } + + Message eventActionDefinition5(19, 4, Message::TC, 1); + eventActionDefinition5.appendUint16(3); + eventActionDefinition5.appendUint16(0); + eventActionDefinition5.appendUint16(2); + eventActionDefinition5.appendUint16(1); + eventActionDefinition5.appendUint16(0); + eventActionDefinition5.appendUint16(4); + eventActionDefinition5.appendUint16(2); + eventActionDefinition5.appendUint16(0); + eventActionDefinition5.appendUint16(4); + eventActionDefinition5.appendUint16(4); + + eventActionService.enableEventActionDefinitions(eventActionDefinition5); + std::cout << "\nStatus should be 111:"; + for (auto& element : eventActionService.eventActionDefinitionMap){ + std::cout << element.second.enabled; + } + Message eventActionDefinition3(19, 5, Message::TC, 1); eventActionDefinition3.appendUint16(3); eventActionDefinition3.appendUint16(0); eventActionDefinition3.appendUint16(2); + eventActionDefinition3.appendUint16(1); eventActionDefinition3.appendUint16(0); - eventActionDefinition3.appendUint16(3); + eventActionDefinition3.appendUint16(4); + eventActionDefinition3.appendUint16(2); eventActionDefinition3.appendUint16(0); eventActionDefinition3.appendUint16(4); - + eventActionDefinition3.appendUint16(4); eventActionService.disableEventActionDefinitions(eventActionDefinition3); - std::cout << "Status of position 0,1,2 should be 000:" << eventActionService.eventActionDefinitionArray[0].enabled - << eventActionService.eventActionDefinitionArray[1].enabled - << eventActionService.eventActionDefinitionArray[2].enabled; + std::cout << "Status should be 000:"; + for (auto& element : eventActionService.eventActionDefinitionMap){ + std::cout << element.second.enabled; + } - Message eventActionDefinition5(19, 4, Message::TC, 1); - eventActionDefinition5.appendUint16(2); - eventActionDefinition5.appendUint16(0); - eventActionDefinition5.appendUint16(2); - eventActionDefinition5.appendUint16(0); - eventActionDefinition5.appendUint16(3); eventActionService.enableEventActionDefinitions(eventActionDefinition5); - std::cout << "\nStatus of position 0,1,2 should be 110:" << eventActionService.eventActionDefinitionArray[0].enabled - << eventActionService.eventActionDefinitionArray[1].enabled - << eventActionService.eventActionDefinitionArray[2].enabled; Message eventActionDefinition4(19, 2, Message::TC, 1); - eventActionDefinition4.appendUint16(2); + eventActionDefinition4.appendUint16(1); eventActionDefinition4.appendUint16(0); eventActionDefinition4.appendUint16(2); - eventActionDefinition4.appendUint16(0); - eventActionDefinition4.appendUint16(3); + eventActionDefinition4.appendUint16(1); + + std::cout << "After this message there should be a failed start of execution error \n"; + eventActionService.deleteEventActionDefinitions(eventActionDefinition4); + Message eventActionDefinition6(19, 5, Message::TC, 1); + eventActionDefinition6.appendUint16(1); + eventActionDefinition6.appendUint16(0); + eventActionDefinition6.appendUint16(2); + eventActionDefinition6.appendUint16(1); + eventActionService.disableEventActionDefinitions(eventActionDefinition6); + std::cout << "After this message there should NOT be a failed start of execution error \n"; eventActionService.deleteEventActionDefinitions(eventActionDefinition4); - std::cout << "\nPositions 0,1 empty should be 11:" - << static_cast<uint16_t>(eventActionService.eventActionDefinitionArray[0].empty) - << static_cast<uint16_t>(eventActionService.eventActionDefinitionArray[1].empty); - - Message eventActionDefinition6(19, 3, Message::TC, 1); - eventActionService.deleteAllEventActionDefinitions(eventActionDefinition6); - std::cout << "\nPositions 0,1 empty should be 1:" - << static_cast<uint16_t>(eventActionService.eventActionDefinitionArray[0].empty); + // ST13 test diff --git a/test/Services/EventActionService.cpp b/test/Services/EventActionService.cpp index 2c6d96786894bba8ecf729ab962cc172ce8dc077..975d92ae52ba206f2071ae9a6a746cc59170d89d 100644 --- a/test/Services/EventActionService.cpp +++ b/test/Services/EventActionService.cpp @@ -3,146 +3,195 @@ #include <Message.hpp> #include "ServiceTests.hpp" #include <etl/String.hpp> +#include <etl/map.h> #include <cstring> #include <iostream> #include <ServicePool.hpp> EventActionService& eventActionService = Services.eventAction; -TEST_CASE("Add event-action definitions TC[19,1]", "[service][st09]") { - char checkstring[256]; +TEST_CASE("Add event-action definitions TC[19,1]", "[service][st19]") { + + // Add a message that is too large to check for the corresponding error Message message(19, 1, Message::TC, 0); message.appendEnum16(0); - message.appendEnum16(2); - String<64> data = "123"; + message.appendEnum16(1); + message.appendEnum16(1); + String<128> data = "0123456789012345678901234567890123456789012345678901234567890123456789"; message.appendString(data); eventActionService.addEventActionDefinitions(message); - CHECK(eventActionService.eventActionDefinitionArray[0].empty == 0); - CHECK(eventActionService.eventActionDefinitionArray[0].applicationId == 0); - CHECK(eventActionService.eventActionDefinitionArray[0].eventDefinitionID == 2); - CHECK(eventActionService.eventActionDefinitionArray[0].enabled == 1); - CHECK(message.readEnum16() == 0); - CHECK(message.readEnum16() == 2); - message.readString(checkstring, 3); - CHECK(eventActionService.eventActionDefinitionArray[0].request.compare(data) == 0); + CHECK(ServiceTests::thrownError(ErrorHandler::MessageTooLarge)); + CHECK(ServiceTests::countErrors() == 1); + // Add an event-action definition to check if the values are inserted correctly + Message message1(19, 1, Message::TC, 0); + message1.appendEnum16(0); + message1.appendEnum16(2); + message1.appendEnum16(1); + data = "01234"; + message1.appendString(data); + eventActionService.addEventActionDefinitions(message1); + + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(2)->second.applicationId == 0); + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(2)->second.eventDefinitionID == 2); + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(2)->second.enabled == 0); + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(2)->second.request.compare(data) == 0); + + // Add a second event-action definition Message message2(19, 1, Message::TC, 0); message2.appendEnum16(1); message2.appendEnum16(3); + message2.appendEnum16(1); data = "456"; message2.appendString(data); - eventActionService.addEventActionDefinitions(message2); - CHECK(eventActionService.eventActionDefinitionArray[1].empty == 0); - CHECK(eventActionService.eventActionDefinitionArray[1].applicationId == 1); - CHECK(eventActionService.eventActionDefinitionArray[1].eventDefinitionID == 3); - CHECK(eventActionService.eventActionDefinitionArray[1].enabled == 1); - - CHECK(message2.readEnum16() == 1); - CHECK(message2.readEnum16() == 3); - CHECK(eventActionService.eventActionDefinitionArray[1].request.compare(data) == 0); + + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(3)->second.applicationId == 1); + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(3)->second.eventDefinitionID == 3); + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(3)->second.enabled == 0); + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(3)->second.request.compare(data) == 0); + + // Adding the same message to check for error + Message message3(19, 1, Message::TC, 0); + message3.appendEnum16(1); + message3.appendEnum16(3); + message3.appendEnum16(1); + data = "456"; + message3.appendString(data); + eventActionService.addEventActionDefinitions(message3); + CHECK(ServiceTests::thrownError(ErrorHandler::EventActionDefinitionIDExistsError)); + CHECK(ServiceTests::countErrors() == 2); } -TEST_CASE("Delete event-action definitions TC[19,2]", "[service][st09]") { +TEST_CASE("Delete event-action definitions TC[19,2]", "[service][st19]") { + + // Add messages for the purpose of deleting them Message message0(19, 1, Message::TC, 0); message0.appendEnum16(1); message0.appendEnum16(0); + message0.appendEnum16(1); String<64> data = "0"; message0.appendString(data); eventActionService.addEventActionDefinitions(message0); + Message message1(19, 1, Message::TC, 0); message1.appendEnum16(1); message1.appendEnum16(1); + message1.appendEnum16(1); data = "1"; message1.appendString(data); eventActionService.addEventActionDefinitions(message1); + Message message2(19, 1, Message::TC, 0); message2.appendEnum16(1); message2.appendEnum16(2); + message2.appendEnum16(1); data = "2"; message2.appendString(data); eventActionService.addEventActionDefinitions(message2); - Message message3(19, 1, Message::TC, 0); - message3.appendEnum16(1); - message3.appendEnum16(3); - data = "3"; - message3.appendString(data); - eventActionService.addEventActionDefinitions(message3); - Message message4(19, 1, Message::TC, 0); - message4.appendEnum16(1); - message4.appendEnum16(4); - data = "4"; - message4.appendString(data); - eventActionService.addEventActionDefinitions(message4); - Message message(19, 2, Message::TC, 0); - message.appendUint16(2); - message.appendEnum16(1); - message.appendEnum16(4); - message.appendEnum16(1); - message.appendEnum16(2); - eventActionService.deleteEventActionDefinitions(message); - - CHECK(eventActionService.eventActionDefinitionArray[0].empty == 0); - CHECK(eventActionService.eventActionDefinitionArray[0].applicationId == 1); - CHECK(eventActionService.eventActionDefinitionArray[0].eventDefinitionID == 0); - CHECK(eventActionService.eventActionDefinitionArray[0].request.compare("0") == 0); - CHECK(eventActionService.eventActionDefinitionArray[0].enabled == 1); - - CHECK(eventActionService.eventActionDefinitionArray[1].empty == 0); - CHECK(eventActionService.eventActionDefinitionArray[1].applicationId == 1); - CHECK(eventActionService.eventActionDefinitionArray[1].eventDefinitionID == 1); - CHECK(eventActionService.eventActionDefinitionArray[1].request.compare("1") == 0); - CHECK(eventActionService.eventActionDefinitionArray[1].enabled == 1); - - CHECK(eventActionService.eventActionDefinitionArray[2].empty == 1); - CHECK(eventActionService.eventActionDefinitionArray[2].applicationId == 0); - CHECK(eventActionService.eventActionDefinitionArray[2].eventDefinitionID == 65535); - CHECK(eventActionService.eventActionDefinitionArray[2].request.compare("") == 0); - CHECK(eventActionService.eventActionDefinitionArray[2].enabled == 0); - - CHECK(eventActionService.eventActionDefinitionArray[3].empty == 0); - CHECK(eventActionService.eventActionDefinitionArray[3].applicationId == 1); - CHECK(eventActionService.eventActionDefinitionArray[3].eventDefinitionID == 3); - CHECK(eventActionService.eventActionDefinitionArray[3].request.compare("3") == 0); - CHECK(eventActionService.eventActionDefinitionArray[3].enabled == 1); - - CHECK(eventActionService.eventActionDefinitionArray[4].empty == 1); - CHECK(eventActionService.eventActionDefinitionArray[4].applicationId == 0); - CHECK(eventActionService.eventActionDefinitionArray[4].eventDefinitionID == 65535); - CHECK(eventActionService.eventActionDefinitionArray[4].request.compare("") == 0); - CHECK(eventActionService.eventActionDefinitionArray[4].enabled == 0); + Message message5(19, 2, Message::TC, 0); + message5.appendUint16(1); + message5.appendEnum16(1); + message5.appendEnum16(2); + message5.appendEnum16(1); + eventActionService.deleteEventActionDefinitions(message5); + + // Checking the values after deleting some definitions + + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(0)->second.applicationId == 1); + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(0)->second.eventDefinitionID == 0); + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(0)->second.request.compare("0") == 0); + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(0)->second.enabled == 0); + + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(1)->second.applicationId == 1); + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(1)->second.eventDefinitionID == 1); + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(1)->second.request.compare("1") == 0); + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(1)->second.enabled == 0); + + CHECK(eventActionService.eventActionDefinitionMap.find(2) == eventActionService.eventActionDefinitionMap.end()); + + // Enabling a definition to check for errors in the case of an attempt to delete it + Message message8(19, 4, Message::TC, 0); + message8.appendUint16(1); + message8.appendEnum16(1); + message8.appendEnum16(1); + message8.appendEnum16(1); + eventActionService.enableEventActionDefinitions(message8); + + Message message6(19, 2, Message::TC, 0); + message6.appendUint16(1); + message6.appendEnum16(1); + message6.appendEnum16(1); + message6.appendEnum16(1); + eventActionService.deleteEventActionDefinitions(message6); + + // Checking for errors in the case mentioned above + CHECK(ServiceTests::thrownError(ErrorHandler::EventActionDeleteEnabledDefinitionError)); + CHECK(ServiceTests::countErrors() == 1); + + // Checking for errors in the case of an unknown definition + Message message7(19, 2, Message::TC, 0); + message7.appendUint16(1); + message7.appendEnum16(1); + message7.appendEnum16(10); + message7.appendEnum16(1); + eventActionService.deleteEventActionDefinitions(message7); + + CHECK(ServiceTests::thrownError(ErrorHandler::EventActionUnknownEventDefinitionError)); + CHECK(ServiceTests::countErrors() == 2); + + Message message9(19, 2, Message::TC, 0); + message9.appendUint16(1); + message9.appendEnum16(1); + message9.appendEnum16(1); + message9.appendEnum16(10); + eventActionService.deleteEventActionDefinitions(message9); + + CHECK(ServiceTests::thrownError(ErrorHandler::EventActionUnknownEventActionDefinitionIDError)); + CHECK(ServiceTests::countErrors() == 3); } -TEST_CASE("Delete all event-action definitions TC[19,3]", "[service][st09]") { +TEST_CASE("Delete all event-action definitions TC[19,3]", "[service][st19]") { + + // Adding event action definitions to delete them later Message message0(19, 1, Message::TC, 0); message0.appendEnum16(1); message0.appendEnum16(0); + message0.appendEnum16(1); String<64> data = "0"; message0.appendString(data); eventActionService.addEventActionDefinitions(message0); + Message message1(19, 1, Message::TC, 0); message1.appendEnum16(1); message1.appendEnum16(1); + message1.appendEnum16(1); data = "1"; message1.appendString(data); eventActionService.addEventActionDefinitions(message1); + Message message2(19, 1, Message::TC, 0); message2.appendEnum16(1); message2.appendEnum16(2); + message2.appendEnum16(1); data = "2"; message2.appendString(data); eventActionService.addEventActionDefinitions(message2); + Message message3(19, 1, Message::TC, 0); message3.appendEnum16(1); message3.appendEnum16(3); + message3.appendEnum16(1); data = "3"; message3.appendString(data); eventActionService.addEventActionDefinitions(message3); + Message message4(19, 1, Message::TC, 0); message4.appendEnum16(1); message4.appendEnum16(4); + message4.appendEnum16(1); data = "4"; message4.appendString(data); eventActionService.addEventActionDefinitions(message4); @@ -150,110 +199,219 @@ TEST_CASE("Delete all event-action definitions TC[19,3]", "[service][st09]") { Message message(19, 3, Message::TC, 0); eventActionService.deleteAllEventActionDefinitions(message); - for (int i = 0; i < 256; i++) { - CHECK(eventActionService.eventActionDefinitionArray[i].empty == 1); - CHECK(eventActionService.eventActionDefinitionArray[i].applicationId == 0); - CHECK(eventActionService.eventActionDefinitionArray[i].eventDefinitionID == 65535); - CHECK(eventActionService.eventActionDefinitionArray[i].request.compare("") == 0); + // Checking the content of the map + for (int i = 0; i < 256; i++){ + CHECK(eventActionService.eventActionDefinitionMap.find(i) == eventActionService.eventActionDefinitionMap.end()); } } -TEST_CASE("Enable event-action definitions TC[19,4]", "[service][st09]") { +TEST_CASE("Enable event-action definitions TC[19,4]", "[service][st19]") { + + // Adding event action definitions to enable them Message message0(19, 1, Message::TC, 0); message0.appendEnum16(1); message0.appendEnum16(0); + message0.appendEnum16(1); String<64> data = "0"; message0.appendString(data); eventActionService.addEventActionDefinitions(message0); + Message message1(19, 1, Message::TC, 0); message1.appendEnum16(1); message1.appendEnum16(1); + message1.appendEnum16(1); data = "00"; message1.appendString(data); eventActionService.addEventActionDefinitions(message1); - Message message2(19, 4, Message::TC, 0); - message2.appendUint16(2); - message2.appendEnum16(1); - message2.appendEnum16(0); - message2.appendEnum16(1); - message2.appendEnum16(1); - eventActionService.enableEventActionDefinitions(message2); - CHECK(eventActionService.eventActionDefinitionArray[0].enabled == 1); - CHECK(eventActionService.eventActionDefinitionArray[1].enabled == 1); + + // Checking their enabled status + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(0)->second.enabled == 0); + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(1)->second.enabled == 0); + + // Creating a message to enable the previous messages + Message message3(19, 4, Message::TC, 0); + message3.appendUint16(2); + message3.appendEnum16(1); + message3.appendEnum16(0); + message3.appendEnum16(1); + message3.appendEnum16(1); + message3.appendEnum16(1); + message3.appendEnum16(1); + eventActionService.enableEventActionDefinitions(message3); + + // Checking if the messages are enabled + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(0)->second.enabled == 1); + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(1)->second.enabled == 1); + + // Checking for errors in the case of an attempt to enable an unknown definition + Message message7(19, 4, Message::TC, 0); + message7.appendUint16(1); + message7.appendEnum16(1); + message7.appendEnum16(6); + eventActionService.enableEventActionDefinitions(message7); + + CHECK(ServiceTests::thrownError(ErrorHandler::EventActionUnknownEventDefinitionError)); + CHECK(ServiceTests::countErrors() == 1); + + // Checking for errors in the case of an attempt to enable an unknown definition + Message message8(19, 4, Message::TC, 0); + message8.appendUint16(1); + message8.appendEnum16(1); + message8.appendEnum16(1); + message8.appendEnum16(10); + eventActionService.enableEventActionDefinitions(message8); + + CHECK(ServiceTests::thrownError(ErrorHandler::EventActionUnknownEventActionDefinitionIDError)); + CHECK(ServiceTests::countErrors() == 2); } -TEST_CASE("Disable event-action definitions TC[19,5]", "[service][st09]") { +TEST_CASE("Disable event-action definitions TC[19,5]", "[service][st19]") { + + // Adding event action definitions to enable them Message message0(19, 1, Message::TC, 0); message0.appendEnum16(1); message0.appendEnum16(0); + message0.appendEnum16(1); String<64> data = "0"; message0.appendString(data); eventActionService.addEventActionDefinitions(message0); + Message message1(19, 1, Message::TC, 0); message1.appendEnum16(1); - message1.appendEnum16(0); + message1.appendEnum16(1); + message1.appendEnum16(1); data = "00"; message1.appendString(data); eventActionService.addEventActionDefinitions(message1); - Message message2(19, 5, Message::TC, 0); - message2.appendUint16(1); - message2.appendEnum16(1); - message2.appendEnum16(0); - eventActionService.disableEventActionDefinitions(message2); - CHECK(eventActionService.eventActionDefinitionArray[0].enabled == 0); - CHECK(eventActionService.eventActionDefinitionArray[1].enabled == 0); + + // Checking their enabled status + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(0)->second.enabled == 0); + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(1)->second.enabled == 0); + + // Creating a message to enable the previous messages + Message message3(19, 4, Message::TC, 0); + message3.appendUint16(2); + message3.appendEnum16(1); + message3.appendEnum16(0); + message3.appendEnum16(1); + message3.appendEnum16(1); + message3.appendEnum16(1); + message3.appendEnum16(1); + eventActionService.enableEventActionDefinitions(message3); + + // Checking if the messages are enabled + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(0)->second.enabled == 1); + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(1)->second.enabled == 1); + + // Creating a message to enable the previous messages + Message message4(19, 5, Message::TC, 0); + message4.appendUint16(2); + message4.appendEnum16(1); + message4.appendEnum16(0); + message4.appendEnum16(1); + message4.appendEnum16(1); + message4.appendEnum16(1); + message4.appendEnum16(1); + eventActionService.disableEventActionDefinitions(message4); + + // Checking if the messages are enabled + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(0)->second.enabled == 0); + CHECK(eventActionService.eventActionDefinitionMap.lower_bound(1)->second.enabled == 0); + + // Checking for errors in the case of an attempt to enable an unknown definition + Message message7(19, 5, Message::TC, 0); + message7.appendUint16(1); + message7.appendEnum16(1); + message7.appendEnum16(6); + eventActionService.disableEventActionDefinitions(message7); + + CHECK(ServiceTests::thrownError(ErrorHandler::EventActionUnknownEventDefinitionError)); + CHECK(ServiceTests::countErrors() == 1); + + // Checking for errors in the case of an attempt to enable an unknown definition + Message message8(19, 5, Message::TC, 0); + message8.appendUint16(1); + message8.appendEnum16(1); + message8.appendEnum16(1); + message8.appendEnum16(10); + eventActionService.disableEventActionDefinitions(message8); + + CHECK(ServiceTests::thrownError(ErrorHandler::EventActionUnknownEventActionDefinitionIDError)); + CHECK(ServiceTests::countErrors() == 2); } -TEST_CASE("Request event-action definition status TC[19,6]", "[service][st09]") { +TEST_CASE("Request event-action definition status TC[19,6]", "[service][st19]") { + + // Creating a request for a report on the event action definitions Message message(19, 6, Message::TC, 0); eventActionService.requestEventActionDefinitionStatus(message); REQUIRE(ServiceTests::hasOneMessage()); + // Checking that the report was made Message report = ServiceTests::get(0); CHECK(report.messageType == 7); } -TEST_CASE("Event-action status report TM[19,7]", "[service][st09]") { +TEST_CASE("Event-action status report TM[19,7]", "[service][st19]") { + + // Adding event-action definitions to report them Message message0(19, 1, Message::TC, 0); message0.appendEnum16(1); message0.appendEnum16(0); + message0.appendEnum16(1); String<64> data = "0"; message0.appendString(data); eventActionService.addEventActionDefinitions(message0); + Message message1(19, 1, Message::TC, 0); message1.appendEnum16(1); message1.appendEnum16(2); + message1.appendEnum16(1); data = "2"; message1.appendString(data); eventActionService.addEventActionDefinitions(message1); + + // Enablilng one of the two Message message2(19, 5, Message::TC, 0); message2.appendUint16(1); message2.appendEnum16(1); message2.appendEnum16(0); - eventActionService.disableEventActionDefinitions(message2); + message2.appendEnum16(1); + eventActionService.enableEventActionDefinitions(message2); + eventActionService.eventActionStatusReport(); REQUIRE(ServiceTests::hasOneMessage()); + // Checking the contents of the report Message report = ServiceTests::get(0); - CHECK(report.readUint8() == 2); + CHECK(report.readUint16() == 2); CHECK(report.readEnum16() == 1); CHECK(report.readEnum16() == 0); - CHECK(report.readUint8() == 0); + CHECK(report.readEnum16() == 1); + CHECK(report.readBoolean() == 1); CHECK(report.readEnum16() == 1); CHECK(report.readEnum16() == 2); - CHECK(report.readUint8() == 1); + CHECK(report.readEnum16() == 1); + CHECK(report.readBoolean() == 0); } -TEST_CASE("Enable event-action function TC[19,8]", "[service][st09]") { +TEST_CASE("Enable event-action function TC[19,8]", "[service][st19]") { + + // A message to enable event action function + Message message(19, 8, Message::TC, 0); eventActionService.enableEventActionFunction(message); - CHECK(eventActionService.getEventActionFunctionStatus() == true); + CHECK(eventActionService.getEventActionFunctionStatus()); } -TEST_CASE("Disable event-action function TC[19,9]", "[service][st09]") { +TEST_CASE("Disable event-action function TC[19,9]", "[service][st19]") { + + // A message to disable event action function Message message(19, 9, Message::TC, 0); eventActionService.disableEventActionFunction(message); CHECK(eventActionService.getEventActionFunctionStatus() == false); } -TEST_CASE("Execute a TC request", "[service][st09]") {} +TEST_CASE("Execute a TC request", "[service][st19]"){ + +}