diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000000000000000000000000000000000000..99bf475e5cfd40d9a84d7e21d28b1f0380870114
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,116 @@
+---
+Language:        Cpp
+# BasedOnStyle:  LLVM
+AccessModifierOffset: -4
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlines: Right
+AlignOperands:   true
+AlignTrailingComments: false
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: Empty
+AllowShortIfStatementsOnASingleLine: true
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: Yes
+BinPackArguments: true
+BinPackParameters: true
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Custom
+BraceWrapping:
+  AfterClass: false
+  AfterControlStatement: false
+  AfterEnum: false
+  AfterFunction: false
+  AfterNamespace: true
+  AfterStruct: false
+  AfterUnion: false
+  AfterExternBlock: false
+  BeforeCatch: false
+  BeforeElse: false
+  SplitEmptyFunction: false
+  SplitEmptyRecord: false
+  SplitEmptyNamespace: false
+BreakBeforeInheritanceComma: false
+BreakInheritanceList: BeforeColon
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+BreakConstructorInitializers: BeforeColon
+BreakAfterJavaFieldAnnotations: false
+BreakStringLiterals: true
+ColumnLimit:     120
+CommentPragmas:  '^ IWYU pragma:'
+CompactNamespaces: false
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+DisableFormat:   false
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
+ForEachMacros:
+  - foreach
+  - Q_FOREACH
+  - BOOST_FOREACH
+IncludeBlocks:   Merge
+IncludeCategories:
+  - Regex:           '^"'
+    Priority:        2
+  - Regex:           '^<'
+    Priority:        3
+  - Regex:           '.*'
+    Priority:        1
+IncludeIsMainRegex: '(Test)?$'
+IndentCaseLabels: true
+IndentPPDirectives: None
+IndentWidth:     4
+IndentWrappedFunctionNames: false
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: false
+MacroBlockBegin: ''
+MacroBlockEnd:   ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBinPackProtocolList: Auto
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakAssignment: 2
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyBreakTemplateDeclaration: 10
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Left
+ReflowComments:  true
+SortIncludes:    false
+SortUsingDeclarations: true
+SpaceAfterCStyleCast: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeParens: ControlStatements
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles:  false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard:        Cpp11
+TabWidth:        4
+UseTab:          ForIndentation
+...
+
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index f25060c0a0ccdd77d361f71cffaeeb85e993991b..684c966e49b30670fa8b7e5fc58997469b6e3ecc 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -1,7 +1,16 @@
 <component name="ProjectCodeStyleConfiguration">
   <code_scheme name="Project" version="173">
-    <option name="RIGHT_MARGIN" value="100" />
     <option name="WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN" value="true" />
+    <Objective-C>
+      <option name="KEEP_CASE_EXPRESSIONS_IN_ONE_LINE" value="true" />
+      <option name="FUNCTION_PARAMETERS_ALIGN_MULTILINE" value="false" />
+      <option name="FUNCTION_CALL_ARGUMENTS_ALIGN_MULTILINE" value="false" />
+      <option name="SPACE_BEFORE_TEMPLATE_DECLARATION_LT" value="true" />
+      <option name="SPACE_BEFORE_POINTER_IN_DECLARATION" value="false" />
+      <option name="SPACE_AFTER_POINTER_IN_DECLARATION" value="true" />
+      <option name="SPACE_BEFORE_REFERENCE_IN_DECLARATION" value="false" />
+      <option name="SPACE_AFTER_REFERENCE_IN_DECLARATION" value="true" />
+    </Objective-C>
     <Objective-C-extensions>
       <extensions>
         <pair source="cpp" header="hpp" fileNamingConvention="PASCAL_CASE" />
@@ -9,6 +18,12 @@
       </extensions>
     </Objective-C-extensions>
     <codeStyleSettings language="ObjectiveC">
+      <option name="ALIGN_MULTILINE_CHAINED_METHODS" value="true" />
+      <option name="ALIGN_MULTILINE_FOR" value="false" />
+      <option name="ALIGN_MULTILINE_ASSIGNMENT" value="false" />
+      <option name="ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION" value="false" />
+      <option name="METHOD_CALL_CHAIN_WRAP" value="1" />
+      <option name="ENUM_CONSTANTS_WRAP" value="2" />
       <indentOptions>
         <option name="CONTINUATION_INDENT_SIZE" value="4" />
         <option name="USE_TAB_CHARACTER" value="true" />
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 26659a90aa7cb5a617f8a27eafd2b1e6d9c85195..37b151c03e16be403d2d367a27ca5daffbd2b092 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -28,7 +28,10 @@ add_library(common OBJECT
         src/Services/RequestVerificationService.cpp
         src/Services/TestService.cpp
         src/Services/TimeManagementService.cpp
-        src/Services/EventActionService.cpp
+        src/Services/LargePacketTransferService.cpp
+    	src/Services/EventActionService.cpp
+        src/Services/TimeBasedSchedulingService.cpp
+        src/Services/FunctionManagementService.cpp
         )
 
 # Specify the .cpp files for the executables
diff --git a/ci/clang-format.sh b/ci/clang-format.sh
new file mode 100755
index 0000000000000000000000000000000000000000..d8718f524a3230ced99febabba5cdd08b1e72bf0
--- /dev/null
+++ b/ci/clang-format.sh
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+
+#
+# Edit files, performing code style corrections using clang-format
+#
+# Usage:
+# $ ci/clang-format.sh
+#
+
+echo -e "\033[0;34mRunning clang-format...\033[0m"
+
+cd "$(dirname "$0")"
+clang-format-7 -i `find ../src/ ../inc/ ../test/ -type f -regextype posix-egrep -regex '.*\.(cpp|hpp|c|h)'` \
+    -verbose $@
diff --git a/ci/vera.sh b/ci/vera.sh
index 470c348bf7e4d999de64b3e58df311a444c87bcc..4481cfb2b2b49d904725a211d4c58b51fe4c4048 100755
--- a/ci/vera.sh
+++ b/ci/vera.sh
@@ -10,4 +10,4 @@
 echo -e "\033[0;34mRunning vera++...\033[0m"
 
 cd "$(dirname "$0")/.."
-vera++ --error --profile custom `find src inc test -type f -regextype posix-egrep -regex '.*\.(cpp|hpp|c|h)'`
+vera++ --error --parameter max-line-length=120 --profile custom `find src inc test -type f -regextype posix-egrep -regex '.*\.(cpp|hpp|c|h)'`
diff --git a/inc/ECSS_Definitions.hpp b/inc/ECSS_Definitions.hpp
index 1f000979a32969565a7cdee0d7e91f63779da207..047db0f70cda0a66d4069ffb7aacd3c780e45baf 100644
--- a/inc/ECSS_Definitions.hpp
+++ b/inc/ECSS_Definitions.hpp
@@ -5,13 +5,47 @@
 
 #define ECSS_MAX_STRING_SIZE 256
 
+#define ECSS_MAX_FIXED_OCTET_STRING_SIZE 256 // For the ST13 large packet transfer service
+
 // 7.4.1
 #define CCSDS_PACKET_VERSION 0
 
 // 7.4.4.1c
-#define ECSS_PUS_VERSION 2
+#define ECSS_PUS_VERSION 2U
 
 // 9.3.1a.1.e
 #define ECSS_SEQUENCE_FLAGS 0x3
 
+/**
+ * @brief Maximum number of TC requests that can be contained in a single message request
+ * @details This definition accounts for the maximum number of TC packet requests that can be
+ * contained in the message of a request. This was defined for the time based command scheduling
+ * service and specifically to address the needs of the sub-services containing a TC packet in
+ * their message request.
+ * @attention This definition is probably dependent on the ECSS_TC_REQUEST_STRING_SIZE
+ */
+#define ECSS_MAX_REQUEST_COUNT 20 // todo: Needs to be defined
+
+/**
+ * @brief Maximum length of a String converted TC packet message
+ * @details This definition refers to the maximum length that an embedded TC packet, meaning a TC
+ * packet contained in a message request as a part of the request.
+ */
+#define ECSS_TC_REQUEST_STRING_SIZE 64
+
+// todo: Define the maximum number of activities
+#define ECSS_MAX_NUMBER_OF_TIME_SCHED_ACTIVITIES    10
+
+/**
+ * @brief Time margin used in the time based command scheduling service ST[11]
+ * @details This defines the time margin in seconds, from the current rime, that an activity must
+ * have in order
+ * @todo Define the time margin for the command activation
+ */
+#define ECSS_TIME_MARGIN_FOR_ACTIVATION  60
+
+// todo: Define the maximum delta between the specified
+#define ECSS_MAX_DELTA_OF_RELEASE_TIME   60
+// release time and the actual release time
+
 #endif //ECSS_SERVICES_ECSS_DEFINITIONS_H
diff --git a/inc/ErrorHandler.hpp b/inc/ErrorHandler.hpp
index 9864f708b31bc297459627581f2542bb4352fb4e..4f50837588ce77417bc2818c2093b675a9bfd267 100644
--- a/inc/ErrorHandler.hpp
+++ b/inc/ErrorHandler.hpp
@@ -69,7 +69,11 @@ public:
 		/**
 		 * A function received a Message that was not of the correct type
 		 */
-		    OtherMessageType = 9,
+			OtherMessageType = 9,
+		/**
+		 * Attempt to insert new function in a full function map (ST[08])
+		 */
+			FunctionMapFull = 10,
 	};
 
 	/**
@@ -106,6 +110,8 @@ public:
 	 */
 	enum ExecutionStartErrorType {
 		UnknownExecutionStartError = 0,
+		SubServiceExecutionStartError = 1,
+		InstructionExecutionStartError = 2,
 	};
 
 	/**
diff --git a/inc/Helpers/CRCHelper.hpp b/inc/Helpers/CRCHelper.hpp
index 12da516b2d6718d6743b17779c2fcf01dec178cd..aa7149846b762498ac4e13979afbbe215119b3bd 100644
--- a/inc/Helpers/CRCHelper.hpp
+++ b/inc/Helpers/CRCHelper.hpp
@@ -6,7 +6,7 @@
 class CRCHelper {
 
 	/**
-	 * CRC32 calculation helper class
+	 * CRC16 calculation helper class
 	 * This class declares a function which calculates the CRC16 checksum of the given data.
 	 *
 	 * For now the actual implementation is the CRC16/CCITT variant (ECSS-E-ST-70-41C, pg.615)
@@ -25,7 +25,7 @@ public:
 	 * Actual CRC calculation function.
 	 * @param  message (pointer to the data to be checksummed)
 	 * @param  length (size in bytes)
-	 * @return the CRC32 checksum of the input data
+	 * @return the CRC16 checksum of the input data
 	 */
 	static uint16_t calculateCRC(const uint8_t* message, uint32_t length);
 
