diff --git a/CMakeLists.txt b/CMakeLists.txt
index 037f051530f4e6a8d23967a464d3a5b11667110a..227d2632f485b8692952f3bb3f140c080bad21a1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -41,7 +41,9 @@ add_library(common OBJECT
         src/Services/FunctionManagementService.cpp
         src/Services/HousekeepingService.cpp
         src/Services/ParameterStatisticsService.cpp
+        src/Services/OnBoardMonitoringService.cpp
         src/Helpers/Statistic.cpp
+        src/Helpers/PMONBase.cpp
         )
 
 # Specify the .cpp files for the executables
diff --git a/inc/ECSS_Definitions.hpp b/inc/ECSS_Definitions.hpp
index 7f836e5ca6244c4c370164a941ba1509f1523678..e5df0e60eca65475428e28b60c79df2e350dfc67 100644
--- a/inc/ECSS_Definitions.hpp
+++ b/inc/ECSS_Definitions.hpp
@@ -164,6 +164,11 @@ inline const bool SupportsStandardDeviation = true;
  */
 inline const uint8_t ECSSMaxHousekeepingStructures = 10;
 
+/**
+ * Maximum number of ST[12] Parameter Monitoring Definitions.
+ */
+inline const uint8_t ECSSMaxMonitoringDefinitions = 4;
+
 /** @} */
 
 #endif // ECSS_SERVICES_ECSS_DEFINITIONS_H
diff --git a/inc/ErrorHandler.hpp b/inc/ErrorHandler.hpp
index b05d465fedb11f28a8b2cd827586b7321fae94c3..32d7f33308943e8649989ddf6f9cf5f1eb033880 100644
--- a/inc/ErrorHandler.hpp
+++ b/inc/ErrorHandler.hpp
@@ -158,52 +158,97 @@ public:
 		/**
 		 * Attempt to add definition to the struct map but its already full. (ST[19])
 		 */
-		EventActionDefinitionsMapIsFull = 11,
+		EventActionDefinitionsMapIsFull = 9,
 		/**
 		 * Attempt to report/delete non existing housekeeping structure (ST[03])
 		 */
-		RequestedNonExistingStructure = 12,
+		RequestedNonExistingStructure = 10,
 		/**
 		 * Attempt to create already created structure (ST[03])
 		 */
-		RequestedAlreadyExistingStructure = 13,
+		RequestedAlreadyExistingStructure = 11,
 		/**
 		 * Attempt to delete structure which has the periodic reporting status enabled (ST[03]) as per 6.3.3.5.2(d-2)
 		 */
-		RequestedDeletionOfEnabledHousekeeping = 14,
+		RequestedDeletionOfEnabledHousekeeping = 12,
 		/**
 		 * Attempt to append a new parameter ID to a housekeeping structure, but the ID is already in the structure
 		 * (ST[03])
 		 */
-		AlreadyExistingParameter = 15,
+		AlreadyExistingParameter = 13,
 		/**
 		 * Attempt to append a new parameter id to a housekeeping structure, but the periodic generation status is
 		 * enabled (ST[03])
 		 */
-		RequestedAppendToEnabledHousekeeping = 16,
+		RequestedAppendToEnabledHousekeeping = 14,
 		/**
 		 * Attempt to create a new housekeeping structure in Housekeeping Service, when the maximum number of
 		 * housekeeping structures is already reached (ST[03])
 		 */
-		ExceededMaxNumberOfHousekeepingStructures = 17,
+		ExceededMaxNumberOfHousekeepingStructures = 15,
 		/**
 		 * Attempt to add a new simply commutated parameter in a specific housekeeping structure, but the maximum
 		 * number of simply commutated parameters for this structure is already reached (ST[03])
 		 */
-		ExceededMaxNumberOfSimplyCommutatedParameters = 18,
+		ExceededMaxNumberOfSimplyCommutatedParameters = 16,
 		/* Attempt to set a reporting rate which is smaller than the parameter sampling rate.
 		 * ST[04]
 		 */
-		InvalidReportingRateError = 19,
+		InvalidReportingRateError = 17,
 		/**
 		 * Attempt to set a sampling rate which is greater than the parameter reporting rate.
 		 * ST[04]
 		 */
-		InvalidSamplingRateError = 20,
+		InvalidSamplingRateError = 18,
 		/**
 		 * Attempt to add new statistic definition but the maximum number is already reached (ST[04])
 		 */
