From 8432c3d964d6c3fd3da8f09f7ee7cc16c21d4c1a Mon Sep 17 00:00:00 2001 From: kpetridis <petridkon@gmail.com> Date: Mon, 4 Apr 2022 12:21:58 +0300 Subject: [PATCH] Finalization of the add report types to app process config functino --- inc/Helpers/ForwardControlConfiguration.hpp | 18 ++- .../RealTimeForwardingControlService.hpp | 10 +- .../RealTimeForwardingControlService.cpp | 25 ++-- test/Services/RealTimeForwardingControl.cpp | 137 ++++++++++++------ 4 files changed, 124 insertions(+), 66 deletions(-) diff --git a/inc/Helpers/ForwardControlConfiguration.hpp b/inc/Helpers/ForwardControlConfiguration.hpp index 9ac00bef..ad47508c 100644 --- a/inc/Helpers/ForwardControlConfiguration.hpp +++ b/inc/Helpers/ForwardControlConfiguration.hpp @@ -7,6 +7,10 @@ #include "etl/map.h" #include "Helpers/Parameter.hpp" +/** + * Contains all the necessary configuration types, for the ST[14] 'Real Time Forwarding Control Service'. + * @author Konstantinos Petridis <petridkon@gmail.com> + */ namespace ForwardControlConfiguration { /** @@ -25,15 +29,14 @@ public: /** * Boolean values for each service type of an application process. See next documentation comment. */ - typedef etl::map<uint8_t, bool, ECSSMaxServiceTypeDefinitions> reportsAreNotEmpty; + typedef etl::map<uint8_t, bool, ECSSMaxServiceTypeDefinitions> reportsNotEmpty; /** - * Indicates the meaning of a service type being empty of report types. It specifies whether the 'empty' means that - * it has not been filled yet (so we proceed to add new report types) or it is empty because we accept every + * Translates the absence of report types, in a service type definition. It specifies whether the 'empty' means that + * it has not been filled yet (so we proceed to add new report types) or it is empty because we block every * report type for the service. - * TODO: rename to 'allServicesAllowed' */ - etl::map<uint8_t, reportsAreNotEmpty, ECSSMaxControlledApplications> serviceNotEmpty; + etl::map<uint8_t, reportsNotEmpty, ECSSMaxControlledApplications> notEmpty; /** * Vector containing the Report Type definitions. Each definition has its unique name of type uint8. For @@ -53,6 +56,7 @@ public: * key to provide access to the list of Service Type definitions, included by the application. */ etl::map<uint8_t, serviceTypeDefinitions, ECSSMaxControlledApplications> definitions; + ApplicationProcess() = default; }; @@ -77,6 +81,8 @@ public: * used as a key to provide access to the list of the Housekeeping structure IDs. */ typedef etl::map<uint8_t, housekeepingStructureIds, ECSSMaxControlledApplications> definitions; + + HousekeepingParameterReport() = default; }; /** @@ -100,6 +106,8 @@ public: * used as a key to provide access to the list of the Event Definitions. */ typedef etl::map<uint8_t, eventDefinitionIds, ECSSMaxControlledApplications> definitions; + + EventReportBlocking() = default; }; } // namespace ForwardControlConfiguration diff --git a/inc/Services/RealTimeForwardingControlService.hpp b/inc/Services/RealTimeForwardingControlService.hpp index fa88121b..2e231b7f 100644 --- a/inc/Services/RealTimeForwardingControlService.hpp +++ b/inc/Services/RealTimeForwardingControlService.hpp @@ -11,7 +11,7 @@ * Implementation of the ST[14] 'Real Time Forwarding Control Service' as defined in ECSS-E-ST-70-41C. * * @brief - * The purpose of this Service is to control the forwarding of the stores telemetry to the ground station. It includes + * The purpose of this Service is to control the forwarding of the stores' telemetry to the ground station. It includes * conditions for all the application processes that are controlled by the Service, which determine whether a message * should be forwarded to the ground station, through the corresponding virtual channel. * @@ -65,13 +65,13 @@ private: * Checks whether the specified message type already exists in the specified application process and service * type definition. */ - inline bool reportExistsInAppProcessConfiguration(uint8_t target, uint8_t applicationID, uint8_t serviceType); + bool reportExistsInAppProcessConfiguration(uint8_t target, uint8_t applicationID, uint8_t serviceType); /** * Performs the necessary error checking/logging for a specific application process ID. Also, skips the necessary * bytes from the request message, in case of an invalid request. */ - bool checkApplication1(Message& request, uint8_t applicationID, uint8_t numOfServices); + bool checkApplicationOfAppProcessConfig(Message& request, uint8_t applicationID, uint8_t numOfServices); /** * Checks if the specified application process is controlled by the Service and returns true if it does. @@ -93,7 +93,7 @@ private: * Performs the necessary error checking/logging for a specific service type. Also, skips the necessary bytes * from the request message, in case of an invalid request. */ - bool checkService1(Message& request, uint8_t applicationID, uint8_t serviceType, uint8_t numOfMessages); + bool checkService(Message& request, uint8_t applicationID, uint8_t serviceType, uint8_t numOfMessages); /** * Checks if all report types are allowed already, i.e. if the service type definition contains no report type @@ -110,7 +110,7 @@ private: * Checks if the maximum number of message types that can be contained inside a service type definition, is * already reached. */ - bool checkMessage1(Message& request, uint8_t applicationID, uint8_t serviceType, uint8_t messageType); + bool checkMessage(Message& request, uint8_t applicationID, uint8_t serviceType, uint8_t messageType); public: /** diff --git a/src/Services/RealTimeForwardingControlService.cpp b/src/Services/RealTimeForwardingControlService.cpp index 98d61e43..3c6c3ab8 100644 --- a/src/Services/RealTimeForwardingControlService.cpp +++ b/src/Services/RealTimeForwardingControlService.cpp @@ -10,8 +10,8 @@ bool RealTimeForwardingControlService::appIsControlled(Message& request, uint8_t return true; } -bool RealTimeForwardingControlService::checkApplication1(Message& request, uint8_t applicationID, - uint8_t numOfServices) { +bool RealTimeForwardingControlService::checkApplicationOfAppProcessConfig(Message& request, uint8_t applicationID, + uint8_t numOfServices) { if (not appIsControlled(request, applicationID) or allServiceTypesAllowed(request, applicationID)) { for (uint8_t l = 0; l < numOfServices; l++) { request.skipBytes(1); @@ -25,7 +25,7 @@ bool RealTimeForwardingControlService::checkApplication1(Message& request, uint8 bool RealTimeForwardingControlService::allServiceTypesAllowed(Message& request, uint8_t applicationID) { if (applicationProcessConfiguration.definitions[applicationID].empty() and - not applicationProcessConfiguration.serviceNotEmpty[applicationID].empty()) { + not applicationProcessConfiguration.notEmpty[applicationID].empty()) { ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::AllServiceTypesAlreadyAllowed); return true; } @@ -40,8 +40,8 @@ bool RealTimeForwardingControlService::maxServiceTypesReached(Message& request, return false; } -bool RealTimeForwardingControlService::checkService1(Message& request, uint8_t applicationID, uint8_t serviceType, - uint8_t numOfMessages) { +bool RealTimeForwardingControlService::checkService(Message& request, uint8_t applicationID, uint8_t serviceType, + uint8_t numOfMessages) { if (maxServiceTypesReached(request, applicationID) or allReportTypesAllowed(request, applicationID, serviceType)) { request.skipBytes(numOfMessages); return false; @@ -52,7 +52,7 @@ bool RealTimeForwardingControlService::checkService1(Message& request, uint8_t a bool RealTimeForwardingControlService::allReportTypesAllowed(Message& request, uint8_t applicationID, uint8_t serviceType) { if (applicationProcessConfiguration.definitions[applicationID][serviceType].empty() and - applicationProcessConfiguration.serviceNotEmpty[applicationID][serviceType]) { + applicationProcessConfiguration.notEmpty[applicationID][serviceType]) { ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::AllReportTypesAlreadyAllowed); return true; } @@ -69,11 +69,10 @@ bool RealTimeForwardingControlService::maxReportTypesReached(Message& request, u return false; } -bool RealTimeForwardingControlService::checkMessage1(Message& request, uint8_t applicationID, uint8_t serviceType, - uint8_t messageType) { +bool RealTimeForwardingControlService::checkMessage(Message& request, uint8_t applicationID, uint8_t serviceType, + uint8_t messageType) { if (maxReportTypesReached(request, applicationID, serviceType) or reportExistsInAppProcessConfiguration(messageType, applicationID, serviceType)) { - // request.skipBytes(1); return false; } return true; @@ -94,7 +93,7 @@ void RealTimeForwardingControlService::addReportTypesToAppProcessConfiguration(M uint8_t applicationID = request.readUint8(); uint8_t numOfServices = request.readUint8(); - if (not checkApplication1(request, applicationID, numOfServices)) { + if (not checkApplicationOfAppProcessConfig(request, applicationID, numOfServices)) { continue; } @@ -108,7 +107,7 @@ void RealTimeForwardingControlService::addReportTypesToAppProcessConfiguration(M uint8_t serviceType = request.readUint8(); uint8_t numOfMessages = request.readUint8(); - if (not checkService1(request, applicationID, serviceType, numOfMessages)) { + if (not checkService(request, applicationID, serviceType, numOfMessages)) { continue; } @@ -120,13 +119,13 @@ void RealTimeForwardingControlService::addReportTypesToAppProcessConfiguration(M for (uint8_t k = 0; k < numOfMessages; k++) { uint8_t messageType = request.readUint8(); - if (not checkMessage1(request, applicationID, serviceType, messageType)) { + if (not checkMessage(request, applicationID, serviceType, messageType)) { continue; } // todo: check if message type is valid. applicationProcessConfiguration.definitions[applicationID][serviceType].push_back(messageType); - applicationProcessConfiguration.serviceNotEmpty[applicationID][serviceType] = true; + applicationProcessConfiguration.notEmpty[applicationID][serviceType] = true; } } } diff --git a/test/Services/RealTimeForwardingControl.cpp b/test/Services/RealTimeForwardingControl.cpp index 32570d23..ebf08f41 100644 --- a/test/Services/RealTimeForwardingControl.cpp +++ b/test/Services/RealTimeForwardingControl.cpp @@ -17,7 +17,7 @@ uint8_t messages1[] = {HousekeepingService::MessageType::HousekeepingPeriodicPro uint8_t messages2[] = {EventReportService::MessageType::InformativeEventReport, EventReportService::MessageType::DisabledListEventReport}; -void initializeValid(Message& request) { +void validReportTypes(Message& request) { uint8_t numOfApplications = 1; uint8_t numOfServicesPerApp = 2; uint8_t numOfMessagesPerService = 2; @@ -39,22 +39,32 @@ void initializeValid(Message& request) { } } } +} + +void duplicateReportTypes(Message& request) { + uint8_t numOfApplications = 1; + uint8_t numOfServicesPerApp = 2; + uint8_t numOfMessagesPerService = 2; + + request.appendUint8(numOfApplications); + + for (auto appID : applications) { + request.appendUint8(appID); + request.appendUint8(numOfServicesPerApp); + + for (uint8_t j = 0; j < numOfServicesPerApp; j++) { + uint8_t serviceType = services[j]; + request.appendUint8(serviceType); + request.appendUint8(numOfMessagesPerService); - REQUIRE(request.readUint8() == 1); - REQUIRE(request.readUint8() == 1); - REQUIRE(request.readUint8() == 2); - REQUIRE(request.readUint8() == 3); - REQUIRE(request.readUint8() == 2); - REQUIRE(request.readUint8() == HousekeepingService::MessageType::HousekeepingPeriodicPropertiesReport); - REQUIRE(request.readUint8() == HousekeepingService::MessageType::DisablePeriodicHousekeepingParametersReport); - REQUIRE(request.readUint8() == 5); - REQUIRE(request.readUint8() == 2); - REQUIRE(request.readUint8() == EventReportService::MessageType::InformativeEventReport); - REQUIRE(request.readUint8() == EventReportService::MessageType::DisabledListEventReport); - request.resetRead(); + for (uint8_t k = 0; k < numOfMessagesPerService; k++) { + request.appendUint8(messages1[0]); + } + } + } } -void initializeCombined(Message& request) { +void validInvalidReportTypes(Message& request) { uint8_t numOfApplications = 3; uint8_t numOfMessagesPerService = 2; @@ -80,7 +90,7 @@ void initializeCombined(Message& request) { } } -void allReportsOfService(Message& request) { +void validAllReportsOfService(Message& request) { uint8_t numOfApplications = 1; uint8_t numOfServicesPerApp = 2; uint8_t numOfMessagesPerService = 0; @@ -99,7 +109,7 @@ void allReportsOfService(Message& request) { } } -void allReportsOfServiceCombined(Message& request) { +void validInvalidAllReportsOfService(Message& request) { uint8_t numOfApplications = 3; uint8_t numOfMessagesPerService = 2; @@ -128,7 +138,7 @@ void allReportsOfServiceCombined(Message& request) { } } -void allReportTypesOfApp(Message& request) { +void validAllReportsOfApp(Message& request) { uint8_t numOfApplications = 1; uint8_t numOfServicesPerApp = 0; @@ -140,7 +150,7 @@ void allReportTypesOfApp(Message& request) { } } -void allReportsOfAppCombined(Message& request) { +void validInvalidAllReportsOfApp(Message& request) { uint8_t numOfApplications = 3; uint8_t numOfMessagesPerService = 2; @@ -183,7 +193,7 @@ TEST_CASE("Add report types to the Application Process Configuration") { uint8_t applicationID = 1; realTimeForwarding.controlledApplications.push_back(applicationID); - initializeValid(request); + validReportTypes(request); MessageParser::execute(request); @@ -209,7 +219,7 @@ TEST_CASE("Add report types to the Application Process Configuration") { } } - auto& servicesAllowed = realTimeForwarding.applicationProcessConfiguration.serviceNotEmpty; + auto& servicesAllowed = realTimeForwarding.applicationProcessConfiguration.notEmpty; REQUIRE(servicesAllowed[applicationID].size() == 2); REQUIRE(servicesAllowed[applicationID][services[0]] == true); REQUIRE(servicesAllowed[applicationID][services[1]] == true); @@ -225,14 +235,14 @@ TEST_CASE("Add report types to the Application Process Configuration") { Message::TC, 1); uint8_t applicationID = 1; - initializeValid(request); + validReportTypes(request); MessageParser::execute(request); CHECK(ServiceTests::count() == 1); CHECK(ServiceTests::countThrownErrors(ErrorHandler::ExecutionStartErrorType::NotControlledApplication) == 1); REQUIRE(realTimeForwarding.applicationProcessConfiguration.definitions.empty()); - REQUIRE(realTimeForwarding.applicationProcessConfiguration.serviceNotEmpty[applicationID].empty()); + REQUIRE(realTimeForwarding.applicationProcessConfiguration.notEmpty[applicationID].empty()); resetAppProcessConfiguration(); ServiceTests::reset(); @@ -246,11 +256,11 @@ TEST_CASE("Add report types to the Application Process Configuration") { uint8_t applicationID = 1; realTimeForwarding.controlledApplications.push_back(applicationID); - initializeValid(request); + validReportTypes(request); realTimeForwarding.applicationProcessConfiguration.definitions[applicationID].clear(); CHECK(realTimeForwarding.applicationProcessConfiguration.definitions[applicationID].empty()); - realTimeForwarding.applicationProcessConfiguration.serviceNotEmpty[applicationID][services[0]] = true; + realTimeForwarding.applicationProcessConfiguration.notEmpty[applicationID][services[0]] = true; MessageParser::execute(request); @@ -271,23 +281,23 @@ TEST_CASE("Add report types to the Application Process Configuration") { uint8_t applicationID = 1; realTimeForwarding.controlledApplications.push_back(applicationID); - initializeValid(request); + validReportTypes(request); auto& applicationProcessConfig = realTimeForwarding.applicationProcessConfiguration; for (auto service : allServices) { applicationProcessConfig.definitions[applicationID][service].clear(); - applicationProcessConfig.serviceNotEmpty[applicationID][service] = true; + applicationProcessConfig.notEmpty[applicationID][service] = true; } REQUIRE(applicationProcessConfig.definitions[applicationID].size() == 15); - REQUIRE(applicationProcessConfig.serviceNotEmpty[applicationID].size() == 15); + REQUIRE(applicationProcessConfig.notEmpty[applicationID].size() == 15); MessageParser::execute(request); CHECK(ServiceTests::count() == 2); CHECK(ServiceTests::countThrownErrors(ErrorHandler::ExecutionStartErrorType::MaxServiceTypesReached) == 2); REQUIRE(applicationProcessConfig.definitions[applicationID].size() == 15); - REQUIRE(applicationProcessConfig.serviceNotEmpty[applicationID].size() == 15); + REQUIRE(applicationProcessConfig.notEmpty[applicationID].size() == 15); resetAppProcessConfiguration(); ServiceTests::reset(); @@ -302,11 +312,11 @@ TEST_CASE("Add report types to the Application Process Configuration") { uint8_t applicationID = 1; uint8_t serviceType = services[0]; realTimeForwarding.controlledApplications.push_back(applicationID); - initializeValid(request); + validReportTypes(request); realTimeForwarding.applicationProcessConfiguration.definitions[applicationID][serviceType].clear(); CHECK(realTimeForwarding.applicationProcessConfiguration.definitions[applicationID][serviceType].empty()); - realTimeForwarding.applicationProcessConfiguration.serviceNotEmpty[applicationID][serviceType] = true; + realTimeForwarding.applicationProcessConfiguration.notEmpty[applicationID][serviceType] = true; MessageParser::execute(request); @@ -328,17 +338,17 @@ TEST_CASE("Add report types to the Application Process Configuration") { uint8_t applicationID = 1; uint8_t serviceType = services[0]; realTimeForwarding.controlledApplications.push_back(applicationID); - initializeValid(request); + validReportTypes(request); auto& applicationProcessConfig = realTimeForwarding.applicationProcessConfiguration; - applicationProcessConfig.serviceNotEmpty[applicationID][serviceType] = true; + applicationProcessConfig.notEmpty[applicationID][serviceType] = true; for (uint8_t i = 0; i < ECSSMaxReportTypeDefinitions; i++) { applicationProcessConfig.definitions[applicationID][serviceType].push_back(i); } REQUIRE(applicationProcessConfig.definitions[applicationID].size() == 1); - REQUIRE(applicationProcessConfig.serviceNotEmpty[applicationID].size() == 1); + REQUIRE(applicationProcessConfig.notEmpty[applicationID].size() == 1); REQUIRE(applicationProcessConfig.definitions[applicationID][serviceType].size() == ECSSMaxReportTypeDefinitions); @@ -347,7 +357,7 @@ TEST_CASE("Add report types to the Application Process Configuration") { CHECK(ServiceTests::count() == 2); CHECK(ServiceTests::countThrownErrors(ErrorHandler::ExecutionStartErrorType::MaxReportTypesReached) == 2); REQUIRE(applicationProcessConfig.definitions[applicationID].size() == 2); - REQUIRE(applicationProcessConfig.serviceNotEmpty[applicationID].size() == 2); + REQUIRE(applicationProcessConfig.notEmpty[applicationID].size() == 2); REQUIRE(applicationProcessConfig.definitions[applicationID][services[1]].size() == 2); REQUIRE(applicationProcessConfig.definitions[applicationID][serviceType].size() == ECSSMaxReportTypeDefinitions); @@ -357,6 +367,47 @@ TEST_CASE("Add report types to the Application Process Configuration") { Services.reset(); } + SECTION("Requested addition of duplicate report type definitions") { + Message request(RealTimeForwardingControlService::ServiceType, + RealTimeForwardingControlService::MessageType::AddReportTypesToAppProcessConfiguration, + Message::TC, 1); + + uint8_t applicationID = 1; + realTimeForwarding.controlledApplications.push_back(applicationID); + duplicateReportTypes(request); + + MessageParser::execute(request); + + CHECK(ServiceTests::count() == 0); + auto& applicationProcesses = realTimeForwarding.applicationProcessConfiguration.definitions; + REQUIRE(applicationProcesses.size() == 1); + + for (auto appID : applications) { + REQUIRE(applicationProcesses.find(appID) != applicationProcesses.end()); + REQUIRE(applicationProcesses[appID].size() == 2); + + for (auto& serviceType : services) { + REQUIRE(applicationProcesses[appID].find(serviceType) != applicationProcesses[appID].end()); + REQUIRE(applicationProcesses[appID][serviceType].size() == 1); + + for (uint8_t k = 0; k < 2; k++) { + REQUIRE(std::find(applicationProcesses[appID][serviceType].begin(), + applicationProcesses[appID][serviceType].end(), + messages1[0]) != applicationProcesses[appID][serviceType].end()); + } + } + } + + auto& servicesAllowed = realTimeForwarding.applicationProcessConfiguration.notEmpty; + REQUIRE(servicesAllowed[applicationID].size() == 2); + REQUIRE(servicesAllowed[applicationID][services[0]] == true); + REQUIRE(servicesAllowed[applicationID][services[1]] == true); + + resetAppProcessConfiguration(); + ServiceTests::reset(); + Services.reset(); + } + SECTION("Valid and invalid application-related requests combined") { Message request(RealTimeForwardingControlService::ServiceType, RealTimeForwardingControlService::MessageType::AddReportTypesToAppProcessConfiguration, @@ -367,11 +418,11 @@ TEST_CASE("Add report types to the Application Process Configuration") { uint8_t applicationID3 = 3; realTimeForwarding.controlledApplications.push_back(applicationID1); realTimeForwarding.controlledApplications.push_back(applicationID3); - initializeCombined(request); + validInvalidReportTypes(request); realTimeForwarding.applicationProcessConfiguration.definitions[applicationID3].clear(); CHECK(realTimeForwarding.applicationProcessConfiguration.definitions[applicationID3].empty()); - realTimeForwarding.applicationProcessConfiguration.serviceNotEmpty[applicationID3][services[0]] = true; + realTimeForwarding.applicationProcessConfiguration.notEmpty[applicationID3][services[0]] = true; MessageParser::execute(request); @@ -382,7 +433,7 @@ TEST_CASE("Add report types to the Application Process Configuration") { 1); auto& applicationProcesses = realTimeForwarding.applicationProcessConfiguration.definitions; - auto& servicesAllowed = realTimeForwarding.applicationProcessConfiguration.serviceNotEmpty; + auto& servicesAllowed = realTimeForwarding.applicationProcessConfiguration.notEmpty; REQUIRE(applicationProcesses.size() == 2); REQUIRE(applicationProcesses.find(applicationID2) == applicationProcesses.end()); @@ -421,7 +472,7 @@ TEST_CASE("Add report types to the Application Process Configuration") { Message::TC, 1); uint8_t applicationID1 = 1; realTimeForwarding.controlledApplications.push_back(applicationID1); - allReportsOfService(request); + validAllReportsOfService(request); MessageParser::execute(request); @@ -447,7 +498,7 @@ TEST_CASE("Add report types to the Application Process Configuration") { uint8_t applicationID2 = 2; realTimeForwarding.controlledApplications.push_back(applicationID1); realTimeForwarding.controlledApplications.push_back(applicationID2); - allReportsOfServiceCombined(request); + validInvalidAllReportsOfService(request); MessageParser::execute(request); @@ -460,10 +511,10 @@ TEST_CASE("Add report types to the Application Process Configuration") { REQUIRE(applicationProcesses[applicationID1].size() == 15); REQUIRE(applicationProcesses[applicationID2].size() == 2); - for (auto& serviceType: applicationProcesses[applicationID1]) { + for (auto& serviceType : applicationProcesses[applicationID1]) { REQUIRE(serviceType.second.empty()); } - for (auto& serviceType: applicationProcesses[applicationID2]) { + for (auto& serviceType : applicationProcesses[applicationID2]) { REQUIRE(serviceType.second.empty()); } @@ -478,7 +529,7 @@ TEST_CASE("Add report types to the Application Process Configuration") { Message::TC, 1); uint8_t applicationID1 = 1; realTimeForwarding.controlledApplications.push_back(applicationID1); - allReportTypesOfApp(request); + validAllReportsOfApp(request); MessageParser::execute(request); @@ -499,7 +550,7 @@ TEST_CASE("Add report types to the Application Process Configuration") { uint8_t applicationID2 = 2; realTimeForwarding.controlledApplications.push_back(applicationID1); realTimeForwarding.controlledApplications.push_back(applicationID2); - allReportsOfAppCombined(request); + validInvalidAllReportsOfApp(request); MessageParser::execute(request); -- GitLab