diff --git a/inc/Message.hpp b/inc/Message.hpp
index 3240626189f8848a4147f9e97e9d46399dfaa5fe..ac1509f9ea39dc2c8d330e0ebd4bcc34978c382a 100644
--- a/inc/Message.hpp
+++ b/inc/Message.hpp
@@ -22,6 +22,41 @@ class Message {
 public:
 	Message() = default;
 
+	/**
+	 * @brief Compare two messages
+	 * @details Check whether two Message objects are of the same type
+	 * @param msg1 First message for comparison
+	 * @param msg2 Second message for comparison
+	 * @return A boolean value indicating whether the messages are of the same type
+	 */
+	static bool isSameType(const Message &msg1, const Message &msg2) {
+		return (msg1.packetType == msg2.packetType) &&
+		       (msg1.messageType == msg2.messageType) && (msg1.serviceType == msg2.serviceType);
+	}
+
+	/**
+	 * @brief Overload the equality operator to compare messages
+	 * @details Compare two @ref ::Message objects, based on their contents and type
+	 * @param The message content to compare against
+	 * @todo Activate the dataSize check when the Message object data field is defined with a
+	 * fixed size
+	 * @return The result of comparison
+	 */
+	bool operator==(const Message &msg) const {
+		// todo: Enable the following check when the message data field has a fixed size padded
+		//  with zeros. At the moment the data array is not padded with zeros to fulfil the
+		//  maximum set number of a TC request message.
+		//if (this->dataSize != msg.dataSize) return false;
+
+		for (uint16_t i = 0; i < ECSS_MAX_MESSAGE_SIZE; i++) {
+			if (this->data[i] != msg.data[i]) {
+				return false;
+			}
+		}
+		return (this->packetType == msg.packetType) &&
+		       (this->messageType == msg.messageType) && (this->serviceType == msg.serviceType);
+	}
+
 	enum PacketType {
 		TM = 0, // Telemetry
 		TC = 1 // Telecommand
@@ -438,6 +473,16 @@ public:
 		return size; // Return the string size
 	}
 
+	/**
+	 * @brief Skip read bytes in the read string
+	 * @details Skips the provided number of bytes, by incrementing the readPosition and this is
+	 * done to avoid accessing the `readPosition` variable directly
+	 * @param numberOfBytes The number of bytes to be skipped
+	 */
+	void skipBytes(uint16_t numberOfBytes) {
+		readPosition += numberOfBytes;
+	}
+
 	/**
 	 * Reset the message reading status, and start reading data from it again
 	 */
diff --git a/inc/MessageParser.hpp b/inc/MessageParser.hpp
index 4d1985b274f049dd325287de6e623b9a85b0ea4b..4b848bc75c08f443d8a1302d4c683baf2b4abc01 100644
--- a/inc/MessageParser.hpp
+++ b/inc/MessageParser.hpp
@@ -37,7 +37,24 @@ public:
 	 * this great analysis:
 	 * stackoverflow.com/questions/15078638/can-i-turn-unsigned-char-into-char-and-vice-versa
 	 */
-	Message parseRequestTC(String<ECSS_EVENT_SERVICE_STRING_SIZE> data);
+	Message parseRequestTC(String<ECSS_TC_REQUEST_STRING_SIZE> data);
+
+	/**
+	 * @brief Overloaded version
+	 * @param data A uint8_t array of the TC packet data
+	 * @return Parsed message
+	 */
+	Message parseRequestTC(uint8_t* data);
+
+	/**
+	 * @brief Converts a TC packet of type Message to a String
+	 * @details Convert a parsed TC message to a string in order to be used by the services
+	 * @param message The Message object to be parsed to a String
+	 * @return A String class containing the parsed TC request
+	 * @attention The returned String has a fixed size, therefore the message size is considered
+	 * fixed and equal to the ECSS_TC_REQUEST_STRING_SIZE definition.
+	 */
+	String<ECSS_TC_REQUEST_STRING_SIZE> convertTCToStr(Message& message);
 
 private:
 	/**
@@ -49,7 +66,7 @@ private:
 	 * @param length The size of the header
 	 * @param message The Message to modify based on the header
 	 */
-	void parseTC(uint8_t *data, uint16_t length, Message &message);
+	void parseTC(const uint8_t *data, uint16_t length, Message &message);
 
 	/**
 	 * Parse the ECSS Telemetry packet secondary header
@@ -60,7 +77,7 @@ private:
 	 * @param length The size of the header
 	 * @param message The Message to modify based on the header
 	 */
-	void parseTM(uint8_t *data, uint16_t length, Message &message);
+	void parseTM(const uint8_t *data, uint16_t length, Message &message);
 };
 
 
diff --git a/inc/Platform/x86/TimeGetter.hpp b/inc/Platform/x86/TimeGetter.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..7dcf22ed020dd6163ef5c1adede6e1f3dbf26d22
--- /dev/null
+++ b/inc/Platform/x86/TimeGetter.hpp
@@ -0,0 +1,24 @@
+#ifndef ECSS_SERVICES_TIMEGETTER_HPP
+#define ECSS_SERVICES_TIMEGETTER_HPP
+
+#include <iostream>
+#include <cstdint>
+#include <ctime>
+
+
+/**
+ * @brief Get the current time
+ */
+class TimeGetter {
+public:
+
+	/**
+	 * @brief Gets the current time in UNIX epoch
+	 * @return Current UNIX epoch time, in elapsed seconds
+	 */
+	static inline uint32_t getSeconds() {
+		return static_cast<uint32_t >(time(nullptr));
+	}
+};
+
+#endif //ECSS_SERVICES_TIMEGETTER_HPP
diff --git a/inc/ServicePool.hpp b/inc/ServicePool.hpp
index 8a1e6035855eea8b35003ff37047ac4bb1b01f06..d8ec83c84eef6be474397028868a89eef78f9d60 100644
--- a/inc/ServicePool.hpp
+++ b/inc/ServicePool.hpp
@@ -1,6 +1,7 @@
 #ifndef ECSS_SERVICES_SERVICEPOOL_HPP
 #define ECSS_SERVICES_SERVICEPOOL_HPP
 
+#include "Services/LargePacketTransferService.hpp"
 #include "Services/RequestVerificationService.hpp"
 #include "Services/TimeManagementService.hpp"
 #include "Services/EventReportService.hpp"
@@ -8,6 +9,7 @@
 #include "Services/ParameterService.hpp"
 #include "Services/TestService.hpp"
 #include "Services/MemoryManagementService.hpp"
+#include "Services/FunctionManagementService.hpp"
 
 /**
  * Defines a class that contains instances of all Services.
@@ -25,6 +27,8 @@ public:
 	EventActionService eventAction;
 	TestService testService;
 	ParameterService parameterManagement;
+	LargePacketTransferService largePacketTransferService;
+	FunctionManagementService functionManagement;
 
 	/**
 	 * The default ServicePool constructor
diff --git a/inc/Services/EventActionService.hpp b/inc/Services/EventActionService.hpp
index 338a67345c0163bb8df8708f784c0b7aae868edc..3b561617d2cbe76b4423b6bcc83035c3fc5af79e 100644
--- a/inc/Services/EventActionService.hpp
+++ b/inc/Services/EventActionService.hpp
@@ -1,7 +1,6 @@
 #ifndef ECSS_SERVICES_EVENTACTIONSERVICE_HPP
 #define ECSS_SERVICES_EVENTACTIONSERVICE_HPP
 
-#define ECSS_EVENT_SERVICE_STRING_SIZE 64
 
 #define ECSS_EVENT_ACTION_STRUCT_ARRAY_SIZE 256
 
diff --git a/inc/Services/EventReportService.hpp b/inc/Services/EventReportService.hpp
index 0ecaf179e3468712fe49984cc3287fc643e32ee9..fdb32c0c5b9ea143c031d1efeaad730f5cd8e822 100644
--- a/inc/Services/EventReportService.hpp
+++ b/inc/Services/EventReportService.hpp
@@ -2,7 +2,7 @@
 #define ECSS_SERVICES_EVENTREPORTSERVICE_HPP
 
 #include "Service.hpp"
-#include <bitset>
+#include <etl/bitset.h>
 /**
  * Implementation of ST[05] event reporting service
  *
@@ -17,7 +17,7 @@
 class EventReportService : public Service {
 private:
 	static const uint16_t numberOfEvents = 7;
-	std::bitset<numberOfEvents> stateOfEvents;
+	etl::bitset<numberOfEvents> stateOfEvents;
 public:
 	// Variables that count the event reports per severity level
 	uint16_t lowSeverityReportCount;
@@ -170,7 +170,7 @@ public:
 	 * Getter for stateOfEvents bitset
 	 * @return stateOfEvents, just in case the whole bitset is needed
 	 */
-	std::bitset<numberOfEvents> getStateOfEvents() {
+	etl::bitset<numberOfEvents> getStateOfEvents() {
 		return stateOfEvents;
 	}
 };