-		MaxStatisticDefinitionsReached = 21,
+		MaxStatisticDefinitionsReached = 19,
+		/**
+		 * Attempt to delete all parameter monitoring definitions but the Parameter Monitoring Function Status is
+		 * enabled.
+		 */
+		InvalidRequestToDeleteAllParameterMonitoringDefinitions = 20,
+		/**
+		 * Attempt to delete one parameter monitoring definition but its Parameter Monitoring Status is
+		 * enabled.
+		 */
+		InvalidRequestToDeleteParameterMonitoringDefinition = 21,
+		/**
+		 * Attempt to add a parameter that already exists to the Parameter Monitoring List.
+		 */
+		AddAlreadyExistingParameter = 22,
+		/**
+		 * Attempt to add a parameter in the Parameter Monitoring List but it's full
+		 */
+		ParameterMonitoringListIsFull = 23,
+		/**
+		 * Attempt to add or modify a limit check parameter monitoring definition, but the high limit is lower than
+		 * the low limit.
+		 */
+		HighLimitIsLowerThanLowLimit = 24,
+		/**
+		 * Attempt to add or modify a delta check parameter monitoring definition, but the high threshold is lower than
+		 * the low threshold.
+		 */
+		HighThresholdIsLowerThanLowThreshold = 25,
+		/**
+		 * Attempt to modify a non existent Parameter Monitoring definition.
+		 */
+		ModifyParameterNotInTheParameterMonitoringList = 26,
+		/**
+		 * Attempt to modify a parameter monitoring definition, but the instruction refers to a monitored parameter
+		 * that is not the one used in that parameter monitoring definition.
+		 */
+		DifferentParameterMonitoringDefinitionAndMonitoredParameter = 27,
+		/**
+		 * Attempt to get a parameter monitoring definition that does not exist.
+		 */
+		GetNonExistingParameterMonitoringDefinition = 28,
+		/**
+		 * Request to report a non existent parameter monitoring definition.
+		 */
+		ReportParameterNotInTheParameterMonitoringList = 29
 	};
 
 	/**
diff --git a/inc/Helpers/PMONBase.hpp b/inc/Helpers/PMONBase.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..66c00e58ff877d4b3c4f11b718ef6c83aeb7860e
--- /dev/null
+++ b/inc/Helpers/PMONBase.hpp
@@ -0,0 +1,102 @@
+#ifndef ECSS_SERVICES_PMONBASE_HPP
+#define ECSS_SERVICES_PMONBASE_HPP
+#include <cstdint>
+#include "Message.hpp"
+#include "etl/array.h"
+#include "Service.hpp"
+#include "Helpers/Parameter.hpp"
+#include "etl/map.h"
+#include "ECSS_Definitions.hpp"
+#include "etl/list.h"
+
+/**
+ * Base class for Parameter Monitoring definitions. Contains the common variables of all check types.
+ */
+class PMONBase {
+public:
+	enum CheckingStatus : uint8_t {
+		Unchecked = 1,
+		Invalid = 2,
+		ExpectedValue = 3,
+		UnexpectedValue = 4,
+		WithinLimits = 5,
+		BelowLowLimit = 6,
+		AboveHighLimit = 7,
+		WithinThreshold = 8,
+		BelowLowThreshold = 9,
+		AboveHighThreshold = 10
+	};
+
+	uint16_t monitoredParameterId;
+
+	std::reference_wrapper<ParameterBase> monitoredParameter;
+	/**
+	 * The number of checks that need to be conducted in order to set a new Parameter Monitoring Status.
+	 */
+	uint16_t repetitionNumber;
+	/**
+	 * The number of checks that have been conducted so far.
+	 */
+	uint16_t repetitionCounter = 0;
+	bool monitoringEnabled = false;
+	CheckingStatus checkingStatus = Unchecked;
+	etl::array<CheckingStatus, 2> checkTransitionList = {};
+
+protected:
+	/**
+	 * @param monitoredParameterId is assumed to be correct and not checked.
+	 */
+	PMONBase(uint16_t monitoredParameterId, uint16_t repetitionNumber);
+};
+
+/**
+ * Contains the variables specific to Parameter Monitoring definitions of expected value check type.
+ */
+class PMONExpectedValueCheck : public PMONBase {
+public:
+	double expectedValue;
+	uint64_t mask;
+	uint16_t unexpectedValueEvent;
+
+	explicit PMONExpectedValueCheck(uint16_t monitoredParameterId, uint16_t repetitionNumber, double expectedValue,
+	                                uint64_t mask, uint16_t unexpectedValueEvent)
+	    : expectedValue(expectedValue), mask(mask), unexpectedValueEvent(unexpectedValueEvent),
+	      PMONBase(monitoredParameterId, repetitionNumber){};
+};
+
+/**
+ * Contains the variables specific to Parameter Monitoring definitions of limit check type.
+ */
+class PMONLimitCheck : public PMONBase {
+public:
+	double lowLimit;
+	uint16_t belowLowLimitEvent;
+	double highLimit;
+	uint16_t aboveHighLimitEvent;
+
+	explicit PMONLimitCheck(uint16_t monitoredParameterId, uint16_t repetitionNumber, double lowLimit,
+	                        uint16_t belowLowLimitEvent, double highLimit, uint16_t aboveHighLimitEvent)
+	    : lowLimit(lowLimit), belowLowLimitEvent(belowLowLimitEvent), highLimit(highLimit),
+	      aboveHighLimitEvent(aboveHighLimitEvent), PMONBase(monitoredParameterId, repetitionNumber){};
+};
+
+/**
+ * Contains the variables specific to Parameter Monitoring definitions of delta check type.
+ */
+class PMONDeltaCheck : public PMONBase {
+public:
+	uint16_t numberOfConsecutiveDeltaChecks;
+	double lowDeltaThreshold;
+	uint16_t belowLowThresholdEvent;
+	double highDeltaThreshold;
+	uint16_t aboveHighThresholdEvent;
+
+	explicit PMONDeltaCheck(uint16_t monitoredParameterId, uint16_t repetitionNumber,
+	                        uint16_t numberOfConsecutiveDeltaChecks, double lowDeltaThreshold,
+	                        uint16_t belowLowThresholdEvent, double highDeltaThreshold,
+	                        uint16_t aboveHighThresholdEvent)
+	    : numberOfConsecutiveDeltaChecks(numberOfConsecutiveDeltaChecks), lowDeltaThreshold(lowDeltaThreshold),
+	      belowLowThresholdEvent(belowLowThresholdEvent), highDeltaThreshold(highDeltaThreshold),
+	      aboveHighThresholdEvent(aboveHighThresholdEvent), PMONBase(monitoredParameterId, repetitionNumber){};
+};
+#endif // ECSS_SERVICES_PMONBASE_HPP
diff --git a/inc/Platform/x86/ECSS_Configuration.hpp b/inc/Platform/x86/ECSS_Configuration.hpp
index 07a47a4c254d5fb787f806e4c21aaeb4ae572d8a..c03814e5ad812c932c576df81c0d21917ca659dd 100644
--- a/inc/Platform/x86/ECSS_Configuration.hpp
+++ b/inc/Platform/x86/ECSS_Configuration.hpp
@@ -21,19 +21,20 @@
 #define SERVICE_ALL ///< Enables compilation of all the ECSS services
 
 #ifdef SERVICE_ALL
-#define SERVICE_EVENTACTION         ///<  Compile ST[19] event-action
-#define SERVICE_EVENTREPORT         ///<  Compile ST[05] event reporting
-#define SERVICE_FUNCTION            ///<  Compile ST[08] function management
-#define SERVICE_HOUSEKEEPING        ///<  Compile ST[03] housekeeping
-#define SERVICE_LARGEPACKET         ///<  Compile ST[13] large packet transfer
-#define SERVICE_MEMORY              ///<  Compile ST[06] memory management
-#define SERVICE_PARAMETER           ///<  Compile ST[20] parameter management
+#define SERVICE_EVENTACTION ///<  Compile ST[19] event-action
+#define SERVICE_EVENTREPORT ///<  Compile ST[05] event reporting
+#define SERVICE_FUNCTION ///<  Compile ST[08] function management
+#define SERVICE_HOUSEKEEPING ///<  Compile ST[03] housekeeping
+#define SERVICE_LARGEPACKET ///<  Compile ST[13] large packet transfer
+#define SERVICE_MEMORY ///<  Compile ST[06] memory management
+#define SERVICE_ONBOARDMONITORING ///<  Compile ST[12] on-board monitoring
+#define SERVICE_PARAMETER ///<  Compile ST[20] parameter management
 #define SERVICE_PARAMETERSTATISTICS ///<  Compile ST[04] parameter statistics
 #define SERVICE_REQUESTVERIFICATION ///<  Compile ST[01] request verification
-#define SERVICE_TEST                ///<  Compile ST[17] test
-#define SERVICE_TIME                ///<  Compile ST[09] time management
-#define SERVICE_TIMESCHEDULING      ///<  Compile ST[11] time-based scheduling
+#define SERVICE_TEST ///<  Compile ST[17] test
+#define SERVICE_TIME ///<  Compile ST[09] time management
+#define SERVICE_TIMESCHEDULING ///<  Compile ST[11] time-based scheduling
 #endif
 /** @} */
 