diff --git a/inc/Services/FunctionManagementService.hpp b/inc/Services/FunctionManagementService.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..2267f7ea112afabefbb97adce73d4844ad40a883
--- /dev/null
+++ b/inc/Services/FunctionManagementService.hpp
@@ -0,0 +1,95 @@
+#ifndef ECSS_SERVICES_FUNCTIONMANAGEMENTSERVICE_HPP
+#define ECSS_SERVICES_FUNCTIONMANAGEMENTSERVICE_HPP
+
+#include "etl/map.h"
+#include "etl/String.hpp"
+#include "Message.hpp"
+#include "Service.hpp"
+#include "ErrorHandler.hpp"
+
+#define FUNC_MAP_SIZE     5     // size of the function map (number of elements)
+#define FUNC_NAME_LENGTH  32      // max length of the function name
+#define MAX_ARG_LENGTH    32      // maximum argument byte string length
+
+/**
+ * Implementation of the ST[08] function management service
+ *
+ * This class implements a skeleton framework for the ST[08] service as described in
+ * ECSS-E-ST-70-41C, pages 157-159. Final implementation is dependent on subsystem requirements
+ * which are, as of this writing, undefined yet.
+ *
+ * Caveats:
+ * 1) Function names shall be exactly MAXFUNCNAMELENGTH-lengthed in order to be properly read
+ * and stored!  (not sure if this is a caveat though, as ECSS-E-ST-70-41C stipulates for ST[08]
+ * that all function names must be fixed-length character strings)
+ *
+ * You have been warned.
+ *
+ * @author Grigoris Pavlakis <grigpavl@ece.auth.gr>
+ */
+
+ /**
+ * Usage of the include() function:
+ *
+ * @code
+ * void foo(String<MAX_ARG_LENGTH> b) {
+ * 		std::cout << "SPAAAACE!" << std::endl;
+ * 	}
+ *
+ * void bar(String<MAX_ARG_LENGTH> b) {
+ * 		std::cout << "I HAZ A CUBESAT THAT SNAPS PIX!" << std::endl;
+ * 	}
+ *
+ * void baz(String<MAX_ARG_LENGTH> b) {
+ * 		std::cout << "QWERTYUIOP" << std::endl;
+ * 	}
+ *
+ * 	FunctionManagementService::FunctionManagementService() {
+ * 		include(String<FUNC_NAME_LENGTH>("foo"), &foo);
+ * 		include(String<FUNC_NAME_LENGTH>("bar"), &bar);
+ * 		include(String<FUNC_NAME_LENGTH>("baz"), &baz);
+ * 	}
+ */
+
+typedef String<FUNC_NAME_LENGTH> functionName;
+typedef etl::map<functionName, void(*)(String<MAX_ARG_LENGTH>), FUNC_MAP_SIZE>
+FunctionMap;
+
+class FunctionManagementService : public Service {
+	/**
+	 * Map of the function names to their respective pointers. Size controlled by FUNC_MAP_SIZE
+	 */
+	FunctionMap funcPtrIndex;
+
+
+public:
+	/**
+	 * Constructs the function pointer index with all the necessary functions at initialization time
+	 * These functions need to be in scope. Un-default when needed.
+	 *
+	 * @param None
+	 */
+	FunctionManagementService() = default;
+
+	/**
+	 * Calls the function described in the TC[8,1] message *msg*, passing the arguments contained
+	 * and, if non-existent, generates a failed start of execution notification. Returns an unneeded
+	 * int, for testing purposes.
+	 * @param msg A TC[8,1] message
+	 */
+	void call(Message& msg);
+
+	/**
+	 * Includes a new function in the pointer map. This enables it to be called by way of a valid
+	 * TC [8,1] message.
+	 *
+	 * @param funcName the function's name. Max. length is FUNC_NAME_LENGTH bytes.
+	 * @param ptr pointer to a function of void return type and a MAX_ARG_LENGTH-lengthed byte
+	 * string as argument (which contains the actual arguments of the function)
+	 */
+	void include(String<FUNC_NAME_LENGTH> funcName, void(*ptr)(String<MAX_ARG_LENGTH>));
+
+	int getMapSize() { return funcPtrIndex.size(); }
+};
+
+#endif //ECSS_SERVICES_FUNCTIONMANAGEMENTSERVICE_HPP
diff --git a/inc/Services/LargePacketTransferService.hpp b/inc/Services/LargePacketTransferService.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..7ed7d997ebcea0009193ebeb52d823001c38cab2
--- /dev/null
+++ b/inc/Services/LargePacketTransferService.hpp
@@ -0,0 +1,82 @@
+#ifndef ECSS_SERVICES_LARGEPACKETTRANSFERSERVICE_HPP
+#define ECSS_SERVICES_LARGEPACKETTRANSFERSERVICE_HPP
+
+#include "Service.hpp"
+#include <etl/String.hpp>
+
+/**
+ * Implementation of the ST[13] large packet transfer service
+ * The goal of this service is to help in splitting data packages that exceed the standard's
+ * maximum data size
+ *
+ * Note: More information can be found in the standards' manual, in p. 526-528 and in p. 229-236
+ */
+
+class LargePacketTransferService : public Service {
+public:
+
+	/**
+	 * Default constructor since only functions will be used.
+	 */
+	LargePacketTransferService() {
+		serviceType = 13;
+	}
+
+	/**
+	 * Function that handles the first part of the download report
+	 * @param largeMessageTransactionIdentifier The identifier of the large packet
+	 * @param partSequenceNumber The identifier of the part of the large packet
+	 * @param string The data contained in this part of the large packet
+	 */
+	void firstDownlinkPartReport(uint16_t
+	                             largeMessageTransactionIdentifier, uint16_t partSequenceNumber,
+	                             const String<ECSS_MAX_FIXED_OCTET_STRING_SIZE> &string);
+
+	/**
+	 * Function that handles the n-2 parts of tbe n-part download report
+	 * @param largeMessageTransactionIdentifier The identifier of the large packet
+	 * @param partSequenceNumber The identifier of the part of the large packet
+	 * @param string The data contained in this part of the large packet
+	 */
+	void intermediateDownlinkPartReport(uint16_t
+	                                    largeMessageTransactionIdentifier,
+	                                    uint16_t partSequenceNumber,
+	                                    const String<ECSS_MAX_FIXED_OCTET_STRING_SIZE> &string);
+
+	/**
+	 * Function that handles the last part of the download report
+	 * @param largeMessageTransactionIdentifier The identifier of the large packet
+	 * @param partSequenceNumber The identifier of the part of the large packet
+	 * @param string The data contained in this part of the large packet
+	 */
+	void lastDownlinkPartReport(uint16_t
+	                            largeMessageTransactionIdentifier, uint16_t partSequenceNumber,
+	                            const String<ECSS_MAX_FIXED_OCTET_STRING_SIZE> &string);
+
+
+	// The three uplink functions should handle a TC request to "upload" data. Since there is not
+	// a createTC function ready, I just return the given string.
+	// @TODO: Modify these functions properly
+	/**
+	 * Function that handles the first part of the uplink request
+	 * @param string This will change when these function will be modified
+	 */
+	String<ECSS_MAX_FIXED_OCTET_STRING_SIZE>
+	firstUplinkPart(const String<ECSS_MAX_FIXED_OCTET_STRING_SIZE> &string);
+
+	/**
+	 * Function that handles the n-2 parts of tbe n-part uplink request
+	 * @param string This will change when these function will be modified
+	 */
+	String<ECSS_MAX_FIXED_OCTET_STRING_SIZE>
+	intermediateUplinkPart(const String<ECSS_MAX_FIXED_OCTET_STRING_SIZE> &string);
+
+	/**
+	 * Function that handles the last part of the uplink request
+	 * @param string This will change when these function will be modified
+	 */
+	String<ECSS_MAX_FIXED_OCTET_STRING_SIZE>
+	lastUplinkPart(const String<ECSS_MAX_FIXED_OCTET_STRING_SIZE> &string);
+};
+
+#endif // ECSS_SERVICES_LARGEPACKETTRANSFERSERVICE_HPP
diff --git a/inc/Services/TimeBasedSchedulingService.hpp b/inc/Services/TimeBasedSchedulingService.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..76343b5d76fa5aac07e9a59f29899ec00769e4bd
--- /dev/null
+++ b/inc/Services/TimeBasedSchedulingService.hpp
@@ -0,0 +1,250 @@
+#ifndef ECSS_SERVICES_TIMEBASEDSCHEDULINGSERVICE_HPP
+#define ECSS_SERVICES_TIMEBASEDSCHEDULINGSERVICE_HPP
+
+#include "etl/list.h"
+#include "Service.hpp"
+#include "ErrorHandler.hpp"
+#include "MessageParser.hpp"
+#include "Helpers/CRCHelper.hpp"
+#include "Helpers/TimeHelper.hpp"
+
+// Include platform specific files
+#include "Platform/x86/TimeGetter.hpp"
+
+/**
+ * @def SUB_SCHEDULES_ENABLED
+ * @brief Indicates whether sub-schedules are supported
+ *
+ * @details Sub-schedules are currently not implemented so this has no effect
+ */
+/**
+ * @def GROUPS_ENABLED
+ * @brief Indicates whether scheduling groups are enabled
+ */
+#define GROUPS_ENABLED          0
+#define SUB_SCHEDULES_ENABLED   0
+
+
+/**
+ * @brief Namespace to access private members during test
+ *
+ * @details Define a namespace for the access of the private members to avoid conflicts
+ */
+namespace unit_test {
+	struct Tester;
+} // namespace unit_test
+
+/**
+ * @brief An implementation of the ECSS standard ST[11] service
+ *
+ * @details This service is taking care of the timed release of a received TC packet from the
+ * ground.
+ * @todo Define whether the parsed absolute release time is saved in the scheduled activity as an
+ * uint32_t or in the time format specified by the time management service.
+ */
+class TimeBasedSchedulingService : public Service {
+private:
+	/**
+	 * @brief Indicator of the schedule execution
+	 *
+	 * @details The schedule execution indicator will be updated by the process that is running
+	 * the time scheduling service.
+	 */
+	bool executionFunctionStatus = false; // True indicates "enabled" and False "disabled" state
+
+	MessageParser msgParser; // Parse TC packets
+
+	/**
+	 * @brief Request identifier of the received packet
+	 *
+	 * @details The request identifier consists of the application process ID, the packet
+	 * sequence count and the source ID, all defined in the ECSS standard.
+	 * @var applicationID Application process ID
+	 * @var sequenceCount Packet sequence count
+	 * @var sourceID Packet source ID
+	 */
+	struct RequestID {
+		uint16_t applicationID = 0;
+		uint16_t sequenceCount = 0;
+		uint8_t sourceID = 0;
+
+		bool operator!=(const RequestID &rightSide) const {
+			return (sequenceCount != rightSide.sequenceCount) or
+			       (applicationID != rightSide.applicationID) or (sourceID != rightSide.sourceID);
+		}
+	};
+
+	/**
+	 * @brief Instances of activities to run in the schedule
+	 *
+	 * @details All scheduled activities must contain the request they exist for, their release
+	 * time and the corresponding request identifier.
+	 * @var request Contains the received TC request
+	 * @var requestID Contains the unique request identifier for that activity
+	 * @var requestReleaseTime The absolute time is seconds of the request release
+	 */
+	struct ScheduledActivity {
+		Message request; // Hold the received command request
+		RequestID requestID; // Request ID, characteristic of the definition
+		uint32_t requestReleaseTime = 0; // Keep the command release time
+		// todo: If we decide to use sub-schedules, the ID of that has to be defined
+		// todo: If groups are used, then the group ID has to be defined here
+	};
+
+	/**
+	 * @brief Hold the scheduled activities
+	 *
+	 * @details The scheduled activities in this list are ordered by their release time, as the
+	 * standard requests.
+	 */
+	etl::list<ScheduledActivity, ECSS_MAX_NUMBER_OF_TIME_SCHED_ACTIVITIES> scheduledActivities;
+
+
+	/**
+	 * @brief Sort the activities by their release time
+	 *
+	 * @details The ECSS standard requires that the activities are sorted in the TM message
+	 * response. Also it is better to have the activities sorted.
+	 */
+	inline void sortActivitiesReleaseTime(etl::list<ScheduledActivity,
+		ECSS_MAX_NUMBER_OF_TIME_SCHED_ACTIVITIES> &schedActivities) {
+		schedActivities.sort([](ScheduledActivity const &leftSide, ScheduledActivity const
+		&rightSide) { return leftSide.requestReleaseTime < rightSide.requestReleaseTime; });
+	}
+
+	/**
+	 * @brief Define a friend in order to be able to access private members during testing
+	 *
+	 * @details The private members defined in this class, must not in any way be public to avoid
+	 * misuse. During testing, access to private members for verification is required, so an
+	 * access friend structure is defined here.
+	 */
+	friend struct ::unit_test::Tester;
+
+
+public:
+	/**
+	 * @brief Class constructor
+	 * @details Initializes the serviceType
+	 */
+	TimeBasedSchedulingService();
+
+	/**
+	 * @brief TC[11,1] enable the time-based schedule execution function
+	 *
+	 * @details Enables the time-based command execution scheduling
+	 * @param request Provide the received message as a parameter
+	 */
+	void enableScheduleExecution(Message &request);
+
+	/**
+	 * @breif TC[11,2] disable the time-based schedule execution function
+	 *
+	 * @details Disables the time-based command execution scheduling
+	 * @param request Provide the received message as a parameter
+	 */
+	void disableScheduleExecution(Message &request);
+
+	/**
+	 * @brief TC[11,3] reset the time-based schedule
+	 *
+	 * @details Resets the time-based command execution schedule, by clearing all scheduled
+	 * activities.
+	 * @param request Provide the received message as a parameter
+	 */
+	void resetSchedule(Message &request);
+
+	/**
+	 * @brief TC[11,4] insert activities into the time based schedule
+	 *
+	 * @details Add activities into the schedule for future execution. The activities are inserted
+	 * by ascending order of their release time. This done to avoid confusion during the
+	 * execution of the schedule and also to make things easier whenever a release time sorted
+	 * report is requested by he corresponding service.
+	 * @param request Provide the received message as a parameter
+	 * @todo Definition of the time format is required
+	 * @throws ExecutionStartError If there is request to be inserted and the maximum
+	 * number of activities in the current schedule has been reached, then an @ref
+	 * ErrorHandler::ExecutionStartErrorType is being issued.  Also if the release time of the
+	 * request is less than a set time margin, defined in @ref ECSS_TIME_MARGIN_FOR_ACTIVATION,
+	 * from the current time a @ref ErrorHandler::ExecutionStartErrorType is also issued.
+	 */
+	void insertActivities(Message &request);
+
+	/**
+	 * @brief TC[11,15] time-shift all scheduled activities
+	 *
+	 * @details All scheduled activities are shifted per user request. The relative time offset
+	 * received and tested against the current time.
+	 * @param request Provide the received message as a parameter
+	 * @todo Definition of the time format is required for the relative time format
+	 * @throws ExecutionStartError If the release time of the request is less than a
+	 * set time margin, defined in @ref ECSS_TIME_MARGIN_FOR_ACTIVATION, from the current time an
+	 * @ref ErrorHandler::ExecutionStartErrorType report is issued for that instruction.
+	 */
+	void timeShiftAllActivities(Message &request);
+
+	/**
+	 * @brief TC[11,16] detail-report all activities
+	 *
+	 * @details Send a detailed report about the status of all the activities
+	 * on the current schedule. Generates a TM[11,10] response.
+	 * @param request Provide the received message as a parameter
+	 * @todo Replace the time parsing with the time parser
+	 */
+	void detailReportAllActivities(Message &request);
+
+	/**
+	 * @brief TC[11,9] detail-report activities identified by request identifier
+	 *
+	 * @details Send a detailed report about the status of the requested activities, based on the
+	 * provided request identifier. Generates a TM[11,10] response. The matched activities are
+	 * contained in the report, in an ascending order based on their release time.
+	 * @param request Provide the received message as a parameter
+	 * @todo Replace time parsing with the time parser
+	 * @throws ExecutionStartError If a requested activity, identified by the provided
+	 * request identifier is not found in the schedule issue an @ref
+	 * ErrorHandler::ExecutionStartErrorType for that instruction.
+	 */
+	void detailReportActivitiesByID(Message &request);
+
+	/**
+	 * @brief TC[11,12] summary-report activities identified by request identifier
+	 *
+	 * @details Send a summary report about the status of the requested activities. Generates a
+	 * TM[11,13] response, with activities ordered in an ascending order, based on their release
+	 * time.
+	 * @param request Provide the received message as a parameter
+	 * @throws ExecutionStartError If a requested activity, identified by the provided
+	 * request identifier is not found in the schedule issue an @ref
+	 * ErrorHandler::ExecutionStartErrorType for that instruction.
+	 */
+	void summaryReportActivitiesByID(Message &request);
+
+	/**
+	 * @brief TC[11,5] delete time-based scheduled activities identified by a request identifier
+	 *
+	 * @details Delete certain activities by using the unique request identifier.
+	 * @param request Provide the received message as a parameter
+	 * @throws ExecutionStartError If a requested activity, identified by the provided
+	 * request identifier is not found in the schedule issue an @ref
+	 * ErrorHandler::ExecutionStartErrorType for that instruction.
+	 */
+	void deleteActivitiesByID(Message &request);
+
+	/**
+	 * @brief TC[11,7] time-shift scheduled activities identified by a request identifier
+	 *
+	 * @details Time-shift certain activities by using the unique request identifier
+	 * @param request Provide the received message as a parameter
+	 * @todo Definition of the time format is required
+	 * @throws ExecutionStartError If the requested time offset is less than the earliest
+	 * time from the currently scheduled activities plus the @ref ECSS_TIME_MARGIN_FOR_ACTIVATION,
+	 * then the request is rejected and an @ref ErrorHandler::ExecutionStartErrorType is issued.
+	 * Also if an activity with a specified request identifier is not found, generate a failed
+	 * start of execution for that specific instruction.
+	 */
+	void timeShiftActivitiesByID(Message &request);
+};
+
+#endif //ECSS_SERVICES_TIMEBASEDSCHEDULINGSERVICE_HPP
diff --git a/inc/etl/String.hpp b/inc/etl/String.hpp
index 8fbd401cc4eb033cce095feb13d4fa577aa7d013..f9198df199888453fa690067020528ce9c2d1a36 100644
--- a/inc/etl/String.hpp
+++ b/inc/etl/String.hpp
@@ -1,7 +1,6 @@
 #ifndef ECSS_SERVICES_ETL_STRING_HPP
 #define ECSS_SERVICES_ETL_STRING_HPP
 
-
 #include <cstddef>
 #include <etl/cstring.h>
 
diff --git a/lib/Catch2 b/lib/Catch2
index d63307279412de3870cf97cc6802bae8ab36089e..62460fafe6b54c3173bc5cbc46d05a5f071017ff 160000
--- a/lib/Catch2
+++ b/lib/Catch2
@@ -1 +1 @@
-Subproject commit d63307279412de3870cf97cc6802bae8ab36089e
+Subproject commit 62460fafe6b54c3173bc5cbc46d05a5f071017ff
diff --git a/src/Message.cpp b/src/Message.cpp
index 409e65e4e18ae303c8cbcac02422172615943184..0127ecf679d0bdf93600413653eea9878f20690e 100644
--- a/src/Message.cpp
+++ b/src/Message.cpp
@@ -145,6 +145,7 @@ void Message::readString(uint8_t *string, uint16_t size) {
 	ASSERT_REQUEST(size < ECSS_MAX_STRING_SIZE, ErrorHandler::StringTooShort);
 
 	memcpy(string, data + readPosition, size);
+	string[size] = '\0'; // todo: Use that for now to avoid problems. Later to be removed
 
 	readPosition += size;
 }
diff --git a/src/MessageParser.cpp b/src/MessageParser.cpp
index af4988a1a302b2da35eed9d2cbe45e6b1508b706..d382dd3432bc10b1dbe1b097db8afec2a56827ef 100644
--- a/src/MessageParser.cpp
+++ b/src/MessageParser.cpp
@@ -1,4 +1,3 @@
-#include <cstring>
 #include <Services/EventActionService.hpp>
 #include <ServicePool.hpp>
 #include "ErrorHandler.hpp"
@@ -53,7 +52,7 @@ Message MessageParser::parse(uint8_t *data, uint32_t length) {
 	return message;
 }
 