-#endif //ECSS_SERVICES_ECSS_CONFIGURATION_HPP
+#endif // ECSS_SERVICES_ECSS_CONFIGURATION_HPP
diff --git a/inc/ServicePool.hpp b/inc/ServicePool.hpp
index 544b7460c93ca76b53d3ff76d5f321750085efb3..a916cb82cee3e93b7560c4c7d07ec1b9d51239a0 100644
--- a/inc/ServicePool.hpp
+++ b/inc/ServicePool.hpp
@@ -13,6 +13,7 @@
 #include "Services/FunctionManagementService.hpp"
 #include "Services/HousekeepingService.hpp"
 #include "Services/ParameterStatisticsService.hpp"
+#include "Services/OnBoardMonitoringService.hpp"
 
 /**
  * Defines a class that contains instances of all Services.
@@ -36,10 +37,6 @@ class ServicePool {
 	uint16_t packetSequenceCounter = 0;
 
 public:
-#ifdef SERVICE_PARAMETERSTATISTICS
-	ParameterStatisticsService parameterStatistics;
-#endif
-
 #ifdef SERVICE_EVENTACTION
 	EventActionService eventAction;
 #endif
@@ -64,10 +61,18 @@ public:
 	MemoryManagementService memoryManagement;
 #endif
 
+#ifdef SERVICE_ONBOARDMONITORING
+	OnBoardMonitoringService onBoardMonitoringService;
+#endif
+
 #ifdef SERVICE_PARAMETER
 	ParameterService parameterManagement;
 #endif
 
+#ifdef SERVICE_PARAMETERSTATISTICS
+	ParameterStatisticsService parameterStatistics;
+#endif
+
 #ifdef SERVICE_REQUESTVERIFICATION
 	RequestVerificationService requestVerification;
 #endif
diff --git a/inc/Services/OnBoardMonitoringService.hpp b/inc/Services/OnBoardMonitoringService.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..1ef954f2f6f4356436047b1909bc75dcd95d45b4
--- /dev/null
+++ b/inc/Services/OnBoardMonitoringService.hpp
@@ -0,0 +1,96 @@
+#ifndef ECSS_SERVICES_ONBOARDMONITORINGSERVICE_HPP
+#define ECSS_SERVICES_ONBOARDMONITORINGSERVICE_HPP
+#include <cstdint>
+#include "Message.hpp"
+#include "etl/array.h"
+#include "Service.hpp"
+#include "Helpers/Parameter.hpp"
+#include "etl/map.h"
+#include "ECSS_Definitions.hpp"
+#include "etl/list.h"
+#include "Helpers/PMONBase.hpp"
+
+/**
+ * Implementation of the ST[12] parameter statistics reporting service, as defined in ECSS-E-ST-70-41C.
+ * @ingroup Services
+ * @author Konstantinos Michopoulos <konstantinos.michopoulos@gmail.com>
+ */
+class OnBoardMonitoringService : public Service {
+private:
+	/**
+	 * Map storing the parameter monitoring definitions.
+	 */
+	etl::map<uint16_t, std::reference_wrapper<PMONBase>, ECSSMaxMonitoringDefinitions> parameterMonitoringList;
+
+public:
+	inline static const uint8_t ServiceType = 12;
+	enum MessageType : uint8_t {
+		EnableParameterMonitoringDefinitions = 1,
+		DisableParameterMonitoringDefinitions = 2,
+		ChangeMaximumTransitionReportingDelay = 3,
+		DeleteAllParameterMonitoringDefinitions = 4,
+		AddParameterMonitoringDefinitions = 5,
+		DeleteParameterMonitoringDefinitions = 6,
+		ModifyParameterMonitoringDefinitions = 7,
+		ReportParameterMonitoringDefinitions = 8,
+		ParameterMonitoringDefinitionReport = 9,
+		ReportOutOfLimits = 10,
+		OutOfLimitsReport = 11,
+		CheckTransitionReport = 12,
+		ReportStatusOfParameterMonitoringDefinition = 13,
+		ParameterMonitoringDefinitionStatusReport = 14
+	};
+	/**
+	 * The maximum time between two transition reports.
+	 * Measured in "on-board parameter minimum sampling interval" units (see 5.4.3.2c in ECSS-E-ST-70-41C).
+	 */
+	uint16_t maximumTransitionReportingDelay = 0;
+	/**
+	 * If true, parameter monitoring is enabled
+	 */
+	bool parameterMonitoringFunctionStatus = false;
+	/*
+	 * Adds a new Parameter Monitoring definition to the parameter monitoring list.
+	 */
+	void addPMONDefinition(uint16_t PMONId, std::reference_wrapper<PMONBase> PMONDefinition) {
+		parameterMonitoringList.insert({PMONId, PMONDefinition});
+	}
+	/**
+	 * @param PMONId
+	 * @return Parameter Monitoring definition
+	 */
+	std::reference_wrapper<PMONBase> getPMONDefinition(uint16_t PMONId) {
+		return parameterMonitoringList.at(PMONId);
+	}
+	/**
+	 * @return true if PMONList is empty.
+	 */
+	bool isPMONListEmpty() {
+		return parameterMonitoringList.empty();
+	}
+	/**
+	 * Enables the PMON definitions which correspond to the ids in TC[12,1].
+	 */
+	void enableParameterMonitoringDefinitions(Message& message);
+
+	/**
+	 * Disables the PMON definitions which correspond to the ids in TC[12,2].
+	 */
+	void disableParameterMonitoringDefinitions(Message& message);
+
+	/**
+	 * TC[12,3]
+	 * Changes the maximum time between two transition reports.
+	 */
+	void changeMaximumTransitionReportingDelay(Message& message);
+
+	/**
+	 * TC[12,4]
+	 * Deletes all the PMON definitions in the PMON list.
+	 */
+	void deleteAllParameterMonitoringDefinitions(Message& message);
+
+	void execute(Message& message);
+};
+
+#endif // ECSS_SERVICES_ONBOARDMONITORINGSERVICE_HPP
diff --git a/src/Helpers/PMONBase.cpp b/src/Helpers/PMONBase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..85f163fd24029d46f6dc3300b57a4dc79049d6e6
--- /dev/null
+++ b/src/Helpers/PMONBase.cpp
@@ -0,0 +1,9 @@
+#include "Helpers/PMONBase.hpp"
+#include "ServicePool.hpp"
+
+
+PMONBase::PMONBase(uint16_t monitoredParameterId, uint16_t repetitionNumber)
+    : monitoredParameter(monitoredParameter), monitoredParameterId(monitoredParameterId),
+      repetitionNumber(repetitionNumber) {
+	monitoredParameter = Services.parameterManagement.getParameter(monitoredParameterId)->get();
+}
\ No newline at end of file
diff --git a/src/MessageParser.cpp b/src/MessageParser.cpp
index c35c525bb5d3f1fb8b5010d1104a9c845da387af..b34fc13d3c874609fa593718f9285c2c0e010a0f 100644
--- a/src/MessageParser.cpp
+++ b/src/MessageParser.cpp
@@ -7,6 +7,7 @@
 
 void MessageParser::execute(Message& message) {
 	switch (message.serviceType) {
+
 #ifdef SERVICE_HOUSEKEEPING
 		case HousekeepingService::ServiceType:
 			Services.housekeeping.execute(message);
@@ -43,6 +44,12 @@ void MessageParser::execute(Message& message) {
 			break;
 #endif
 
+#ifdef SERVICE_ONBOARDMONITORING
+		case OnBoardMonitoringService::ServiceType:
+			Services.onBoardMonitoringService.execute(message);
+			break;
+#endif
+
 #ifdef SERVICE_TEST
 		case TestService::ServiceType:
 			Services.testService.execute(message);
diff --git a/src/Services/OnBoardMonitoringService.cpp b/src/Services/OnBoardMonitoringService.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f644546db72bc8f8bfc59ec14352064893258cb1
--- /dev/null
+++ b/src/Services/OnBoardMonitoringService.cpp
@@ -0,0 +1,75 @@
+#include "ECSS_Configuration.hpp"
+#ifdef SERVICE_ONBOARDMONITORING
+#include "Message.hpp"
+#include "Services/OnBoardMonitoringService.hpp"
+#include "etl/map.h"
+
+void OnBoardMonitoringService::enableParameterMonitoringDefinitions(Message& message) {
+	message.assertTC(ServiceType, EnableParameterMonitoringDefinitions);
+
+	uint16_t numberOfPMONDefinitions = message.readUint16();
+	for (uint16_t i = 0; i < numberOfPMONDefinitions; i++) {
+		uint16_t currentId = message.readEnum16();
+		auto definition = parameterMonitoringList.find(currentId);
+		if (definition == parameterMonitoringList.end()) {
+			ErrorHandler::reportError(
+			    message, ErrorHandler::ExecutionStartErrorType::GetNonExistingParameterMonitoringDefinition);
+			continue;
+		}
+		definition->second.get().repetitionNumber = 0;
+		definition->second.get().monitoringEnabled = true;
+	}
+}
+
+void OnBoardMonitoringService::disableParameterMonitoringDefinitions(Message& message) {
+	message.assertTC(ServiceType, DisableParameterMonitoringDefinitions);
+
+	uint16_t numberOfPMONDefinitions = message.readUint16();
+	for (uint16_t i = 0; i < numberOfPMONDefinitions; i++) {
+		uint16_t currentId = message.readEnum16();
+		auto definition = parameterMonitoringList.find(currentId);
+		if (definition == parameterMonitoringList.end()) {
+			ErrorHandler::reportError(
+			    message, ErrorHandler::ExecutionStartErrorType::GetNonExistingParameterMonitoringDefinition);
+			continue;
+		}
+		definition->second.get().monitoringEnabled = false;
+		definition->second.get().checkingStatus = PMONBase::Unchecked;
+	}
+}
+
+void OnBoardMonitoringService::changeMaximumTransitionReportingDelay(Message& message) {
+	message.assertTC(ServiceType, ChangeMaximumTransitionReportingDelay);
+	maximumTransitionReportingDelay = message.readUint16();
+}
+
+void OnBoardMonitoringService::deleteAllParameterMonitoringDefinitions(Message& message) {
+	message.assertTC(ServiceType, DeleteAllParameterMonitoringDefinitions);
+	if (parameterMonitoringFunctionStatus) {
+		ErrorHandler::reportError(
+		    message, ErrorHandler::ExecutionStartErrorType::InvalidRequestToDeleteAllParameterMonitoringDefinitions);
+		return;
+	}
+	parameterMonitoringList.clear();
+}
+
+void OnBoardMonitoringService::execute(Message& message) {
+	switch (message.messageType) {
+		case EnableParameterMonitoringDefinitions:
+			enableParameterMonitoringDefinitions(message);
+			break;
+		case DisableParameterMonitoringDefinitions:
+			disableParameterMonitoringDefinitions(message);
+			break;
+		case ChangeMaximumTransitionReportingDelay:
+			changeMaximumTransitionReportingDelay(message);
+			break;
+		case DeleteAllParameterMonitoringDefinitions:
+			deleteAllParameterMonitoringDefinitions(message);
+			break;
+		default:
+			ErrorHandler::reportInternalError(ErrorHandler::OtherMessageType);
+	}
+}
+
+#endif
\ No newline at end of file
diff --git a/test/Services/OnBoardMonitoringService.cpp b/test/Services/OnBoardMonitoringService.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..548cf83969d2fe97e21987e877dc6b147e7b3147
--- /dev/null
+++ b/test/Services/OnBoardMonitoringService.cpp
@@ -0,0 +1,193 @@
+#include <catch2/catch.hpp>
+#include <Services/OnBoardMonitoringService.hpp>
+#include <Message.hpp>
+#include "ServiceTests.hpp"
+#include <etl/array.h>
+#include <etl/String.hpp>
+#include <ServicePool.hpp>
+
+OnBoardMonitoringService& onBoardMonitoringService = Services.onBoardMonitoringService;
+
+struct Fixtures {
+	PMONExpectedValueCheck monitoringDefinition1 = PMONExpectedValueCheck(7, 5, 10, 8, 0);
+	PMONLimitCheck monitoringDefinition2 = PMONLimitCheck(7, 5, 2, 1, 9, 2);
+	PMONDeltaCheck monitoringDefinition3 = PMONDeltaCheck(7, 5, 5, 3, 3, 11, 4);
+	PMONDeltaCheck monitoringDefinition4 = PMONDeltaCheck(7, 5, 5, 3, 3, 11, 4);
+
+	/*
+	 * Constructor to modify monitoring definitions if needed
+	 */
+	Fixtures() {
+		monitoringDefinition1.monitoringEnabled = true;
+	}
+};
+
+Fixtures fixtures;
+
+void initialiseParameterMonitoringDefinitions() {
+	// Reset fixtures to the defaults set up by the constructor
+	new (&fixtures) Fixtures();
+
+	onBoardMonitoringService.addPMONDefinition(0, fixtures.monitoringDefinition1);
+	onBoardMonitoringService.addPMONDefinition(1, fixtures.monitoringDefinition2);
+	onBoardMonitoringService.addPMONDefinition(2, fixtures.monitoringDefinition3);
+	onBoardMonitoringService.addPMONDefinition(3, fixtures.monitoringDefinition4);
+}
+
+TEST_CASE("Enable Parameter Monitoring Definitions") {
+	SECTION("3 valid requests to enable Parameter Monitoring Definitions") {
+		initialiseParameterMonitoringDefinitions();
+
+		Message request =
+		    Message(OnBoardMonitoringService::ServiceType,
+		            OnBoardMonitoringService::MessageType::EnableParameterMonitoringDefinitions, Message::TC, 0);
+		uint16_t numberOfIds = 3;
+		request.appendUint16(numberOfIds);
+		etl::array<uint16_t, 3> PMONIds = {0, 1, 2};
+		request.appendEnum16(PMONIds[0]);
+		request.appendEnum16(PMONIds[1]);
+		request.appendEnum16(PMONIds[2]);
+
+		MessageParser::execute(request);
+		CHECK(ServiceTests::count() == 0);
+
+		CHECK((onBoardMonitoringService.getPMONDefinition(PMONIds[0]).get().monitoringEnabled == true));
+		CHECK((onBoardMonitoringService.getPMONDefinition(PMONIds[1]).get().monitoringEnabled == true));
+		CHECK((onBoardMonitoringService.getPMONDefinition(PMONIds[2]).get().monitoringEnabled == true));
+		CHECK(onBoardMonitoringService.getPMONDefinition(PMONIds[0]).get().repetitionCounter == 0);
+		CHECK(onBoardMonitoringService.getPMONDefinition(PMONIds[1]).get().repetitionCounter == 0);
+		CHECK(onBoardMonitoringService.getPMONDefinition(PMONIds[2]).get().repetitionCounter == 0);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+	SECTION("2 valid requests to enable Parameter Monitoring Definitions and 1 invalid") {
+		initialiseParameterMonitoringDefinitions();
+
+		Message request =
+		    Message(OnBoardMonitoringService::ServiceType,
+		            OnBoardMonitoringService::MessageType::EnableParameterMonitoringDefinitions, Message::TC, 0);
+		uint16_t numberOfIds = 4;
+		request.appendUint16(numberOfIds);
+		etl::array<uint16_t, 4> PMONIds = {0, 10, 1};
+		request.appendEnum16(PMONIds[0]);
+		request.appendEnum16(PMONIds[1]);
+		request.appendEnum16(PMONIds[2]);
+
+		MessageParser::execute(request);
+		CHECK(ServiceTests::count() == 1);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::GetNonExistingParameterMonitoringDefinition) == 1);
+		CHECK((onBoardMonitoringService.getPMONDefinition(PMONIds[0]).get().monitoringEnabled == true));
+		CHECK((onBoardMonitoringService.getPMONDefinition(PMONIds[2]).get().monitoringEnabled == true));
+		CHECK(onBoardMonitoringService.getPMONDefinition(PMONIds[0]).get().repetitionCounter == 0);
+		CHECK(onBoardMonitoringService.getPMONDefinition(PMONIds[2]).get().repetitionCounter == 0);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Disable Parameter Monitoring Definitions") {
+	SECTION("3 valid requests to disable Parameter Monitoring Definitions") {
+		initialiseParameterMonitoringDefinitions();
+		Message request =
+		    Message(OnBoardMonitoringService::ServiceType,
+		            OnBoardMonitoringService::MessageType::DisableParameterMonitoringDefinitions, Message::TC, 0);
+		uint16_t numberOfIds = 3;
+		request.appendUint16(numberOfIds);
+		etl::array<uint16_t, 3> PMONIds = {0, 1, 2};
+		request.appendEnum16(PMONIds[0]);
+		request.appendEnum16(PMONIds[1]);
+		request.appendEnum16(PMONIds[2]);
+		onBoardMonitoringService.getPMONDefinition(PMONIds[0]).get().monitoringEnabled = true;
+		onBoardMonitoringService.getPMONDefinition(PMONIds[1]).get().monitoringEnabled = true;
+		onBoardMonitoringService.getPMONDefinition(PMONIds[2]).get().monitoringEnabled = true;
+
+		MessageParser::execute(request);
+		CHECK(ServiceTests::count() == 0);
+		CHECK(onBoardMonitoringService.getPMONDefinition(PMONIds[0]).get().monitoringEnabled == false);
+		CHECK(onBoardMonitoringService.getPMONDefinition(PMONIds[1]).get().monitoringEnabled == false);
+		CHECK(onBoardMonitoringService.getPMONDefinition(PMONIds[2]).get().monitoringEnabled == false);
+		CHECK(onBoardMonitoringService.getPMONDefinition(PMONIds[0]).get().checkingStatus == PMONBase::Unchecked);
+		CHECK(onBoardMonitoringService.getPMONDefinition(PMONIds[1]).get().checkingStatus == PMONBase::Unchecked);
+		CHECK(onBoardMonitoringService.getPMONDefinition(PMONIds[2]).get().checkingStatus == PMONBase::Unchecked);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+	SECTION("3 valid requests to disable Parameter Monitoring Definitions and 1 invalid") {
+		initialiseParameterMonitoringDefinitions();
+		Message request =
+		    Message(OnBoardMonitoringService::ServiceType,
+		            OnBoardMonitoringService::MessageType::DisableParameterMonitoringDefinitions, Message::TC, 0);
+		uint16_t numberOfIds = 4;
+		request.appendUint16(numberOfIds);
+		etl::array<uint16_t, 4> PMONIds = {0, 10, 1, 2};
+		request.appendEnum16(PMONIds[0]);
+		request.appendEnum16(PMONIds[1]);
+		request.appendEnum16(PMONIds[2]);
+		request.appendEnum16(PMONIds[3]);
+		onBoardMonitoringService.getPMONDefinition(PMONIds[0]).get().monitoringEnabled = true;
+		onBoardMonitoringService.getPMONDefinition(PMONIds[2]).get().monitoringEnabled = true;
+		onBoardMonitoringService.getPMONDefinition(PMONIds[3]).get().monitoringEnabled = true;
+		MessageParser::execute(request);
+		CHECK(ServiceTests::count() == 1);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::GetNonExistingParameterMonitoringDefinition) == 1);
+		CHECK(onBoardMonitoringService.getPMONDefinition(PMONIds[0]).get().monitoringEnabled == false);
+		CHECK(onBoardMonitoringService.getPMONDefinition(PMONIds[2]).get().monitoringEnabled == false);
+		CHECK(onBoardMonitoringService.getPMONDefinition(PMONIds[3]).get().monitoringEnabled == false);
+		CHECK(onBoardMonitoringService.getPMONDefinition(PMONIds[0]).get().checkingStatus == PMONBase::Unchecked);
+		CHECK(onBoardMonitoringService.getPMONDefinition(PMONIds[2]).get().checkingStatus == PMONBase::Unchecked);
+		CHECK(onBoardMonitoringService.getPMONDefinition(PMONIds[3]).get().checkingStatus == PMONBase::Unchecked);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Change Maximum Transition Reporting Delay") {
+	initialiseParameterMonitoringDefinitions();
+	Message request =
+	    Message(OnBoardMonitoringService::ServiceType,
+	            OnBoardMonitoringService::MessageType::ChangeMaximumTransitionReportingDelay, Message::TC, 0);
+	uint16_t newMaximumTransitionReportingDelay = 10;
+	request.appendUint16(newMaximumTransitionReportingDelay);
+	MessageParser::execute(request);
+	CHECK(ServiceTests::count() == 0);
+	CHECK(onBoardMonitoringService.maximumTransitionReportingDelay == newMaximumTransitionReportingDelay);
+
+	ServiceTests::reset();
+	Services.reset();
+}
+
+TEST_CASE("Delete all Parameter Monitoring Definitions") {
+	SECTION("Valid request to delete all Parameter Monitoring Definitions") {
+		initialiseParameterMonitoringDefinitions();
+		onBoardMonitoringService.parameterMonitoringFunctionStatus = false;
+		Message request =
+		    Message(OnBoardMonitoringService::ServiceType,
+		            OnBoardMonitoringService::MessageType::DeleteAllParameterMonitoringDefinitions, Message::TC, 0);
+		MessageParser::execute(request);
+		CHECK(ServiceTests::count() == 0);
+		CHECK(onBoardMonitoringService.isPMONListEmpty());
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+	SECTION("Invalid request to delete all Parameter Monitoring Definitions") {
+		initialiseParameterMonitoringDefinitions();
+		onBoardMonitoringService.parameterMonitoringFunctionStatus = true;
+		Message request =
+		    Message(OnBoardMonitoringService::ServiceType,
+		            OnBoardMonitoringService::MessageType::DeleteAllParameterMonitoringDefinitions, Message::TC, 0);
+		MessageParser::execute(request);
+		CHECK(ServiceTests::count() == 1);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::InvalidRequestToDeleteAllParameterMonitoringDefinitions) ==
+		      1);
+
+		CHECK(!onBoardMonitoringService.isPMONListEmpty());
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}