-void MessageParser::parseTC(uint8_t *data, uint16_t length, Message &message) {
+void MessageParser::parseTC(const uint8_t *data, uint16_t length, Message &message) {
 	ErrorHandler::assertRequest(length >= 5, message, ErrorHandler::UnacceptableMessage);
 
 	// Individual fields of the TC header
@@ -61,6 +60,8 @@ void MessageParser::parseTC(uint8_t *data, uint16_t length, Message &message) {
 	uint8_t serviceType = data[1];
 	uint8_t messageType = data[2];
 
+	// todo: Fix this parsing function, because it assumes PUS header in data, which is not true
+	//  with the current implementation
 	ErrorHandler::assertRequest(pusVersion == 2, message, ErrorHandler::UnacceptableMessage);
 
 	// Remove the length of the header
@@ -74,15 +75,34 @@ void MessageParser::parseTC(uint8_t *data, uint16_t length, Message &message) {
 	message.dataSize = length;
 }
 
-Message MessageParser::parseRequestTC(String<ECSS_EVENT_SERVICE_STRING_SIZE> data) {
+Message MessageParser::parseRequestTC(String<ECSS_TC_REQUEST_STRING_SIZE> data) {
 	Message message;
 	auto *dataInt = reinterpret_cast<uint8_t *>(data.data());
 	message.packetType = Message::TC;
-	parseTC(dataInt, ECSS_EVENT_SERVICE_STRING_SIZE, message);
+	parseTC(dataInt, ECSS_TC_REQUEST_STRING_SIZE, message);
 	return message;
 }
 
-void MessageParser::parseTM(uint8_t *data, uint16_t length, Message &message) {
+Message MessageParser::parseRequestTC(uint8_t* data) {
+	Message message;
+	message.packetType = Message::TC;
+	parseTC(data, ECSS_TC_REQUEST_STRING_SIZE, message);
+	return message;
+}
+
+String<ECSS_TC_REQUEST_STRING_SIZE> MessageParser::convertTCToStr(Message &message) {
+	uint8_t tempString[ECSS_TC_REQUEST_STRING_SIZE] = {0};
+
+	tempString[0] = ECSS_PUS_VERSION << 4; // Assign the pusVersion = 2
+	tempString[1] = message.serviceType;
+	tempString[2] = message.messageType;
+	memcpy(tempString + 5, message.data, ECSS_TC_REQUEST_STRING_SIZE - 5);
+	String<ECSS_TC_REQUEST_STRING_SIZE> dataString(tempString);
+
+	return dataString;
+}
+
+void MessageParser::parseTM(const uint8_t *data, uint16_t length, Message &message) {
 	ErrorHandler::assertRequest(length >= 5, message, ErrorHandler::UnacceptableMessage);
 
 	// Individual fields of the TM header
diff --git a/src/Service.cpp b/src/Service.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..66fdd045bb9f777cea939f8c32fb344a995263a5
--- /dev/null
+++ b/src/Service.cpp
@@ -0,0 +1 @@
+#include "Service.hpp"
diff --git a/src/Services/EventActionService.cpp b/src/Services/EventActionService.cpp
index 2ace42dd9796cfff95120b189ed95e35e44c9722..6ac29c0531184da62bbd617f94189fb240995cf6 100644
--- a/src/Services/EventActionService.cpp
+++ b/src/Services/EventActionService.cpp
@@ -34,12 +34,12 @@ void EventActionService::addEventActionDefinitions(Message message) {
 			eventActionDefinitionArray[index].enabled = true;
 			eventActionDefinitionArray[index].applicationId = applicationID;
 			eventActionDefinitionArray[index].eventDefinitionID = eventDefinitionID;
-			if (message.dataSize - 4 > ECSS_EVENT_SERVICE_STRING_SIZE) {
+			if (message.dataSize - 4 > ECSS_TC_REQUEST_STRING_SIZE) {
 				ErrorHandler::reportInternalError(ErrorHandler::InternalErrorType::MessageTooLarge);
 			} else {
-				char data[ECSS_EVENT_SERVICE_STRING_SIZE];
+				char data[ECSS_TC_REQUEST_STRING_SIZE];
 				message.readString(data, message.dataSize - 4);
-				eventActionDefinitionArray[index].request = String<ECSS_EVENT_SERVICE_STRING_SIZE>(
+				eventActionDefinitionArray[index].request = String<ECSS_TC_REQUEST_STRING_SIZE>(
 					data);
 			}
 		}
@@ -150,11 +150,11 @@ void EventActionService::eventActionStatusReport() {
 		}
 	}
 	report.appendUint8(count);
-	for (uint16_t i = 0; i < ECSS_EVENT_ACTION_STRUCT_ARRAY_SIZE; i++) {
-		if (not eventActionDefinitionArray[i].empty) {
-			report.appendEnum16(eventActionDefinitionArray[i].applicationId);
-			report.appendEnum16(eventActionDefinitionArray[i].eventDefinitionID);
-			report.appendBoolean(eventActionDefinitionArray[i].enabled);
+	for (const auto &definition : eventActionDefinitionArray) {
+		if (not definition.empty) {
+			report.appendEnum16(definition.applicationId);
+			report.appendEnum16(definition.eventDefinitionID);
+			report.appendBoolean(definition.enabled);
 		}
 	}
 	storeMessage(report);
@@ -178,13 +178,13 @@ void EventActionService::disableEventActionFunction(Message message) {
 void EventActionService::executeAction(uint16_t eventID) {
 	// Custom function
 	if (eventActionFunctionStatus) {
-		for (uint16_t i = 0; i < ECSS_EVENT_ACTION_STRUCT_ARRAY_SIZE; i++) {
-			if (not eventActionDefinitionArray[i].empty &&
-			    eventActionDefinitionArray[i].enabled) {
-				if (eventActionDefinitionArray[i].eventDefinitionID == eventID) {
+		for (const auto &definition : eventActionDefinitionArray) {
+			if (not definition.empty &&
+			    definition.enabled) {
+				if (definition.eventDefinitionID == eventID) {
 					MessageParser messageParser;
 					Message message = messageParser.parseRequestTC(
-						eventActionDefinitionArray[i].request);
+						definition.request);
 					messageParser.execute(message);
 				}
 			}
diff --git a/src/Services/FunctionManagementService.cpp b/src/Services/FunctionManagementService.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8dcc602792b45199d17bf95e53330905ebcfaab0
--- /dev/null
+++ b/src/Services/FunctionManagementService.cpp
@@ -0,0 +1,52 @@
+#include "Services/FunctionManagementService.hpp"
+
+void FunctionManagementService::call(Message& msg) {
+	msg.resetRead();
+	ErrorHandler::assertRequest(msg.packetType == Message::TC, msg,
+	                            ErrorHandler::AcceptanceErrorType::UnacceptableMessage);
+	ErrorHandler::assertRequest(msg.messageType == 1, msg,
+	                            ErrorHandler::AcceptanceErrorType::UnacceptableMessage);
+	ErrorHandler::assertRequest(msg.serviceType == 8, msg,
+	                            ErrorHandler::AcceptanceErrorType::UnacceptableMessage);
+
+	uint8_t funcName[FUNC_NAME_LENGTH];  // the function's name
+	uint8_t funcArgs[MAX_ARG_LENGTH];    // arguments for the function
+
+	msg.readString(funcName, FUNC_NAME_LENGTH);
+	msg.readString(funcArgs, MAX_ARG_LENGTH);
+
+	if (msg.dataSize > FUNC_NAME_LENGTH + MAX_ARG_LENGTH) {
+		ErrorHandler::reportError(msg,
+			ErrorHandler::ExecutionStartErrorType::UnknownExecutionStartError);  // report failed
+			// start of execution as requested by the standard
+			return;
+	}
+
+	// locate the appropriate function pointer
+	String<FUNC_NAME_LENGTH> name(funcName);
+	FunctionMap::iterator iter = funcPtrIndex.find(name);
+	void (*selected)(String<MAX_ARG_LENGTH>);
+
+	if (iter != funcPtrIndex.end()) {
+		selected = *iter->second;
+	} else {
+		ErrorHandler::reportError(msg,
+			ErrorHandler::ExecutionStartErrorType::UnknownExecutionStartError);
+		return;
+	}
+
+	// execute the function if there are no obvious flaws (defined in the standard, pg.158)
+	selected(funcArgs);
+}
+
+void FunctionManagementService::include(String<FUNC_NAME_LENGTH> funcName, void(*ptr)
+	(String<MAX_ARG_LENGTH>)) {
+
+	if (not funcPtrIndex.full()) {  // CAUTION: etl::map won't check by itself if it's full
+		// before attempting to insert a key-value pair, causing segmentation faults. Check first!
+		funcName.append(FUNC_NAME_LENGTH - funcName.length(), '\0');
+		funcPtrIndex.insert(std::make_pair(funcName, ptr));
+	} else {
+		ErrorHandler::reportInternalError(ErrorHandler::InternalErrorType::FunctionMapFull);
+	}
+}
diff --git a/src/Services/LargePacketTransferService.cpp b/src/Services/LargePacketTransferService.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fedfec8f97b65dd9264502c8ef45c8e801e4e084
--- /dev/null
+++ b/src/Services/LargePacketTransferService.cpp
@@ -0,0 +1,55 @@
+#include <Services/LargePacketTransferService.hpp>
+#include "Message.hpp"
+#include <etl/String.hpp>
+
+void LargePacketTransferService::firstDownlinkPartReport(uint16_t
+	largeMessageTransactionIdentifier,
+    uint16_t partSequenceNumber,
+    const String<ECSS_MAX_FIXED_OCTET_STRING_SIZE> &string) {
+	// TM[13,1]
+
+	Message report = createTM(1);
+	report.appendUint16(largeMessageTransactionIdentifier); // large message transaction identifier
+	report.appendUint16(partSequenceNumber); // part sequence number
+	report.appendOctetString(string); // fixed octet-string
+	storeMessage(report);
+}
+
+void LargePacketTransferService::intermediateDownlinkPartReport(uint16_t
+	largeMessageTransactionIdentifier, uint16_t partSequenceNumber, const
+	String<ECSS_MAX_FIXED_OCTET_STRING_SIZE> &string) {
+	// TM[13,2]
+	Message report = createTM(2);
+	report.appendUint16(largeMessageTransactionIdentifier); // large message transaction identifier
+	report.appendUint16(partSequenceNumber); // part sequence number
+	report.appendOctetString(string); // fixed octet-string
+	storeMessage(report);
+}
+
+void LargePacketTransferService::lastDownlinkPartReport(uint16_t largeMessageTransactionIdentifier,
+	uint16_t partSequenceNumber, const String<ECSS_MAX_FIXED_OCTET_STRING_SIZE> &string) {
+	// TM[13,3]
+	Message report = createTM(3);
+	report.appendUint16(largeMessageTransactionIdentifier); // large message transaction identifier
+	report.appendUint16(partSequenceNumber); // part sequence number
+	report.appendOctetString(string); // fixed octet-string
+	storeMessage(report);
+}
+
+String<ECSS_MAX_FIXED_OCTET_STRING_SIZE> LargePacketTransferService::firstUplinkPart(
+	const String<ECSS_MAX_FIXED_OCTET_STRING_SIZE> &string) {
+	// TC[13,9]
+	return string;
+}
+
+String<ECSS_MAX_FIXED_OCTET_STRING_SIZE> LargePacketTransferService::intermediateUplinkPart(
+	const String<ECSS_MAX_FIXED_OCTET_STRING_SIZE> &string) {
+	// TC[13,10]
+	return string;
+}
+
+String<ECSS_MAX_FIXED_OCTET_STRING_SIZE>
+LargePacketTransferService::lastUplinkPart(const String<ECSS_MAX_FIXED_OCTET_STRING_SIZE> &string) {
+	// TC[13, 11]
+	return string;
+}
diff --git a/src/Services/TimeBasedSchedulingService.cpp b/src/Services/TimeBasedSchedulingService.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a4b74861f91167a5dbbcd942daa51405e66265d5
--- /dev/null
+++ b/src/Services/TimeBasedSchedulingService.cpp
@@ -0,0 +1,283 @@
+#include "Services/TimeBasedSchedulingService.hpp"
+
+
+TimeBasedSchedulingService::TimeBasedSchedulingService() {
+	serviceType = 11;
+}
+
+void TimeBasedSchedulingService::enableScheduleExecution(Message &request) {
+
+	// Check if the correct packet is being processed
+	assert(request.serviceType == 11);
+	assert(request.messageType == 1);
+
+	executionFunctionStatus = true; // Enable the service
+}
+
+void TimeBasedSchedulingService::disableScheduleExecution(Message &request) {
+
+	// Check if the correct packet is being processed
+	assert(request.serviceType == 11);
+	assert(request.messageType == 2);
+
+	executionFunctionStatus = false; // Disable the service
+}
+
+void TimeBasedSchedulingService::resetSchedule(Message &request) {
+
+	// Check if the correct packet is being processed
+	assert(request.serviceType == 11);
+	assert(request.messageType == 3);
+
+	executionFunctionStatus = false; // Disable the service
+	scheduledActivities.clear(); // Delete all scheduled activities
+	// todo: Add resetting for sub-schedules and groups, if defined
+}
+
+void TimeBasedSchedulingService::insertActivities(Message &request) {
+
+	// Check if the correct packet is being processed
+	assert(request.serviceType == 11);
+	assert(request.messageType == 4);
+
+	// todo: Get the sub-schedule ID if they are implemented
+	uint16_t iterationCount = request.readUint16(); // Get the iteration count, (N)
+	while (iterationCount--) {
+		// todo: Get the group ID first, if groups are used
+		uint32_t currentTime = TimeGetter::getSeconds(); // Get the current system time
+
+		uint32_t releaseTime = request.readUint32(); // Get the specified release time
+		if ((not scheduledActivities.available()) ||
+		    (releaseTime < (currentTime + ECSS_TIME_MARGIN_FOR_ACTIVATION))) {
+			ErrorHandler::reportError(request, ErrorHandler::InstructionExecutionStartError);
+			request.skipBytes(ECSS_TC_REQUEST_STRING_SIZE);
+		} else {
+			// Get the TC packet request
+			uint8_t requestData[ECSS_TC_REQUEST_STRING_SIZE] = {0};
+			request.readString(requestData, ECSS_TC_REQUEST_STRING_SIZE);
+			Message receivedTCPacket = msgParser.parseRequestTC(requestData);
+			ScheduledActivity newActivity; // Create the new activity
+
+			// Assign the attributes to the newly created activity
+			newActivity.request = receivedTCPacket;
+			newActivity.requestReleaseTime = releaseTime;
+
+			// todo: When implemented save the source ID
+			newActivity.requestID.applicationID = request.applicationId;
+			newActivity.requestID.sequenceCount = request.packetSequenceCount;
+
+			scheduledActivities.push_back(newActivity); // Insert the new activities
+		}
+	}
+	sortActivitiesReleaseTime(scheduledActivities); // Sort activities by their release time
+}
+
+void TimeBasedSchedulingService::timeShiftAllActivities(Message &request) {
+
+	// Check if the correct packet is being processed
+	assert(request.serviceType == 11);
+	assert(request.messageType == 15);
+
+	uint32_t current_time = TimeGetter::getSeconds(); // Get the current system time
+
+	// Find the earliest release time. It will be the first element of the iterator pair
+	const auto releaseTimes = etl::minmax_element(scheduledActivities.begin(),
+	                                              scheduledActivities.end(),
+	                                              [](ScheduledActivity const &leftSide,
+	                                                 ScheduledActivity const &
+	                                                 rightSide) {
+		                                              return leftSide.requestReleaseTime <
+		                                                     rightSide.requestReleaseTime;
+	                                              });
+	// todo: Define what the time format is going to be
+	int32_t relativeOffset = request.readSint32(); // Get the relative offset
+	if ((releaseTimes.first->requestReleaseTime + relativeOffset) <
+	    (current_time + ECSS_TIME_MARGIN_FOR_ACTIVATION)) {
+		// Report the error
+		ErrorHandler::reportError(request, ErrorHandler::SubServiceExecutionStartError);
+	} else {
+		for (auto &activity : scheduledActivities) {
+			activity.requestReleaseTime += relativeOffset; // Time shift each activity
+		}
+	}
+}
+
+void TimeBasedSchedulingService::timeShiftActivitiesByID(Message &request) {
+
+	// Check if the correct packet is being processed
+	assert(request.serviceType == 11);
+	assert(request.messageType == 7);
+
+	uint32_t current_time = TimeGetter::getSeconds(); // Get the current system time
+
+	int32_t relativeOffset = request.readSint32(); // Get the offset first
+	uint16_t iterationCount = request.readUint16(); // Get the iteration count, (N)
+	while (iterationCount--) {
+		// Parse the request ID
+		RequestID receivedRequestID; // Save the received request ID
+		receivedRequestID.sourceID = request.readUint8(); // Get the source ID
+		receivedRequestID.applicationID = request.readUint16(); // Get the application ID
+		receivedRequestID.sequenceCount = request.readUint16(); // Get the sequence count
+
+		// Try to find the activity with the requested request ID
+		auto requestIDMatch = etl::find_if_not(scheduledActivities.begin(),
+		                                       scheduledActivities.end(),
+		                                       [&receivedRequestID]
+			                                       (ScheduledActivity const &currentElement) {
+			                                       return receivedRequestID !=
+			                                              currentElement.requestID;
+		                                       });
+
+		if (requestIDMatch != scheduledActivities.end()) {
+			// If the relative offset does not meet the restrictions issue an error
+			if ((requestIDMatch->requestReleaseTime + relativeOffset) <
+			    (current_time + ECSS_TIME_MARGIN_FOR_ACTIVATION)) {
+				ErrorHandler::reportError(request, ErrorHandler::InstructionExecutionStartError);
+			} else {
+				requestIDMatch->requestReleaseTime += relativeOffset; // Add the time offset
+			}
+		} else {
+			ErrorHandler::reportError(request, ErrorHandler::InstructionExecutionStartError);
+		}
+	}
+	sortActivitiesReleaseTime(scheduledActivities); // Sort activities by their release time
+}
+
+void TimeBasedSchedulingService::deleteActivitiesByID(Message &request) {
+
+	// Check if the correct packet is being processed
+	assert(request.serviceType == 11);
+	assert(request.messageType == 5);
+
+	uint16_t iterationCount = request.readUint16(); // Get the iteration count, (N)
+	while (iterationCount--) {
+		// Parse the request ID
+		RequestID receivedRequestID; // Save the received request ID
+		receivedRequestID.sourceID = request.readUint8(); // Get the source ID
+		receivedRequestID.applicationID = request.readUint16(); // Get the application ID
+		receivedRequestID.sequenceCount = request.readUint16(); // Get the sequence count
+
+		// Try to find the activity with the requested request ID
+		const auto requestIDMatch = etl::find_if_not(scheduledActivities.begin(),
+		                                             scheduledActivities.end(), [&receivedRequestID]
+			                                             (ScheduledActivity const &currentElement) {
+				return receivedRequestID != currentElement
+					.requestID;
+			});
+
+		if (requestIDMatch != scheduledActivities.end()) {
+			scheduledActivities.erase(requestIDMatch); // Delete activity from the schedule
+		} else {
+			ErrorHandler::reportError(request, ErrorHandler::InstructionExecutionStartError);
+		}
+	}
+}
+
+void TimeBasedSchedulingService::detailReportAllActivities(Message &request) {
+
+	// Check if the correct packet is being processed
+	assert(request.serviceType == 11);
+	assert(request.messageType == 16);
+
+	// Create the report message object of telemetry message subtype 10 for each activity
+	Message report = createTM(10);
+	report.appendUint16(static_cast<uint16_t >(scheduledActivities.size()));
+
+	for (auto &activity : scheduledActivities) {
+		// todo: append sub-schedule and group ID if they are defined
+
+		report.appendUint32(activity.requestReleaseTime);
+		report.appendString(msgParser.convertTCToStr(activity.request));
+	}
+	storeMessage(report); // Save the report
+}
+
+void TimeBasedSchedulingService::detailReportActivitiesByID(Message &request) {
+
+	// Check if the correct packet is being processed
+	assert(request.serviceType == 11);
+	assert(request.messageType == 9);
+
+	// Create the report message object of telemetry message subtype 10 for each activity
+	Message report = createTM(10);
+	etl::list<ScheduledActivity, ECSS_MAX_NUMBER_OF_TIME_SCHED_ACTIVITIES> matchedActivities;
+
+	uint16_t iterationCount = request.readUint16(); // Get the iteration count, (N)
+	while (iterationCount--) {
+		// Parse the request ID
+		RequestID receivedRequestID; // Save the received request ID
+		receivedRequestID.sourceID = request.readUint8(); // Get the source ID
+		receivedRequestID.applicationID = request.readUint16(); // Get the application ID
+		receivedRequestID.sequenceCount = request.readUint16(); // Get the sequence count
+
+		// Try to find the activity with the requested request ID
+		const auto requestIDMatch = etl::find_if_not(scheduledActivities.begin(),
+		                                             scheduledActivities.end(), [&receivedRequestID]
+			                                             (ScheduledActivity const &currentElement) {
+				return receivedRequestID != currentElement
+					.requestID;
+			});
+
+		if (requestIDMatch != scheduledActivities.end()) {
+			matchedActivities.push_back(*requestIDMatch); // Save the matched activity
+		} else {
+			ErrorHandler::reportError(request, ErrorHandler::InstructionExecutionStartError);
+		}
+	}
+
+    sortActivitiesReleaseTime(matchedActivities); // Sort activities by their release time
+
+	// todo: append sub-schedule and group ID if they are defined
+	report.appendUint16(static_cast<uint16_t >(matchedActivities.size()));
+	for (auto &match : matchedActivities) {
+		report.appendUint32(match.requestReleaseTime); // todo: Replace with the time parser
+		report.appendString(msgParser.convertTCToStr(match.request));
+	}
+	storeMessage(report); // Save the report
+}
+
+void TimeBasedSchedulingService::summaryReportActivitiesByID(Message &request) {
+
+	// Check if the correct packet is being processed
+	assert(request.serviceType == 11);
+	assert(request.messageType == 12);
+
+	// Create the report message object of telemetry message subtype 13 for each activity
+	Message report = createTM(13);
+	etl::list<ScheduledActivity, ECSS_MAX_NUMBER_OF_TIME_SCHED_ACTIVITIES> matchedActivities;
+
+	uint16_t iterationCount = request.readUint16(); // Get the iteration count, (N)
+	while (iterationCount--) {
+		// Parse the request ID
+		RequestID receivedRequestID; // Save the received request ID
+		receivedRequestID.sourceID = request.readUint8(); // Get the source ID
+		receivedRequestID.applicationID = request.readUint16(); // Get the application ID
+		receivedRequestID.sequenceCount = request.readUint16(); // Get the sequence count
+
+		// Try to find the activity with the requested request ID
+		auto requestIDMatch = etl::find_if_not(scheduledActivities.begin(),
+		                                       scheduledActivities.end(), [&receivedRequestID]
+			                                       (ScheduledActivity const &currentElement) {
+				return receivedRequestID != currentElement
+					.requestID;
+			});
+
+		if (requestIDMatch != scheduledActivities.end()) {
+			matchedActivities.push_back(*requestIDMatch);
+		} else {
+			ErrorHandler::reportError(request, ErrorHandler::InstructionExecutionStartError);
+		}
+	}
+	sortActivitiesReleaseTime(matchedActivities); // Sort activities by their release time
+
+	// todo: append sub-schedule and group ID if they are defined
+	report.appendUint16(static_cast<uint16_t >(matchedActivities.size()));
+	for (auto &match : matchedActivities) {
+		// todo: append sub-schedule and group ID if they are defined
+		report.appendUint32(match.requestReleaseTime);
+		report.appendUint8(match.requestID.sourceID);
+		report.appendUint16(match.requestID.applicationID);
+		report.appendUint16(match.requestID.sequenceCount);
+	}
+	storeMessage(report); // Save the report
+}
diff --git a/src/main.cpp b/src/main.cpp
index 5615e2641d4329f20a94335f149b62b05f9279df..4e5a4f4652fe4463d4d20f1586d15eb48c922ec0 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -7,11 +7,14 @@
 #include "Services/RequestVerificationService.hpp"
 #include "Services/MemoryManagementService.hpp"
 #include "Services/EventReportService.hpp"
+#include "Services/FunctionManagementService.hpp"
 #include "Services/TimeManagementService.hpp"
 #include "Services/EventActionService.hpp"
+#include "Services/LargePacketTransferService.hpp"
+#include "Services/TimeBasedSchedulingService.hpp"
+#include "ServicePool.hpp"
 #include "Message.hpp"
 #include "MessageParser.hpp"
-#include "Services/MemoryManagementService.hpp"
 #include "Helpers/CRCHelper.hpp"
 #include "ErrorHandler.hpp"
 #include "etl/String.hpp"
@@ -239,22 +242,24 @@ int main() {
 	eventActionService.addEventActionDefinitions(eventActionDefinition);
 	Message eventActionDefinition1(19, 1, Message::TC, 1);
 	eventActionDefinition1.appendEnum16(0);
-	eventActionDefinition1.appendEnum16(2);
+	eventActionDefinition1.appendEnum16(3);
 	TCdata = "hi1";
 	eventActionDefinition1.appendString(TCdata);
 	eventActionService.addEventActionDefinitions(eventActionDefinition1);
 	Message eventActionDefinition2(19, 1, Message::TC, 1);
 	eventActionDefinition2.appendEnum16(0);
-	eventActionDefinition2.appendEnum16(3);
+	eventActionDefinition2.appendEnum16(4);
 	TCdata = "hi2";
 	eventActionDefinition2.appendString(TCdata);
 	eventActionService.addEventActionDefinitions(eventActionDefinition2);
 	Message eventActionDefinition3(19, 5, Message::TC, 1);
-	eventActionDefinition3.appendUint16(2);
+	eventActionDefinition3.appendUint16(3);
 	eventActionDefinition3.appendUint16(0);
 	eventActionDefinition3.appendUint16(2);
 	eventActionDefinition3.appendUint16(0);
 	eventActionDefinition3.appendUint16(3);
+	eventActionDefinition3.appendUint16(0);
+	eventActionDefinition3.appendUint16(4);
 
 	eventActionService.disableEventActionDefinitions(eventActionDefinition3);
 	std::cout << "Status of position 0,1,2 should be 000:" << eventActionService
@@ -269,15 +274,17 @@ int main() {
 	eventActionDefinition5.appendUint16(0);
 	eventActionDefinition5.appendUint16(3);
 	eventActionService.enableEventActionDefinitions(eventActionDefinition5);
-	std::cout << "\nStatus of position 0,1,2 should be 111:" << eventActionService
+	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(1);
+	eventActionDefinition4.appendUint16(2);
 	eventActionDefinition4.appendUint16(0);
 	eventActionDefinition4.appendUint16(2);
+	eventActionDefinition4.appendUint16(0);
+	eventActionDefinition4.appendUint16(3);
 
 	eventActionService.deleteEventActionDefinitions(eventActionDefinition4);
 	std::cout << "\nPositions 0,1 empty should be 11:" << static_cast<uint16_t>(eventActionService
@@ -287,8 +294,54 @@ int main() {
 	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);
+	.eventActionDefinitionArray[0].empty);
+
+
+	// ST13 test
+
+	LargePacketTransferService largePacketTransferService;
+	String<256> dataToTransfer = "12345678";
+	largePacketTransferService.firstDownlinkPartReport(1, 1, dataToTransfer);
+
+
+	// ST[11] test
+	TimeBasedSchedulingService timeBasedSchedulingService;
+	MessageParser msgParser;
+	auto currentTime = static_cast<uint32_t >(time(nullptr)); // Get the current system time
+	std::cout << "\n\nST[11] service is running";
+	std::cout << "\nCurrent time in seconds (UNIX epoch): " << currentTime << std::endl;
+
+	Message receivedMsg = Message(11, 1, Message::TC, 1);
+	Message testMessage1(6, 5, Message::TC, 1), testMessage2(4, 5, Message::TC, 1);
+	testMessage1.appendUint16(4253); // Append dummy data
+	testMessage2.appendUint16(45667); // Append dummy data
+
+	timeBasedSchedulingService.enableScheduleExecution(receivedMsg); // Enable the schedule
+
+	// Insert activities in the schedule
+	receivedMsg = Message(11, 4, Message::TC, 1);
+	receivedMsg.appendUint16(2); // Total number of requests
+
+	receivedMsg.appendUint32(currentTime + 1556435);
+	receivedMsg.appendString(msgParser.convertTCToStr(testMessage1));
+
+	receivedMsg.appendUint32(currentTime + 1957232);
+	receivedMsg.appendString(msgParser.convertTCToStr(testMessage2));
+	timeBasedSchedulingService.insertActivities(receivedMsg);
+
+	// Time shift activities
+	receivedMsg = Message(11, 15, Message::TC, 1);
+	receivedMsg.appendSint32(-6789);
+	timeBasedSchedulingService.timeShiftAllActivities(receivedMsg);
+	std::cout << "Activities should be time shifted by: " << -6789 << " seconds." << std::endl;
+
+	// Report the activities
+	receivedMsg = Message(11, 16, Message::TC, 1);
+	timeBasedSchedulingService.detailReportAllActivities(receivedMsg);
 
+	// Report the activities by ID
+	receivedMsg = Message(11, 12, Message::TC, 1);
+	timeBasedSchedulingService.summaryReportActivitiesByID(receivedMsg);
 
 	return 0;
 }
diff --git a/test/Services/FunctionManagementService.cpp b/test/Services/FunctionManagementService.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1cd99bf509a995fd08ce849965d0cd6d3f28a83c
--- /dev/null
+++ b/test/Services/FunctionManagementService.cpp
@@ -0,0 +1,52 @@
+#include "catch2/catch.hpp"
+#include "Services/FunctionManagementService.hpp"
+#include "ServicePool.hpp"
+#include "ServiceTests.hpp"
+#include <iostream>
+
+FunctionManagementService & fms = Services.functionManagement;
+
+void test(String<MAX_ARG_LENGTH> a) {
+	std::cout << a.c_str() << std::endl;
+}
+
+TEST_CASE("ST[08] - Call Tests") {
+
+	SECTION("Malformed name") {
+		ServiceTests::reset();
+		fms.include(String<FUNC_NAME_LENGTH>("test"), &test);
+		Message msg(8, 1, Message::TC, 1);
+		msg.appendString(String<FUNC_NAME_LENGTH>("t3st"));
+		fms.call(msg);
+		CHECK(ServiceTests::get(0).messageType == 4);
+		CHECK(ServiceTests::get(0).serviceType == 1);
+	}
+
+	SECTION("Too long message") {
+		ServiceTests::reset();
+		fms.include(String<FUNC_NAME_LENGTH>("test"), &test);
+		Message msg(8, 1, Message::TC, 1);
+		msg.appendString(String<FUNC_NAME_LENGTH>("test"));
+		msg.appendString(String<65>
+		    ("eqrhjweghjhwqgthjkrghthjkdsfhgsdfhjsdjsfdhgkjdfsghfjdgkdfsgdfgsgd"));
+		fms.call(msg);
+		CHECK(ServiceTests::get(0).messageType == 4);
+		CHECK(ServiceTests::get(0).serviceType == 1);
+	}
+}
+
+
+TEST_CASE("ST[08] - Insert Tests") {
+
+	SECTION("Insertion to full pointer map") {
+		// make sure the pointer map is full to the brim
+		ServiceTests::reset();
+		std::string name = "test";  // FOR TESTING ONLY!
+
+		for (int i = 0; i < FUNC_MAP_SIZE + 1; i++) {
+			name += std::to_string(i); // different names to fill up the map
+			fms.include(String<FUNC_NAME_LENGTH>(name.c_str()), &test);
+		}
+		CHECK(ServiceTests::thrownError(ErrorHandler::InternalErrorType::FunctionMapFull));
+	}
+}
diff --git a/test/Services/LargePacketTransferService.cpp b/test/Services/LargePacketTransferService.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e7109ee763d620047241ac94cc0ab19a6aa73662
--- /dev/null
+++ b/test/Services/LargePacketTransferService.cpp
@@ -0,0 +1,71 @@
+#include <catch2/catch.hpp>
+#include <Services/LargePacketTransferService.hpp>
+#include <Message.hpp>
+#include "ServiceTests.hpp"
+#include <cstring>
+#include <etl/String.hpp>
+
+LargePacketTransferService &lPT = Services.largePacketTransferService;
+
+TEST_CASE("First Downlink Part Report TM[13,1]", "[service][st13]") {
+	String<ECSS_MAX_FIXED_OCTET_STRING_SIZE> string = String<ECSS_MAX_FIXED_OCTET_STRING_SIZE>
+		("12345678");
+	lPT.firstDownlinkPartReport(1, 1, string);
+	REQUIRE(ServiceTests::hasOneMessage());
+	Message report = ServiceTests::get(0);
+	CHECK(report.messageType == 1);
+	CHECK(report.serviceType == 13);
+	CHECK(report.readUint16() == 1);
+	CHECK(report.readUint16() == 1);
+	uint8_t string2[ECSS_MAX_FIXED_OCTET_STRING_SIZE];
+	printf("%d", report.readOctetString(string2));
+	auto a = String<ECSS_MAX_FIXED_OCTET_STRING_SIZE>(string2, 8);
+	CHECK(string.compare(a) == 0);
+}
+
+TEST_CASE("Intermediate Downlink Part Report TM[13,2]", "[service][st13]") {
+	String<ECSS_MAX_FIXED_OCTET_STRING_SIZE> string = String<ECSS_MAX_FIXED_OCTET_STRING_SIZE>(
+		"12345678");
+	lPT.intermediateDownlinkPartReport(1, 1, string);
+	REQUIRE(ServiceTests::hasOneMessage());
+	Message report = ServiceTests::get(0);
+	CHECK(report.messageType == 2);
+	CHECK(report.serviceType == 13);
+	CHECK(report.readUint16() == 1);
+	CHECK(report.readUint16() == 1);
+	uint8_t string2[ECSS_MAX_FIXED_OCTET_STRING_SIZE];
+	report.readOctetString(string2);
+	auto a = String<ECSS_MAX_FIXED_OCTET_STRING_SIZE>(string2, 8);
+	CHECK(string.compare(a) == 0);
+}
+
+TEST_CASE("Last Downlink Part Report TM[13,3]", "[service][st13]") {
+	String<ECSS_MAX_FIXED_OCTET_STRING_SIZE> string = String<ECSS_MAX_FIXED_OCTET_STRING_SIZE>(
+		"12345678");
+	lPT.lastDownlinkPartReport(1, 1, string);
+	REQUIRE(ServiceTests::hasOneMessage());
+	Message report = ServiceTests::get(0);
+	CHECK(report.messageType == 3);
+	CHECK(report.serviceType == 13);
+	CHECK(report.readUint16() == 1);
+	CHECK(report.readUint16() == 1);
+	uint8_t string2[ECSS_MAX_FIXED_OCTET_STRING_SIZE];
+	report.readOctetString(string2);
+	auto a = String<ECSS_MAX_FIXED_OCTET_STRING_SIZE>(string2, 8);
+	CHECK(string.compare(a) == 0);
+}
+
+TEST_CASE("First Uplink Part TC[13,9]", "[service][st13]") {
+	String<256> string = "12345678";
+	CHECK(string.compare(lPT.firstUplinkPart(string)) == 0);
+}
+
+TEST_CASE("Intermediate Uplink Part TC[13,10]", "[service][st13]") {
+	String<256> string = "12345678";
+	CHECK(string.compare(lPT.intermediateUplinkPart(string)) == 0);
+}
+
+TEST_CASE("Last Uplink Part TC[13,11]", "[service][st13]") {
+	String<256> string = "12345678";
+	CHECK(string.compare(lPT.lastUplinkPart(string)) == 0);
+}
diff --git a/test/Services/TimeBasedSchedulingService.cpp b/test/Services/TimeBasedSchedulingService.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bfa878325c513b2a28dd5f1c840cd5d414a7c7ba
--- /dev/null
+++ b/test/Services/TimeBasedSchedulingService.cpp
@@ -0,0 +1,439 @@
+#include <catch2/catch.hpp>
+#include "ServiceTests.hpp"
+#include <Services/TimeBasedSchedulingService.hpp>
+
+#include <ctime>
+#include <vector>
+
+/*
+ * A namespace defined explicitly for the purposes of testing. This namespace contains a
+ * structure, which has been declared as a friend in the TimeBasedSchedulingService class, so
+ * that it can access the private members required for testing validation.
+ */
+namespace unit_test {
+	struct Tester {
+		static bool executionFunctionStatus(TimeBasedSchedulingService &tmService) {
+			return tmService.executionFunctionStatus;
+		}
+
+		/*
+		 * Read the private member scheduled activities and since it is a list and it can't be
+		 * accessed, get each element and save it to a vector.
+		 */
+		static auto scheduledActivities(TimeBasedSchedulingService &tmService) {
+			std::vector<TimeBasedSchedulingService::ScheduledActivity*>listElements;
+
+			for (auto &element : tmService.scheduledActivities) {
+				listElements.push_back(&element);
+			}
+			return listElements; // Return the list elements
+		}
+	};
+}
+
+Message testMessage1, testMessage2, testMessage3, testMessage4;
+MessageParser msgParser;
+auto currentTime = static_cast<uint32_t >(time(nullptr)); // Get the current system time
+bool messagesPopulated = false; // Indicate whether the test messages are initialized
+
+// Run this function to set the service up before moving on with further testing
+auto activityInsertion(TimeBasedSchedulingService &timeService) {
+	if (not messagesPopulated) {
+		// Initialize the test messages
+		testMessage1.serviceType = 6;
+		testMessage1.messageType = 5;
+		testMessage1.packetType = Message::TC;
+		testMessage1.applicationId = 8; // todo: Remove the dummy application ID
+		testMessage1.appendUint16(4253); // Append dummy data
+
+		testMessage2.serviceType = 4;
+		testMessage2.messageType = 5;
+		testMessage2.packetType = Message::TC;
+		testMessage2.applicationId = 4; // todo: Remove the dummy application ID
+		testMessage2.appendUint16(45667); // Append dummy data
+
+		testMessage3.serviceType = 3;
+		testMessage3.messageType = 2;
+		testMessage3.packetType = Message::TC;
+		testMessage3.appendUint16(456); // Append dummy data
+
+		testMessage4.serviceType = 12;
+		testMessage4.messageType = 23;
+		testMessage4.packetType = Message::TC;
+		testMessage4.appendUint16(934); // Append dummy data
+
+		messagesPopulated = true; // Indicate initialized test messages
+	}
+
+	Message receivedMessage(11, 4, Message::TC, 1);
+	receivedMessage.appendUint16(4); // Total number of requests
+
+	// Test activity 1
+	receivedMessage.appendUint32(currentTime + 1556435);
+	receivedMessage.appendString(msgParser.convertTCToStr(testMessage1));
+
+	// Test activity 2
+	receivedMessage.appendUint32(currentTime + 1957232);
+	receivedMessage.appendString(msgParser.convertTCToStr(testMessage2));
+
+	// Test activity 3
+	receivedMessage.appendUint32(currentTime + 1726435);
+	receivedMessage.appendString(msgParser.convertTCToStr(testMessage3));
+
+	// Test activity 4
+	receivedMessage.appendUint32(currentTime + 17248435);
+	receivedMessage.appendString(msgParser.convertTCToStr(testMessage4));
+
+	// Insert activities in the schedule. They have to be inserted sorted
+	timeService.insertActivities(receivedMessage);
+
+	return unit_test::Tester::scheduledActivities(timeService); // Return the activities vector
+}
+
+
+TEST_CASE("TC[11,1] Enable Schedule Execution", "[service][st11]") {
+	TimeBasedSchedulingService timeService;
+	Message receivedMessage(11, 1, Message::TC, 1);
+
+	timeService.enableScheduleExecution(receivedMessage);
+	CHECK(unit_test::Tester::executionFunctionStatus(timeService));
+}
+
+TEST_CASE("TC[11,2] Disable Schedule Execution", "[service][st11]") {
+	Message receivedMessage(11, 2, Message::TC, 1);
+	TimeBasedSchedulingService timeService;
+
+	timeService.disableScheduleExecution(receivedMessage);
+	CHECK(not unit_test::Tester::executionFunctionStatus(timeService));
+}
+
+TEST_CASE("TC[11,4] Activity Insertion", "[service][st11]") {
+	TimeBasedSchedulingService timeService;
+	auto scheduledActivities = activityInsertion(timeService);
+
+	REQUIRE(scheduledActivities.size() == 4);
+	REQUIRE(scheduledActivities.at(0)->requestReleaseTime == currentTime + 1556435);
+	REQUIRE(scheduledActivities.at(1)->requestReleaseTime == currentTime + 1726435);
+	REQUIRE(scheduledActivities.at(2)->requestReleaseTime == currentTime + 1957232);
+	REQUIRE(scheduledActivities.at(3)->requestReleaseTime == currentTime + 17248435);
+	REQUIRE(scheduledActivities.at(0)->request == testMessage1);
+	REQUIRE(scheduledActivities.at(1)->request == testMessage3);
+	REQUIRE(scheduledActivities.at(2)->request == testMessage2);
+	REQUIRE(scheduledActivities.at(3)->request == testMessage4);
+
+	SECTION("Error throw test") {
+		Message receivedMessage(11, 4, Message::TC, 1);
+		receivedMessage.appendUint16(1); // Total number of requests
+
+		receivedMessage.appendUint32(currentTime - 15564350);
+		timeService.insertActivities(receivedMessage);
+
+		REQUIRE(ServiceTests::thrownError(ErrorHandler::InstructionExecutionStartError));
+	}
+}
+
+TEST_CASE("TC[11,15] Time shift all scheduled activities", "[service][st11]") {
+	TimeBasedSchedulingService timeService;
+	Message receivedMessage(11, 15, Message::TC, 1);
+
+	auto scheduledActivities = activityInsertion(timeService);
+	const int32_t timeShift = 6789;
+
+	SECTION("Positive Shift") {
+		receivedMessage.appendSint32(-timeShift);
+
+		CHECK(scheduledActivities.size() == 4);
+		timeService.timeShiftAllActivities(receivedMessage);
+
+		REQUIRE(scheduledActivities.at(0)->requestReleaseTime == currentTime + 1556435 - timeShift);
+		REQUIRE(scheduledActivities.at(1)->requestReleaseTime == currentTime + 1726435 - timeShift);
+		REQUIRE(scheduledActivities.at(2)->requestReleaseTime == currentTime + 1957232 - timeShift);
+		REQUIRE(
+			scheduledActivities.at(3)->requestReleaseTime == currentTime + 17248435 - timeShift);
+	}
+
+	SECTION("Negative Shift") {
+		receivedMessage.appendSint32(timeShift);
+
+		CHECK(scheduledActivities.size() == 4);
+		timeService.timeShiftAllActivities(receivedMessage);
+
+		REQUIRE(scheduledActivities.at(0)->requestReleaseTime == currentTime + 1556435 + timeShift);
+		REQUIRE(scheduledActivities.at(1)->requestReleaseTime == currentTime + 1726435 + timeShift);
+		REQUIRE(scheduledActivities.at(2)->requestReleaseTime == currentTime + 1957232 + timeShift);
+		REQUIRE(
+			scheduledActivities.at(3)->requestReleaseTime == currentTime + 17248435 + timeShift);
+	}
+
+	SECTION("Error throwing") {
+		receivedMessage.appendSint32(-6789000); // Provide a huge time shift to cause an error
+
+		CHECK(scheduledActivities.size() == 4);
+		timeService.timeShiftAllActivities(receivedMessage);
+
+		REQUIRE(ServiceTests::thrownError(ErrorHandler::SubServiceExecutionStartError));
+	}
+}
+
+TEST_CASE("TC[11,7] Time shift activities by ID", "[service][st11]") {
+	TimeBasedSchedulingService timeService;
+	Message receivedMessage(11, 7, Message::TC, 1);
+
+	auto scheduledActivities = activityInsertion(timeService);
+	scheduledActivities.at(2)->requestID.applicationID = 4; // Append a dummy application ID
+	CHECK(scheduledActivities.size() == 4);
+
+	const int32_t timeShift = 67890000; // Relative time-shift value
+
+	SECTION("Positive Shift") {
+		receivedMessage.appendSint32(timeShift); // Time-shift value
+		receivedMessage.appendUint16(1); // Just one instruction to time-shift an activity
+		receivedMessage.appendUint8(0); // Source ID is not implemented
+		receivedMessage.appendUint16(testMessage2.applicationId); // todo: Remove the dummy app ID
+		receivedMessage.appendUint16(0); // todo: Remove the dummy sequence count
+
+		timeService.timeShiftActivitiesByID(receivedMessage);
+		scheduledActivities = unit_test::Tester::scheduledActivities(timeService);
+
+		// Make sure the new value is inserted sorted
+		REQUIRE(scheduledActivities.at(3)->requestReleaseTime == currentTime + 1957232 + timeShift);
+		REQUIRE(scheduledActivities.at(3)->request == testMessage2);
+	}
+
+	SECTION("Negative Shift") {
+		receivedMessage.appendSint32(-250000); // Time-shift value
+		receivedMessage.appendUint16(1); // Just one instruction to time-shift an activity
+		receivedMessage.appendUint8(0); // Source ID is not implemented
+		receivedMessage.appendUint16(testMessage2.applicationId); // todo: Remove the dummy app ID
+		receivedMessage.appendUint16(0); // todo: Remove the dummy sequence count
+
+		timeService.timeShiftActivitiesByID(receivedMessage);
+		scheduledActivities = unit_test::Tester::scheduledActivities(timeService);
+
+		// Output should be sorted
+		REQUIRE(scheduledActivities.at(1)->requestReleaseTime == currentTime + 1957232 - 250000);
+		REQUIRE(scheduledActivities.at(1)->request == testMessage2);
+	}
+
+	SECTION("Error throw on wrong request ID") {
+		receivedMessage.appendSint32(-250000); // Time-shift value
+		receivedMessage.appendUint16(1); // Just one instruction to time-shift an activity
+		receivedMessage.appendUint8(0); // Dummy source ID
+		receivedMessage.appendUint16(80); // Dummy application ID to throw an error
+		receivedMessage.appendUint16(0); // Dummy sequence count
+
+		timeService.timeShiftActivitiesByID(receivedMessage);
+		REQUIRE(ServiceTests::thrownError(ErrorHandler::InstructionExecutionStartError));
+	}
+
+	SECTION("Error throw on wrong time offset") {
+		receivedMessage.appendSint32(-6789000); // Time-shift value
+		receivedMessage.appendUint16(1); // Just one instruction to time-shift an activity
+		receivedMessage.appendUint8(0); // Source ID is not implemented
+		receivedMessage.appendUint16(testMessage2.applicationId); // todo: Remove the dummy app ID
+		receivedMessage.appendUint16(0); // todo: Remove the dummy sequence count
+
+		timeService.timeShiftActivitiesByID(receivedMessage);
+		REQUIRE(ServiceTests::thrownError(ErrorHandler::InstructionExecutionStartError));
+	}
+}
+
+TEST_CASE("TC[11,9] Detail report scheduled activities by ID", "[service][st11]") {
+	TimeBasedSchedulingService timeService;
+	Message receivedMessage(11, 9, Message::TC, 1);
+
+	auto scheduledActivities = activityInsertion(timeService);
+
+	SECTION("Detailed activity report") {
+		// Verify that everything is in place
+		CHECK(scheduledActivities.size() == 4);
+		scheduledActivities.at(0)->requestID.applicationID = 8; // Append a dummy application ID
+		scheduledActivities.at(2)->requestID.applicationID = 4; // Append a dummy application ID
+
+		receivedMessage.appendUint16(2); // Two instructions in the request
+		receivedMessage.appendUint8(0); // Source ID is not implemented
+		receivedMessage.appendUint16(testMessage2.applicationId); // todo: Remove the dummy app ID
+		receivedMessage.appendUint16(0); // todo: Remove the dummy sequence count
+
+		receivedMessage.appendUint8(0); // Source ID is not implemented
+		receivedMessage.appendUint16(testMessage1.applicationId); // todo: Remove the dummy app ID
+		receivedMessage.appendUint16(0); // todo: Remove the dummy sequence count
+
+		timeService.detailReportActivitiesByID(receivedMessage);
+		REQUIRE(ServiceTests::hasOneMessage());
+
+		Message response = ServiceTests::get(0);
+		CHECK(response.serviceType == 11);
+		CHECK(response.messageType == 10);
+
+		uint16_t iterationCount = response.readUint16();
+		CHECK(iterationCount == 2);
+		for (uint16_t i = 0; i < iterationCount; i++) {
+			uint32_t receivedReleaseTime = response.readUint32();
+
+			Message receivedTCPacket;
+			uint8_t receivedDataStr[ECSS_TC_REQUEST_STRING_SIZE];
+			response.readString(receivedDataStr, ECSS_TC_REQUEST_STRING_SIZE);
+			receivedTCPacket = msgParser.parseRequestTC(receivedDataStr);
+
+			if (i == 0) {
+				REQUIRE(receivedReleaseTime == scheduledActivities.at(0)->requestReleaseTime);
+				REQUIRE(receivedTCPacket == scheduledActivities.at(0)->request);
+			} else {
+				REQUIRE(receivedReleaseTime == scheduledActivities.at(2)->requestReleaseTime);
+				REQUIRE(receivedTCPacket == scheduledActivities.at(2)->request);
+			}
+		}
+	}
+
+	SECTION("Error throw on wrong request ID") {
+		receivedMessage.appendUint16(1); // Just one instruction to time-shift an activity
+		receivedMessage.appendUint8(0); // Dummy source ID
+		receivedMessage.appendUint16(80); // Dummy application ID to throw an error
+		receivedMessage.appendUint16(0); // Dummy sequence count
+
+		timeService.detailReportActivitiesByID(receivedMessage);
+		REQUIRE(ServiceTests::thrownError(ErrorHandler::InstructionExecutionStartError));
+	}
+}
+
+TEST_CASE("TC[11,12] Summary report scheduled activities by ID", "[service][st11]") {
+	TimeBasedSchedulingService timeService;
+	Message receivedMessage(11, 12, Message::TC, 1);
+
+	auto scheduledActivities = activityInsertion(timeService);
+
+	SECTION("Summary report") {
+		// Verify that everything is in place
+		CHECK(scheduledActivities.size() == 4);
+		scheduledActivities.at(0)->requestID.applicationID = 8; // Append a dummy application ID
+		scheduledActivities.at(2)->requestID.applicationID = 4; // Append a dummy application ID
+
+		receivedMessage.appendUint16(2); // Two instructions in the request
+		receivedMessage.appendUint8(0); // Source ID is not implemented
+		receivedMessage.appendUint16(testMessage2.applicationId); // todo: Remove the dummy app ID
+		receivedMessage.appendUint16(0); // todo: Remove the dummy sequence count
+
+		receivedMessage.appendUint8(0); // Source ID is not implemented
+		receivedMessage.appendUint16(testMessage1.applicationId); // todo: Remove the dummy app ID
+		receivedMessage.appendUint16(0); // todo: Remove the dummy sequence count
+
+		timeService.summaryReportActivitiesByID(receivedMessage);
+		REQUIRE(ServiceTests::hasOneMessage());
+
+		Message response = ServiceTests::get(0);
+		CHECK(response.serviceType == 11);
+		CHECK(response.messageType == 13);
+
+		uint16_t iterationCount = response.readUint16();
+		for (uint16_t i = 0; i < iterationCount; i++) {
+			uint32_t receivedReleaseTime = response.readUint32();
+			uint8_t receivedSourceID = response.readUint8();
+			uint16_t receivedApplicationID = response.readUint16();
+			uint16_t receivedSequenceCount = response.readUint16();
+
+			if (i == 0) {
+				REQUIRE(receivedReleaseTime == scheduledActivities.at(0)->requestReleaseTime);
+				REQUIRE(receivedSourceID == scheduledActivities.at(0)->requestID.sourceID);
+				REQUIRE(
+					receivedApplicationID == scheduledActivities.at(0)->requestID.applicationID);
+				REQUIRE(
+					receivedSequenceCount == scheduledActivities.at(0)->requestID.sequenceCount);
+			} else {
+				REQUIRE(receivedReleaseTime == scheduledActivities.at(2)->requestReleaseTime);
+				REQUIRE(receivedSourceID == scheduledActivities.at(2)->requestID.sourceID);
+				REQUIRE(
+					receivedApplicationID == scheduledActivities.at(2)->requestID.applicationID);
+				REQUIRE(
+					receivedSequenceCount == scheduledActivities.at(2)->requestID.sequenceCount);
+			}
+		}
+	}
+
+	SECTION("Error throw on wrong request ID") {
+		receivedMessage.appendUint16(1); // Just one instruction to time-shift an activity
+		receivedMessage.appendUint8(0); // Dummy source ID
+		receivedMessage.appendUint16(80); // Dummy application ID to throw an error
+		receivedMessage.appendUint16(0); // Dummy sequence count
+
+		timeService.summaryReportActivitiesByID(receivedMessage);
+		REQUIRE(ServiceTests::thrownError(ErrorHandler::InstructionExecutionStartError));
+	}
+}
+
+TEST_CASE("TC[11,16] Detail report all scheduled activities", "[service][st11]") {
+	TimeBasedSchedulingService timeService;
+	auto scheduledActivities = activityInsertion(timeService);
+
+	Message receivedMessage(11, 16, Message::TC, 1);
+	timeService.detailReportAllActivities(receivedMessage);
+	REQUIRE(ServiceTests::hasOneMessage());
+
+	Message response = ServiceTests::get(0);
+	CHECK(response.serviceType == 11);
+	CHECK(response.messageType == 10);
+
+	uint16_t iterationCount = response.readUint16();
+	REQUIRE(iterationCount == scheduledActivities.size());
+
+	for (uint16_t i = 0; i < iterationCount; i++) {
+		uint32_t receivedReleaseTime = response.readUint32();
+
+		Message receivedTCPacket;
+		uint8_t receivedDataStr[ECSS_TC_REQUEST_STRING_SIZE];
+		response.readString(receivedDataStr, ECSS_TC_REQUEST_STRING_SIZE);
+		receivedTCPacket = msgParser.parseRequestTC(receivedDataStr);
+
+		REQUIRE(receivedReleaseTime == scheduledActivities.at(i)->requestReleaseTime);
+		REQUIRE(scheduledActivities.at(i)->request == receivedTCPacket);
+	}
+}
+
+TEST_CASE("TC[11,5] Activity deletion by ID", "[service][st11]") {
+	TimeBasedSchedulingService timeService;
+	Message receivedMessage(11, 5, Message::TC, 1);
+
+	auto scheduledActivities = activityInsertion(timeService);
+
+	SECTION("Activity deletion") {
+		// Verify that everything is in place
+		CHECK(scheduledActivities.size() == 4);
+		scheduledActivities.at(2)->requestID.applicationID = 4; // Append a dummy application ID
+
+		receivedMessage.appendUint16(1); // Just one instruction to delete an activity
+		receivedMessage.appendUint8(0); // Source ID is not implemented
+		receivedMessage.appendUint16(testMessage2.applicationId); // todo: Remove the dummy app ID
+		receivedMessage.appendUint16(0); // todo: Remove the dummy sequence count
+
+		CHECK(scheduledActivities.size() == 4);
+		timeService.deleteActivitiesByID(receivedMessage);
+		scheduledActivities = unit_test::Tester::scheduledActivities(timeService);
+
+		REQUIRE(scheduledActivities.size() == 3);
+		REQUIRE(scheduledActivities.at(2)->requestReleaseTime == currentTime + 17248435);
+		REQUIRE(scheduledActivities.at(2)->request == testMessage4);
+	}
+
+	SECTION("Error throw on wrong request ID") {
+		receivedMessage.appendUint16(1); // Just one instruction to time-shift an activity
+		receivedMessage.appendUint8(0); // Dummy source ID
+		receivedMessage.appendUint16(80); // Dummy application ID to throw an error
+		receivedMessage.appendUint16(0); // Dummy sequence count
+
+		timeService.deleteActivitiesByID(receivedMessage);
+		REQUIRE(ServiceTests::thrownError(ErrorHandler::InstructionExecutionStartError));
+	}
+}
+
+TEST_CASE("TC[11,3] Reset schedule", "[service][st11]") {
+	TimeBasedSchedulingService timeService;
+	auto scheduledActivities = activityInsertion(timeService);
+
+	Message receivedMessage(11, 3, Message::TC, 1);
+
+	timeService.resetSchedule(receivedMessage);
+	scheduledActivities = unit_test::Tester::scheduledActivities(timeService); // Get the new list
+
+	REQUIRE(scheduledActivities.empty());
+	REQUIRE(not unit_test::Tester::executionFunctionStatus(timeService));
+}