diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index e9c63b78060a66d19fee0b59c83f59e4fa916454..2afbb623502a0f027af9f76d921738bd98747e05 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -11,15 +11,15 @@
       <option name="SPACE_BEFORE_REFERENCE_IN_DECLARATION" value="false" />
       <option name="SPACE_AFTER_REFERENCE_IN_DECLARATION" value="true" />
     </Objective-C>
-    <Objective-C-extensions>
+    <clangFormatSettings>
+      <option name="ENABLED" value="true" />
+    </clangFormatSettings>
+    <files>
       <extensions>
         <pair source="cpp" header="hpp" fileNamingConvention="PASCAL_CASE" />
         <pair source="c" header="h" fileNamingConvention="NONE" />
       </extensions>
-    </Objective-C-extensions>
-    <clangFormatSettings>
-      <option name="ENABLED" value="true" />
-    </clangFormatSettings>
+    </files>
     <codeStyleSettings language="ObjectiveC">
       <option name="ALIGN_MULTILINE_CHAINED_METHODS" value="true" />
       <option name="ALIGN_MULTILINE_FOR" value="false" />
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 37310bc340db176e5788eafbd34689ae763630d1..3e5c2dee5446dfbb812365dd96086ae1574fbfd2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -29,6 +29,7 @@ add_library(common OBJECT
         src/MessageParser.cpp
         src/ServicePool.cpp
         src/Helpers/CRCHelper.cpp
+        src/Helpers/PacketStore.cpp
         src/Time/UTCTimestamp.cpp
         src/Services/EventReportService.cpp
         src/Services/MemoryManagementService.cpp
@@ -39,6 +40,7 @@ add_library(common OBJECT
         src/Services/EventActionService.cpp
         src/Services/TimeBasedSchedulingService.cpp
         src/Services/FunctionManagementService.cpp
+        src/Services/StorageAndRetrievalService.cpp
         src/Services/HousekeepingService.cpp
         src/Services/ParameterStatisticsService.cpp
         src/Services/OnBoardMonitoringService.cpp
diff --git a/inc/ECSS_Definitions.hpp b/inc/ECSS_Definitions.hpp
index e5df0e60eca65475428e28b60c79df2e350dfc67..01fc74b1db03fab7a40ea7d22c3a58d5c46a4429 100644
--- a/inc/ECSS_Definitions.hpp
+++ b/inc/ECSS_Definitions.hpp
@@ -1,7 +1,7 @@
 #ifndef ECSS_SERVICES_ECSS_DEFINITIONS_H
 #define ECSS_SERVICES_ECSS_DEFINITIONS_H
 
-#include <stdint.h>
+#include <cstdint>
 /**
  * @defgroup ECSSDefinitions ECSS Defined Constants
  *
@@ -159,16 +159,43 @@ inline const uint8_t ECSSMaxStatisticParameters = 4;
  */
 inline const bool SupportsStandardDeviation = true;
 
+/**
+ * @brief the max number of bytes allowed for a packet store to handle in ST[15].
+ */
+inline const uint16_t ECSSMaxPacketStoreSizeInBytes = 1000;
+
+/**
+ * @brief the max number of TM packets that a packet store in ST[15] can store
+ */
+inline const uint16_t ECSSMaxPacketStoreSize = 20;
+
+/**
+ * @brief the max number of packet stores that a packet selection subservice can handle in ST[15]
+ */
+inline const uint16_t ECSSMaxPacketStores = 4;
+
+/**
+ * @brief each packet store's id is an etl::string. So this defines the max size of a packet store ID in ST[15]
+ */
+inline const uint16_t ECSSPacketStoreIdSize = 15;
 /**
  * @brief Defines the max number of housekeeping structs that the housekeeping service can contain
  */
 inline const uint8_t ECSSMaxHousekeepingStructures = 10;
 
+/**
+ * Limits noting the minimum and maximum valid Virtual Channels used by the Storage and Retrieval subservice
+ */
+inline struct {
+	uint8_t min = 1;
+	uint8_t max = 10;
+} VirtualChannelLimits;
+
 /**
  * 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 32d7f33308943e8649989ddf6f9cf5f1eb033880..bffa26ddb99f9bfc607acf557c2f111329a00a5f 100644
--- a/inc/ErrorHandler.hpp
+++ b/inc/ErrorHandler.hpp
@@ -77,18 +77,22 @@ public:
 		 * A Message that is included within another message is too large
 		 */
 		NestedMessageTooLarge = 11,
+		/**
+		 * Request to copy packets in a time window, whose type is not recognized (ST(15)).
+		 */
+		InvalidTimeWindowType = 12,
 		/**
 		 * A request to access a non existing housekeeping structure in ST[03]
 		 */
-		NonExistentHousekeeping = 12,
+		NonExistentHousekeeping = 13,
 		/**
 		 * Attempt to access an invalid parameter in ST[03]
 		 */
-		NonExistentParameter = 13,
+		NonExistentParameter = 14,
 		/**
 		 * Invalid TimeStamp parameters at creation
 		 */
-		InvalidTimeStampInput = 14
+		InvalidTimeStampInput = 15,
 	};
 
 	/**
@@ -156,99 +160,170 @@ public:
 		 */
 		GetNonExistingParameter = 8,
 		/**
-		 * Attempt to add definition to the struct map but its already full. (ST[19])
+		 * Attempt to access a packet store that does not exist (ST[15])
+		 */
+		NonExistingPacketStore = 9,
+		/**
+		 * Attempt to change the start time tag of a packet store, whose open retrieval status is in progress (ST[15])
+		 */
+		SetPacketStoreWithOpenRetrievalInProgress = 10,
+		/**
+		 * Attempt to resume open retrieval of a packet store, whose by-time-range retrieval is enabled (ST[15])
 		 */
-		EventActionDefinitionsMapIsFull = 9,
+		SetPacketStoreWithByTimeRangeRetrieval = 11,
+		/**
+		 * Attempt to access a packet with by-time range retrieval enabled (ST[15])
+		 */
+		GetPacketStoreWithByTimeRangeRetrieval = 12,
+		/**
+		 * Attempt to start the by-time-range retrieval of packet store, whose open retrieval is in progress (ST[15])
+		 */
+		GetPacketStoreWithOpenRetrievalInProgress = 13,
+		/**
+		 * Attempt to start by-time-range retrieval when its already enabled (ST[15])
+		 */
+		ByTimeRangeRetrievalAlreadyEnabled = 14,
+		/**
+		 * Attempt to create packet store, whose ID already exists (ST[15])
+		 */
+		AlreadyExistingPacketStore = 15,
+		/**
+		 * Attempt to create packet store, when the max number of packet stores is already reached (ST[15])
+		 */
+		MaxNumberOfPacketStoresReached = 16,
+		/**
+		 * Attempt to access a packet store with the storage status enabled (ST[15])
+		 */
+		GetPacketStoreWithStorageStatusEnabled = 17,
+		/**
+		 * Attempt to delete a packet whose by time range retrieval status is enabled (ST[15])
+		 */
+		DeletionOfPacketWithByTimeRangeRetrieval = 18,
+		/**
+		 * Attempt to delete a packet whose open retrieval status is in progress (ST[15])
+		 */
+		DeletionOfPacketWithOpenRetrievalInProgress = 19,
+		/**
+		 * Requested a time window where the start time is larger than the end time (ST[15])
+		 */
+		InvalidTimeWindow = 20,
+		/**
+		 * Attempt to copy a packet store to a destination packet store that is not empty (ST[15])
+		 */
+		DestinationPacketStoreNotEmtpy = 21,
+		/**
+		 * Attempt to set a reporting rate which is smaller than the parameter sampling rate.
+		 * ST[04]
+		 */
+		InvalidReportingRateError = 22,
+		/**
+		 * Attempt to add definition to the struct map but its already full.(ST[19])
+		 */
+		EventActionDefinitionsMapIsFull = 23,
 		/**
 		 * Attempt to report/delete non existing housekeeping structure (ST[03])
 		 */
-		RequestedNonExistingStructure = 10,
+		RequestedNonExistingStructure = 24,
 		/**
 		 * Attempt to create already created structure (ST[03])
 		 */
-		RequestedAlreadyExistingStructure = 11,
+		RequestedAlreadyExistingStructure = 25,
 		/**
 		 * Attempt to delete structure which has the periodic reporting status enabled (ST[03]) as per 6.3.3.5.2(d-2)
 		 */
-		RequestedDeletionOfEnabledHousekeeping = 12,
+		RequestedDeletionOfEnabledHousekeeping = 26,
 		/**
 		 * Attempt to append a new parameter ID to a housekeeping structure, but the ID is already in the structure
 		 * (ST[03])
 		 */
-		AlreadyExistingParameter = 13,
+		AlreadyExistingParameter = 27,
 		/**
 		 * Attempt to append a new parameter id to a housekeeping structure, but the periodic generation status is
 		 * enabled (ST[03])
 		 */
-		RequestedAppendToEnabledHousekeeping = 14,
+		RequestedAppendToEnabledHousekeeping = 28,
 		/**
 		 * Attempt to create a new housekeeping structure in Housekeeping Service, when the maximum number of
 		 * housekeeping structures is already reached (ST[03])
 		 */
-		ExceededMaxNumberOfHousekeepingStructures = 15,
+		ExceededMaxNumberOfHousekeepingStructures = 29,
 		/**
 		 * 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 = 16,
-		/* Attempt to set a reporting rate which is smaller than the parameter sampling rate.
-		 * ST[04]
-		 */
-		InvalidReportingRateError = 17,
+		ExceededMaxNumberOfSimplyCommutatedParameters = 30,
 		/**
-		 * Attempt to set a sampling rate which is greater than the parameter reporting rate.
+		 * Attempt to set a reporting rate which is smaller than the parameter sampling rate.
 		 * ST[04]
 		 */
-		InvalidSamplingRateError = 18,
+		InvalidSamplingRateError = 31,
 		/**
 		 * Attempt to add new statistic definition but the maximum number is already reached (ST[04])
 		 */
-		MaxStatisticDefinitionsReached = 19,
+		MaxStatisticDefinitionsReached = 32,
+		/**
+		 * Attempt to set the virtual channel of a packet store to a invalid value (ST[15])
+		 */
+		InvalidVirtualChannel = 33,
+		/**
+		 * Attempt to delete a packet store, whose storage status is enabled (ST[15])
+		 */
+		DeletionOfPacketStoreWithStorageStatusEnabled = 34,
+		/**
+		 * Attempt to copy packets from a packet store to another, but either no packet timestamp falls inside the
+		 * specified timestamp, or more than one boolean argument were given as true in the 'copyPacketsTo' function
+		 * (ST[15])
+		 */
+		CopyOfPacketsFailed = 35,
+		/**
+		 * Attempt to set a packet store size to a value that the available memory cannot handle (ST[15]).
+		 */
+		UnableToHandlePacketStoreSize = 36,
 		/**
 		 * Attempt to delete all parameter monitoring definitions but the Parameter Monitoring Function Status is
 		 * enabled.
 		 */
-		InvalidRequestToDeleteAllParameterMonitoringDefinitions = 20,
+		InvalidRequestToDeleteAllParameterMonitoringDefinitions = 37,
 		/**
 		 * Attempt to delete one parameter monitoring definition but its Parameter Monitoring Status is
 		 * enabled.
 		 */
-		InvalidRequestToDeleteParameterMonitoringDefinition = 21,
+		InvalidRequestToDeleteParameterMonitoringDefinition = 38,
 		/**
 		 * Attempt to add a parameter that already exists to the Parameter Monitoring List.
 		 */
-		AddAlreadyExistingParameter = 22,
+		AddAlreadyExistingParameter = 39,
 		/**
 		 * Attempt to add a parameter in the Parameter Monitoring List but it's full
 		 */
-		ParameterMonitoringListIsFull = 23,
+		ParameterMonitoringListIsFull = 40,
 		/**
 		 * Attempt to add or modify a limit check parameter monitoring definition, but the high limit is lower than
 		 * the low limit.
 		 */
-		HighLimitIsLowerThanLowLimit = 24,
+		HighLimitIsLowerThanLowLimit = 41,
 		/**
 		 * Attempt to add or modify a delta check parameter monitoring definition, but the high threshold is lower than
 		 * the low threshold.
 		 */
-		HighThresholdIsLowerThanLowThreshold = 25,
+		HighThresholdIsLowerThanLowThreshold = 42,
 		/**
 		 * Attempt to modify a non existent Parameter Monitoring definition.
 		 */
-		ModifyParameterNotInTheParameterMonitoringList = 26,
+		ModifyParameterNotInTheParameterMonitoringList = 43,
 		/**
 		 * 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,
+		DifferentParameterMonitoringDefinitionAndMonitoredParameter = 44,
 		/**
 		 * Attempt to get a parameter monitoring definition that does not exist.
 		 */
-		GetNonExistingParameterMonitoringDefinition = 28,
+		GetNonExistingParameterMonitoringDefinition = 45,
 		/**
 		 * Request to report a non existent parameter monitoring definition.
 		 */
-		ReportParameterNotInTheParameterMonitoringList = 29
+		ReportParameterNotInTheParameterMonitoringList = 46
 	};
 
 	/**
diff --git a/inc/Helpers/PacketStore.hpp b/inc/Helpers/PacketStore.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..37c2fdeca0d29796682f2dab0525659bab050f5d
--- /dev/null
+++ b/inc/Helpers/PacketStore.hpp
@@ -0,0 +1,82 @@
+#ifndef ECSS_SERVICES_PACKETSTORE_HPP
+#define ECSS_SERVICES_PACKETSTORE_HPP
+
+#include "ECSS_Definitions.hpp"
+#include "ErrorHandler.hpp"
+#include "etl/deque.h"
+#include "Message.hpp"
+
+/**
+ * This is the Packet Store class, needed for the Storage-Retrieval Service. The purpose of the packet-store is to
+ * store all the TM packets transmitted by the other Services.
+ */
+class PacketStore {
+public:
+	/**
+	 * The virtual channel used to transmit the packet store to the ground station. There is an upper and a lower
+	 * bound for the virtual channels, defined in 'ECSSDefinitions' file.
+	 */
+	uint8_t virtualChannel;
+	/**
+	 * The time-tag that defines the starting point of the open retrieval process, meaning that we retrieve packets,
+	 * starting from the open-retrieval-start-time-tag until the latest packet.
+	 */
+	uint32_t openRetrievalStartTimeTag = 0;
+	/**
+	 * The start time of a by-time-range retrieval process, i.e. retrieval of packets between two specified time-tags.
+	 */
+	uint32_t retrievalStartTime = 0;
+	/**
+	 * The end time of a by-time-range retrieval process, i.e. retrieval of packets between two specified time-tags.
+	 */
+	uint32_t retrievalEndTime = 0;
+	/**
+	 * The maximum size of the packet store, in bytes.
+	 *
+	 * @todo: add a way of defining each packets store's size in bytes
+	 */
+	uint64_t sizeInBytes;
+
+	/**
+	 * Whether the insertion of packets stores in the packet-store should cyclically overwrite older packets, or be
+	 * suspended when the packet-store is full.
+	 */
+	enum PacketStoreType : uint8_t { Circular = 0, Bounded = 1 };
+
+	/**
+	 * Whether the open retrieval status of the packet-store is in progress or not.
+	 */
+	enum PacketStoreOpenRetrievalStatus : bool { Suspended = false, InProgress = true };
+
+	/**
++	 * Whether the storage of TM packets is enabled for this packet store
+	 */
+	bool storageStatus = false;
+
+	/**
+	 * Whether the by-time-range retrieval of packet stores is enabled for this packet-store.
+	 */
+	bool byTimeRangeRetrievalStatus = false;
+	PacketStoreType packetStoreType;
+	PacketStoreOpenRetrievalStatus openRetrievalStatus;
+
+	PacketStore() = default;
+
+	/**
+	 * A queue containing the TM messages stored by the packet store. Every TM is accompanied by its timestamp.
+	 *
+	 * @note A convention is made that this should be filled out using `push_back` and NOT `push_front`, dictating that
+	 * earlier packets are placed in the front position. So removing the earlier packets is done with `pop_front`.
+	 *
+	 * 				old packets  <---------->  new packets
+	 * 				[][][][][][][][][][][][][][][][][][][]	<--- deque
+	 */
+	etl::deque<std::pair<uint32_t, Message>, ECSSMaxPacketStoreSize> storedTelemetryPackets;
+
+	/**
+	 * Returns the sum of the sizes of the packets stored in this PacketStore, in bytes.
+	 */
+	uint16_t calculateSizeInBytes();
+};
+
+#endif
diff --git a/inc/Platform/x86/ECSS_Configuration.hpp b/inc/Platform/x86/ECSS_Configuration.hpp
index c03814e5ad812c932c576df81c0d21917ca659dd..3b27fecf53cd2ad67e162144c2f9f1c5d6bd3774 100644
--- a/inc/Platform/x86/ECSS_Configuration.hpp
+++ b/inc/Platform/x86/ECSS_Configuration.hpp
@@ -31,9 +31,10 @@
 #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_STORAGEANDRETRIEVAL ///<  Compile ST[15] storage-and-retrieval of tm packets
+#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
 /** @} */
 
diff --git a/inc/ServicePool.hpp b/inc/ServicePool.hpp
index a916cb82cee3e93b7560c4c7d07ec1b9d51239a0..9dbb533a2640a1d96abed2543d33129edf5b5314 100644
--- a/inc/ServicePool.hpp
+++ b/inc/ServicePool.hpp
@@ -11,6 +11,7 @@
 #include "Services/TestService.hpp"
 #include "Services/MemoryManagementService.hpp"
 #include "Services/FunctionManagementService.hpp"
+#include "Services/StorageAndRetrievalService.hpp"
 #include "Services/HousekeepingService.hpp"
 #include "Services/ParameterStatisticsService.hpp"
 #include "Services/OnBoardMonitoringService.hpp"
@@ -77,6 +78,10 @@ public:
 	RequestVerificationService requestVerification;
 #endif
 
+#ifdef SERVICE_STORAGEANDRETRIEVAL
+	StorageAndRetrievalService storageAndRetrieval;
+#endif
+
 #ifdef SERVICE_TEST
 	TestService testService;
 #endif
diff --git a/inc/Services/StorageAndRetrievalService.hpp b/inc/Services/StorageAndRetrievalService.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..95142327f8d73d2e272de7cd5d192dec4252d33d
--- /dev/null
+++ b/inc/Services/StorageAndRetrievalService.hpp
@@ -0,0 +1,353 @@
+#ifndef ECSS_SERVICES_STORAGEANDRETRIEVALSERVICE_HPP
+#define ECSS_SERVICES_STORAGEANDRETRIEVALSERVICE_HPP
+
+#include "ECSS_Definitions.hpp"
+#include "Service.hpp"
+#include "ErrorHandler.hpp"
+#include "Helpers/PacketStore.hpp"
+#include "etl/map.h"
+
+/**
+ * Implementation of ST[15] Storage and Retrieval Service, as defined in ECSS-E-ST-70-41C.
+ *
+ * This Service:
+ * - provides the capability to select reports generated by other services and store them into packet stores.
+ * - allows the ground system to manage the reports in the packet stores and request their downlink.
+ *
+ * @author Konstantinos Petridis <petridkon@gmail.com>
+ */
+class StorageAndRetrievalService : public Service {
+public:
+	/**
+	 * The type of timestamps that the Storage and Retrieval Subservice assigns to each incoming packet.
+	 */
+	enum TimeStampType : uint8_t { StorageBased = 0, PacketBased = 1 };
+
+	/**
+	 * Different types of packet retrieval from a packet store, relative to a specified time-tag.
+	 */
+	enum TimeWindowType : uint8_t { FromTagToTag = 0, AfterTimeTag = 1, BeforeTimeTag = 2 };
+
+	/**
+	 * The type of timestamps that the subservice sets to each incoming telemetry packet.
+	 */
+	const TimeStampType timeStamping = PacketBased;
+
+private:
+	typedef String<ECSSPacketStoreIdSize> packetStoreId;
+
+	/**
+	 * All packet stores, held by the Storage and Retrieval Service. Each packet store has its ID as key.
+	 */
+	etl::map<packetStoreId, PacketStore, ECSSMaxPacketStores> packetStores;
+
+	/**
+	 * Helper function that reads the packet store ID string from a TM[15] message
+	 */
+	static inline String<ECSSPacketStoreIdSize> readPacketStoreId(Message& message);
+
+	/**
+	 * Helper function that, given a time-limit, deletes every packet stored in the specified packet-store, up to the
+	 * requested time.
+	 *
+	 * @param packetStoreId required to access the correct packet store.
+	 * @param timeLimit the limit until which, packets are deleted.
+	 */
+	void deleteContentUntil(const String<ECSSPacketStoreIdSize>& packetStoreId, uint32_t timeLimit);
+
+	/**
+	 * Copies all TM packets from source packet store to the target packet-store, that fall between the two specified
+	 * time-tags as per 6.15.3.8.4.d(1) of the standard.
+	 *
+	 * @param request used to read the time-tags, the packet store IDs and to raise errors.
+	 */
+	void copyFromTagToTag(Message& request);
+
+	/**
+	 * Copies all TM packets from source packet store to the target packet-store, whose time-stamp is after the
+	 * specified time-tag as per 6.15.3.8.4.d(2) of the standard.
+	 *
+	 * @param request used to read the time-tag, the packet store IDs and to raise errors.
+	 */
+	void copyAfterTimeTag(Message& request);
+
+	/**
+	 * Copies all TM packets from source packet store to the target packet-store, whose time-stamp is before the
+	 * specified time-tag as per 6.15.3.8.4.d(3) of the standard.
+	 *
+	 * @param request used to raise errors.
+	 */
+	void copyBeforeTimeTag(Message& request);
+
+	/**
+	 * Checks if the two requested packet stores exist.
+	 *
+	 * @param fromPacketStoreId the source packet store, whose content is to be copied.
+	 * @param toPacketStoreId  the target packet store, which is going to receive the new content.
+	 * @param request used to raise errors.
+	 * @return true if an error has occurred.
+	 */
+	bool checkPacketStores(const String<ECSSPacketStoreIdSize>& fromPacketStoreId,
+	                       const String<ECSSPacketStoreIdSize>& toPacketStoreId, Message& request);
+
+	/**
+	 * Checks whether the time window makes logical sense (end time should be after the start time)
+	 *
+	 * @param request used to raise errors.
+	 */
+	static bool checkTimeWindow(uint32_t startTime, uint32_t endTime, Message& request);
+
+	/**
+	 * Checks if the destination packet store is empty, in order to proceed with the copying of packets.
+	 *
+	 * @param toPacketStoreId  the target packet store, which is going to receive the new content. Needed for error
+	 * checking.
+	 * @param request used to raise errors.
+	 */
+	bool checkDestinationPacketStore(const String<ECSSPacketStoreIdSize>& toPacketStoreId, Message& request);
+
+	/**
+	 * Checks if there are no stored timestamps that fall between the two specified time-tags.
+	 *
+	 * @param fromPacketStoreId  the source packet store, whose content is to be copied. Needed for error checking.
+	 * @param request used to raise errors.
+	 *
+	 * @note
+	 * This function assumes that `startTime` and `endTime` are valid at this point, so any necessary error checking
+	 * regarding these variables, should have already occurred.
+	 */
+	bool noTimestampInTimeWindow(const String<ECSSPacketStoreIdSize>& fromPacketStoreId, uint32_t startTime,
+	                             uint32_t endTime, Message& request);
+
+	/**
+	 * Checks if there are no stored timestamps that fall between the two specified time-tags.
+	 *
+	 * @param isAfterTimeTag true indicates that we are examining the case of AfterTimeTag. Otherwise, we are referring
+	 * to the case of BeforeTimeTag.
+	 * @param request used to raise errors.
+	 * @param fromPacketStoreId the source packet store, whose content is to be copied.
+	 */
+	bool noTimestampInTimeWindow(const String<ECSSPacketStoreIdSize>& fromPacketStoreId, uint32_t timeTag,
+	                             Message& request, bool isAfterTimeTag);
+
+	/**
+	 * Performs all the necessary error checking for the case of FromTagToTag copying of packets.
+	 *
+	 * @param fromPacketStoreId the source packet store, whose content is to be copied.
+	 * @param toPacketStoreId  the target packet store, which is going to receive the new content.
+	 * @param request used to raise errors.
+	 * @return true if an error has occurred.
+	 */
+	bool failedFromTagToTag(const String<ECSSPacketStoreIdSize>& fromPacketStoreId,
+	                        const String<ECSSPacketStoreIdSize>& toPacketStoreId, uint32_t startTime,
+	                        uint32_t endTime, Message& request);
+
+	/**
+	 * Performs all the necessary error checking for the case of AfterTimeTag copying of packets.
+	 *
+	 * @param fromPacketStoreId the source packet store, whose content is to be copied.
+	 * @param toPacketStoreId  the target packet store, which is going to receive the new content.
+	 * @param request used to raise errors.
+	 * @return true if an error has occurred.
+	 */
+	bool failedAfterTimeTag(const String<ECSSPacketStoreIdSize>& fromPacketStoreId,
+	                        const String<ECSSPacketStoreIdSize>& toPacketStoreId, uint32_t startTime,
+	                        Message& request);
+
+	/**
+	 * Performs all the necessary error checking for the case of BeforeTimeTag copying of packets.
+	 *
+	 * @param fromPacketStoreId the source packet store, whose content is to be copied.
+	 * @param toPacketStoreId  the target packet store, which is going to receive the new content.
+	 * @param request used to raise errors.
+	 * @return true if an error has occurred.
+	 */
+	bool failedBeforeTimeTag(const String<ECSSPacketStoreIdSize>& fromPacketStoreId,
+	                         const String<ECSSPacketStoreIdSize>& toPacketStoreId, uint32_t endTime,
+	                         Message& request);
+
+	/**
+	 * Performs the necessary error checking for a request to start the by-time-range retrieval process.
+	 *
+	 * @param request used to raise errors.
+	 * @return true if an error has occurred.
+	 */
+	bool failedStartOfByTimeRangeRetrieval(const String<ECSSPacketStoreIdSize>& packetStoreId, Message& request);
+
+	/**
+	 * Forms the content summary of the specified packet-store and appends it to a report message.
+	 */
+	void createContentSummary(Message& report, const String<ECSSPacketStoreIdSize>& packetStoreId);
+
+public:
+	inline static const uint8_t ServiceType = 15;
+
+	enum MessageType : uint8_t {
+		EnableStorageInPacketStores = 1,
+		DisableStorageInPacketStores = 2,
+		StartByTimeRangeRetrieval = 9,
+		DeletePacketStoreContent = 11,
+		ReportContentSummaryOfPacketStores = 12,
+		PacketStoreContentSummaryReport = 13,
+		ChangeOpenRetrievalStartingTime = 14,
+		ResumeOpenRetrievalOfPacketStores = 15,
+		SuspendOpenRetrievalOfPacketStores = 16,
+		AbortByTimeRangeRetrieval = 17,
+		ReportStatusOfPacketStores = 18,
+		PacketStoresStatusReport = 19,
+		CreatePacketStores = 20,
+		DeletePacketStores = 21,
+		ReportConfigurationOfPacketStores = 22,
+		PacketStoreConfigurationReport = 23,
+		CopyPacketsInTimeWindow = 24,
+		ResizePacketStores = 25,
+		ChangeTypeToCircular = 26,
+		ChangeTypeToBounded = 27,
+		ChangeVirtualChannel = 28
+	};
+
+	StorageAndRetrievalService() = default;
+
+	/**
+	 * Adds new packet store into packet stores.
+	 */
+	void addPacketStore(const String<ECSSPacketStoreIdSize>& packetStoreId, const PacketStore& packetStore);
+
+	/**
+	 * Adds telemetry to the specified packet store and timestamps it.
+	 */
+	void addTelemetryToPacketStore(const String<ECSSPacketStoreIdSize>& packetStoreId, uint32_t timestamp);
+
+	/**
+	 * Deletes the content from all the packet stores.
+	 */
+	void resetPacketStores();
+
+	/**
+	 * Returns the number of existing packet stores.
+	 */
+	uint16_t currentNumberOfPacketStores();
+
+	/**
+	 * Returns the packet store with the specified packet store ID.
+	 */
+	PacketStore& getPacketStore(const String<ECSSPacketStoreIdSize>& packetStoreId);
+
+	/**
+	 * Returns true if the specified packet store is present in packet stores.
+	 */
+	bool packetStoreExists(const String<ECSSPacketStoreIdSize>& packetStoreId);
+
+	/**
+	 * Given a request that contains a number N, followed by N packet store IDs, this method calls function on every
+	 * packet store. Implemented to reduce duplication. If N = 0, then function is applied to all packet stores.
+	 * Incorrect packet store IDs are ignored and generate an error.
+
+	 * @param function the job to be done after the error checking.
+	 */
+	void executeOnPacketStores(Message& request, const std::function<void(PacketStore&)>& function);
+
+	/**
+	 * TC[15,1] request to enable the packet stores' storage function
+	 */
+	void enableStorageFunction(Message& request);
+
+	/**
+	 * TC[15,2] request to disable the packet stores' storage function
+	 */
+	void disableStorageFunction(Message& request);
+
+	/**
+	 * TC[15,9] start the by-time-range retrieval of packet stores
+	 */
+	void startByTimeRangeRetrieval(Message& request);
+
+	/**
+	 * TC[15,11] delete the packet store content up to the specified time
+	 */
+	void deletePacketStoreContent(Message& request);
+
+	/**
+	 * This function takes a TC[15,12] 'report the packet store content summary' as argument and responds with a TM[15,
+	 * 13] 'packet store content summary report' report message.
+	 */
+	void packetStoreContentSummaryReport(Message& request);
+
+	/**
+	 * TC[15,14] change the open retrieval start time tag
+	 */
+	void changeOpenRetrievalStartTimeTag(Message& request);
+
+	/**
+	 * TC[15,15] resume the open retrieval of packet stores
+	 */
+	void resumeOpenRetrievalOfPacketStores(Message& request);
+
+	/**
+	 * TC[15,16] suspend the open retrieval of packet stores
+	 */
+	void suspendOpenRetrievalOfPacketStores(Message& request);
+
+	/**
+	 * TC[15,17] abort the by-time-range retrieval of packet stores
+	 */
+	void abortByTimeRangeRetrieval(Message& request);
+
+	/**
+	 * This function takes a TC[15,18] 'report the status of packet stores' request as argument and responds with a
+	 * TM[15,19] 'packet stores status' report message.
+	 */
+	void packetStoresStatusReport(Message& request);
+
+	/**
+	 * TC[15,20] create packet stores
+	 */
+	void createPacketStores(Message& request);
+
+	/**
+	 * TC[15,21] delete packet stores
+	 */
+	void deletePacketStores(Message& request);
+
+	/**
+	 * This function takes a TC[15,22] 'report the packet store configuration' as argument and responds with a TM[15,
+	 * 23] 'packet store configuration report' report message.
+	 */
+	void packetStoreConfigurationReport(Message& request);
+
+	/**
+	 * TC[15,24] copy the packets contained into a packet store, selected by the time window
+	 */
+	void copyPacketsInTimeWindow(Message& request);
+
+	/**
+	 * TC[15,25] resize packet stores
+	 */
+	void resizePacketStores(Message& request);
+
+	/**
+	 * TC[15,26] change the packet store type to circular
+	 */
+	void changeTypeToCircular(Message& request);
+
+	/**
+	 * TC[15,27] change the packet store type to bounded
+	 */
+	void changeTypeToBounded(Message& request);
+
+	/**
+	 * TC[15,28] change the virtual channel used by a packet store
+	 */
+	void changeVirtualChannel(Message& request);
+
+	/**
+	 * It is responsible to call the suitable function that executes a telecommand packet. The source of that packet
+	 * is the ground station.
+	 *
+	 * @note This function is called from the main execute() that is defined in the file MessageParser.hpp
+	 * @param request Contains the necessary parameters to call the suitable subservice
+	 */
+	void execute(Message& request);
+};
+
+#endif
diff --git a/src/Helpers/PacketStore.cpp b/src/Helpers/PacketStore.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..96a0ad6137664293d1ac5d8bc5008ec3a947a560
--- /dev/null
+++ b/src/Helpers/PacketStore.cpp
@@ -0,0 +1,9 @@
+#include "Helpers/PacketStore.hpp"
+
+uint16_t PacketStore::calculateSizeInBytes() {
+	uint16_t size = 0;
+	for (auto& tmPacket : storedTelemetryPackets) {
+		size += tmPacket.second.dataSize;
+	}
+	return size;
+}
diff --git a/src/MessageParser.cpp b/src/MessageParser.cpp
index b34fc13d3c874609fa593718f9285c2c0e010a0f..d756549295a1750a7a45cc0c3d628a50af055a97 100644
--- a/src/MessageParser.cpp
+++ b/src/MessageParser.cpp
@@ -1,9 +1,10 @@
+#include "MessageParser.hpp"
 #include <ServicePool.hpp>
+#include <iostream>
 #include "ErrorHandler.hpp"
-#include "MessageParser.hpp"
-#include "macros.hpp"
-#include "Services/RequestVerificationService.hpp"
 #include "Helpers/CRCHelper.hpp"
+#include "Services/RequestVerificationService.hpp"
+#include "macros.hpp"
 
 void MessageParser::execute(Message& message) {
 	switch (message.serviceType) {
@@ -44,6 +45,11 @@ void MessageParser::execute(Message& message) {
 			break;
 #endif
 
+#ifdef SERVICE_STORAGEANDRETRIEVAL
+		case StorageAndRetrievalService::ServiceType:
+			Services.storageAndRetrieval.execute(message);
+#endif
+
 #ifdef SERVICE_ONBOARDMONITORING
 		case OnBoardMonitoringService::ServiceType:
 			Services.onBoardMonitoringService.execute(message);
@@ -188,7 +194,7 @@ String<CCSDSMaxMessageSize> MessageParser::compose(const Message& message) {
 
 	// Parts of the header
 	uint16_t packetId = message.applicationId;
-	packetId |= (1U << 11U); // Secondary header flag
+	packetId |= (1U << 11U);                                              // Secondary header flag
 	packetId |= (message.packetType == Message::TC) ? (1U << 12U) : (0U); // Ignore-MISRA
 	uint16_t packetSequenceControl = message.packetSequenceCount | (3U << 14U);
 	uint16_t packetDataLength = ecssMessage.size();
diff --git a/src/Services/StorageAndRetrievalService.cpp b/src/Services/StorageAndRetrievalService.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..23f06f48b380f5359ed367787e32a95a057ab27c
--- /dev/null
+++ b/src/Services/StorageAndRetrievalService.cpp
@@ -0,0 +1,810 @@
+#include "Services/StorageAndRetrievalService.hpp"
+
+String<ECSSPacketStoreIdSize> StorageAndRetrievalService::readPacketStoreId(Message& message) {
+	uint8_t packetStoreId[ECSSPacketStoreIdSize];
+	message.readString(packetStoreId, ECSSPacketStoreIdSize);
+	return packetStoreId;
+}
+
+void StorageAndRetrievalService::deleteContentUntil(const String<ECSSPacketStoreIdSize>& packetStoreId,
+                                                    uint32_t timeLimit) {
+	auto& telemetryPackets = packetStores[packetStoreId].storedTelemetryPackets;
+	while (not telemetryPackets.empty() and telemetryPackets.front().first <= timeLimit) {
+		telemetryPackets.pop_front();
+	}
+}
+
+void StorageAndRetrievalService::copyFromTagToTag(Message& request) {
+	uint32_t startTime = request.readUint32();
+	uint32_t endTime = request.readUint32();
+
+	auto fromPacketStoreId = readPacketStoreId(request);
+	auto toPacketStoreId = readPacketStoreId(request);
+
+	if (failedFromTagToTag(fromPacketStoreId, toPacketStoreId, startTime, endTime, request)) {
+		return;
+	}
+
+	for (auto& packet : packetStores[fromPacketStoreId].storedTelemetryPackets) {
+		if (packet.first < startTime) {
+			continue;
+		}
+		if (packet.first > endTime) {
+			break;
+		}
+		packetStores[toPacketStoreId].storedTelemetryPackets.push_back(packet);
+	}
+}
+
+void StorageAndRetrievalService::copyAfterTimeTag(Message& request) {
+	uint32_t startTime = request.readUint32();
+
+	auto fromPacketStoreId = readPacketStoreId(request);
+	auto toPacketStoreId = readPacketStoreId(request);
+
+	if (failedAfterTimeTag(fromPacketStoreId, toPacketStoreId, startTime, request)) {
+		return;
+	}
+
+	for (auto& packet : packetStores[fromPacketStoreId].storedTelemetryPackets) {
+		if (packet.first < startTime) {
+			continue;
+		}
+		packetStores[toPacketStoreId].storedTelemetryPackets.push_back(packet);
+	}
+}
+
+void StorageAndRetrievalService::copyBeforeTimeTag(Message& request) {
+	uint32_t endTime = request.readUint32();
+
+	auto fromPacketStoreId = readPacketStoreId(request);
+	auto toPacketStoreId = readPacketStoreId(request);
+
+	if (failedBeforeTimeTag(fromPacketStoreId, toPacketStoreId, endTime, request)) {
+		return;
+	}
+
+	for (auto& packet : packetStores[fromPacketStoreId].storedTelemetryPackets) {
+		if (packet.first > endTime) {
+			break;
+		}
+		packetStores[toPacketStoreId].storedTelemetryPackets.push_back(packet);
+	}
+}
+
+bool StorageAndRetrievalService::checkPacketStores(const String<ECSSPacketStoreIdSize>& fromPacketStoreId,
+                                                   const String<ECSSPacketStoreIdSize>& toPacketStoreId,
+                                                   Message& request) {
+	if (packetStores.find(fromPacketStoreId) == packetStores.end() or
+	    packetStores.find(toPacketStoreId) == packetStores.end()) {
+		ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::NonExistingPacketStore);
+		return false;
+	}
+	return true;
+}
+
+bool StorageAndRetrievalService::checkTimeWindow(uint32_t startTime, uint32_t endTime, Message& request) {
+	if (startTime >= endTime) {
+		ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::InvalidTimeWindow);
+		return true;
+	}
+	return false;
+}
+
+bool StorageAndRetrievalService::checkDestinationPacketStore(const String<ECSSPacketStoreIdSize>& toPacketStoreId,
+                                                             Message& request) {
+	if (not packetStores[toPacketStoreId].storedTelemetryPackets.empty()) {
+		ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::DestinationPacketStoreNotEmtpy);
+		return true;
+	}
+	return false;
+}
+
+bool StorageAndRetrievalService::noTimestampInTimeWindow(const String<ECSSPacketStoreIdSize>& fromPacketStoreId,
+                                                         uint32_t startTime, uint32_t endTime, Message& request) {
+	if (endTime < packetStores[fromPacketStoreId].storedTelemetryPackets.front().first ||
+	    startTime > packetStores[fromPacketStoreId].storedTelemetryPackets.back().first) {
+		ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::CopyOfPacketsFailed);
+		return true;
+	}
+	return false;
+}
+
+bool StorageAndRetrievalService::noTimestampInTimeWindow(const String<ECSSPacketStoreIdSize>& fromPacketStoreId,
+                                                         uint32_t timeTag, Message& request, bool isAfterTimeTag) {
+	if (isAfterTimeTag) {
+		if (timeTag > packetStores[fromPacketStoreId].storedTelemetryPackets.back().first) {
+			ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::CopyOfPacketsFailed);
+			return true;
+		}
+		return false;
+	} else if (timeTag < packetStores[fromPacketStoreId].storedTelemetryPackets.front().first) {
+		ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::CopyOfPacketsFailed);
+		return true;
+	}
+	return false;
+}
+
+bool StorageAndRetrievalService::failedFromTagToTag(const String<ECSSPacketStoreIdSize>& fromPacketStoreId,
+                                                    const String<ECSSPacketStoreIdSize>& toPacketStoreId,
+                                                    uint32_t startTime, uint32_t endTime, Message& request) {
+	return (not checkPacketStores(fromPacketStoreId, toPacketStoreId, request) or
+	        checkTimeWindow(startTime, endTime, request) or checkDestinationPacketStore(toPacketStoreId, request) or
+	        noTimestampInTimeWindow(fromPacketStoreId, startTime, endTime, request));
+}
+
+bool StorageAndRetrievalService::failedAfterTimeTag(const String<ECSSPacketStoreIdSize>& fromPacketStoreId,
+                                                    const String<ECSSPacketStoreIdSize>& toPacketStoreId,
+                                                    uint32_t startTime, Message& request) {
+	return (not checkPacketStores(fromPacketStoreId, toPacketStoreId, request) or
+	        checkDestinationPacketStore(toPacketStoreId, request) or
+	        noTimestampInTimeWindow(fromPacketStoreId, startTime, request, true));
+}
+
+bool StorageAndRetrievalService::failedBeforeTimeTag(const String<ECSSPacketStoreIdSize>& fromPacketStoreId,
+                                                     const String<ECSSPacketStoreIdSize>& toPacketStoreId,
+                                                     uint32_t endTime, Message& request) {
+	return (not checkPacketStores(fromPacketStoreId, toPacketStoreId, request) or
+	        checkDestinationPacketStore(toPacketStoreId, request) or
+	        noTimestampInTimeWindow(fromPacketStoreId, endTime, request, false));
+}
+
+void StorageAndRetrievalService::createContentSummary(Message& report,
+                                                      const String<ECSSPacketStoreIdSize>& packetStoreId) {
+	uint32_t oldestStoredPacketTime = packetStores[packetStoreId].storedTelemetryPackets.front().first;
+	report.appendUint32(oldestStoredPacketTime);
+
+	uint32_t newestStoredPacketTime = packetStores[packetStoreId].storedTelemetryPackets.back().first;
+	report.appendUint32(newestStoredPacketTime);
+
+	report.appendUint32(packetStores[packetStoreId].openRetrievalStartTimeTag);
+
+	auto filledPercentage1 = static_cast<uint16_t>(packetStores[packetStoreId].storedTelemetryPackets.size() * 100.0f /
+	                                               ECSSMaxPacketStoreSize);
+	report.appendUint16(filledPercentage1);
+
+	uint16_t numOfPacketsToBeTransferred = 0;
+	numOfPacketsToBeTransferred = std::count_if(
+	    std::begin(packetStores[packetStoreId].storedTelemetryPackets),
+	    std::end(packetStores[packetStoreId].storedTelemetryPackets), [this, &packetStoreId](auto packet) {
+		    return packet.first >= packetStores[packetStoreId].openRetrievalStartTimeTag;
+	    });
+	auto filledPercentage2 = static_cast<uint16_t>(numOfPacketsToBeTransferred * 100.0f / ECSSMaxPacketStoreSize);
+	report.appendUint16(filledPercentage2);
+}
+
+bool StorageAndRetrievalService::failedStartOfByTimeRangeRetrieval(
+    const String<ECSSPacketStoreIdSize>& packetStoreId, Message& request) {
+	bool errorFlag = false;
+
+	if (packetStores.find(packetStoreId) == packetStores.end()) {
+		ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::NonExistingPacketStore);
+		errorFlag = true;
+	} else if (packetStores[packetStoreId].openRetrievalStatus == PacketStore::InProgress) {
+		ErrorHandler::reportError(request,
+		                          ErrorHandler::ExecutionStartErrorType::GetPacketStoreWithOpenRetrievalInProgress);
+		errorFlag = true;
+	} else if (packetStores[packetStoreId].byTimeRangeRetrievalStatus) {
+		ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::ByTimeRangeRetrievalAlreadyEnabled);
+		errorFlag = true;
+	}
+	if (errorFlag) {
+		uint16_t numberOfBytesToSkip = 8;
+		request.skipBytes(numberOfBytesToSkip);
+		return true;
+	}
+	return false;
+}
+
+void StorageAndRetrievalService::addPacketStore(const String<ECSSPacketStoreIdSize>& packetStoreId,
+                                                const PacketStore& packetStore) {
+	packetStores.insert({packetStoreId, packetStore});
+}
+
+void StorageAndRetrievalService::addTelemetryToPacketStore(const String<ECSSPacketStoreIdSize>& packetStoreId,
+                                                           uint32_t timestamp) {
+	Message tmPacket;
+	packetStores[packetStoreId].storedTelemetryPackets.push_back({timestamp, tmPacket});
+}
+
+void StorageAndRetrievalService::resetPacketStores() {
+	packetStores.clear();
+}
+
+uint16_t StorageAndRetrievalService::currentNumberOfPacketStores() {
+	return packetStores.size();
+}
+
+PacketStore& StorageAndRetrievalService::getPacketStore(const String<ECSSPacketStoreIdSize>& packetStoreId) {
+	auto packetStore = packetStores.find(packetStoreId);
+	if (packetStore == packetStores.end()) {
+		assert(ErrorHandler::ExecutionStartErrorType::NonExistingPacketStore);
+	}
+	return packetStore->second;
+}
+
+bool StorageAndRetrievalService::packetStoreExists(const String<ECSSPacketStoreIdSize>& packetStoreId) {
+	return packetStores.find(packetStoreId) != packetStores.end();
+}
+
+void StorageAndRetrievalService::executeOnPacketStores(Message& request,
+                                                       const std::function<void(PacketStore&)>& function) {
+	uint16_t numOfPacketStores = request.readUint16();
+	if (numOfPacketStores == 0) {
+		for (auto& packetStore : packetStores) {
+			function(packetStore.second);
+		}
+		return;
+	}
+
+	for (uint16_t i = 0; i < numOfPacketStores; i++) {
+		auto packetStoreId = readPacketStoreId(request);
+		auto packetStore = packetStores.find(packetStoreId);
+		if (packetStore == packetStores.end()) {
+			ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::NonExistingPacketStore);
+			continue;
+		}
+		function(packetStores[packetStoreId]);
+	}
+}
+
+void StorageAndRetrievalService::enableStorageFunction(Message& request) {
+	request.assertTC(ServiceType, MessageType::EnableStorageInPacketStores);
+
+	executeOnPacketStores(request, [](PacketStore& p) { p.storageStatus = true; });
+}
+
+void StorageAndRetrievalService::disableStorageFunction(Message& request) {
+	request.assertTC(ServiceType, MessageType::DisableStorageInPacketStores);
+
+	executeOnPacketStores(request, [](PacketStore& p) { p.storageStatus = false; });
+}
+
+void StorageAndRetrievalService::startByTimeRangeRetrieval(Message& request) {
+	request.assertTC(ServiceType, MessageType::StartByTimeRangeRetrieval);
+
+	uint16_t numOfPacketStores = request.readUint16();
+	bool errorFlag = false;
+
+	for (uint16_t i = 0; i < numOfPacketStores; i++) {
+		auto packetStoreId = readPacketStoreId(request);
+		if (failedStartOfByTimeRangeRetrieval(packetStoreId, request)) {
+			continue;
+		}
+		uint32_t retrievalStartTime = request.readUint32();
+		uint32_t retrievalEndTime = request.readUint32();
+
+		if (retrievalStartTime >= retrievalEndTime) {
+			ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::InvalidTimeWindow);
+			continue;
+		}
+
+		// todo: 6.15.3.5.2.d(4), actually count the current time
+
+		auto& packetStore = packetStores[packetStoreId];
+		packetStore.byTimeRangeRetrievalStatus = true;
+		packetStore.retrievalStartTime = retrievalStartTime;
+		packetStore.retrievalEndTime = retrievalEndTime;
+		// todo: start the by-time-range retrieval process according to the priority policy
+	}
+}
+
+void StorageAndRetrievalService::deletePacketStoreContent(Message& request) {
+	request.assertTC(ServiceType, MessageType::DeletePacketStoreContent);
+
+	uint32_t timeLimit = request.readUint32(); // todo: decide the time-format
+	uint16_t numOfPacketStores = request.readUint16();
+
+	if (numOfPacketStores == 0) {
+		for (auto& packetStore : packetStores) {
+			if (packetStore.second.byTimeRangeRetrievalStatus) {
+				ErrorHandler::reportError(
+				    request, ErrorHandler::ExecutionStartErrorType::SetPacketStoreWithByTimeRangeRetrieval);
+				continue;
+			}
+			if (packetStore.second.openRetrievalStatus == PacketStore::InProgress) {
+				ErrorHandler::reportError(
+				    request, ErrorHandler::ExecutionStartErrorType::SetPacketStoreWithOpenRetrievalInProgress);
+				continue;
+			}
+			deleteContentUntil(packetStore.first, timeLimit);
+		}
+		return;
+	}
+	for (uint16_t i = 0; i < numOfPacketStores; i++) {
+		auto packetStoreId = readPacketStoreId(request);
+		if (packetStores.find(packetStoreId) == packetStores.end()) {
+			ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::NonExistingPacketStore);
+			continue;
+		}
+		if (packetStores[packetStoreId].byTimeRangeRetrievalStatus) {
+			ErrorHandler::reportError(request,
+			                          ErrorHandler::ExecutionStartErrorType::SetPacketStoreWithByTimeRangeRetrieval);
+			continue;
+		}
+		if (packetStores[packetStoreId].openRetrievalStatus == PacketStore::InProgress) {
+			ErrorHandler::reportError(request,
+			                          ErrorHandler::ExecutionStartErrorType::SetPacketStoreWithOpenRetrievalInProgress);
+			continue;
+		}
+		deleteContentUntil(packetStoreId, timeLimit);
+	}
+}
+
+void StorageAndRetrievalService::packetStoreContentSummaryReport(Message& request) {
+	request.assertTC(ServiceType, MessageType::ReportContentSummaryOfPacketStores);
+
+	Message report(ServiceType, MessageType::PacketStoreContentSummaryReport, Message::TM, 1);
+	uint16_t numOfPacketStores = request.readUint16();
+
+	if (numOfPacketStores == 0) {
+		report.appendUint16(packetStores.size());
+		for (auto& packetStore : packetStores) {
+			auto packetStoreId = packetStore.first;
+			report.appendString(packetStoreId);
+			createContentSummary(report, packetStoreId);
+		}
+		storeMessage(report);
+		return;
+	}
+	uint16_t numOfValidPacketStores = 0;
+	for (uint16_t i = 0; i < numOfPacketStores; i++) {
+		auto packetStoreId = readPacketStoreId(request);
+		if (packetStores.find(packetStoreId) != packetStores.end()) {
+			numOfValidPacketStores++;
+		}
+	}
+	report.appendUint16(numOfValidPacketStores);
+	request.resetRead();
+	numOfPacketStores = request.readUint16();
+
+	for (uint16_t i = 0; i < numOfPacketStores; i++) {
+		auto packetStoreId = readPacketStoreId(request);
+		if (packetStores.find(packetStoreId) == packetStores.end()) {
+			ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::NonExistingPacketStore);
+			continue;
+		}
+		report.appendString(packetStoreId);
+		createContentSummary(report, packetStoreId);
+	}
+	storeMessage(report);
+}
+
+void StorageAndRetrievalService::changeOpenRetrievalStartTimeTag(Message& request) {
+	request.assertTC(ServiceType, MessageType::ChangeOpenRetrievalStartingTime);
+
+	uint32_t newStartTimeTag = request.readUint32();
+	/**
+	 * @todo: check if newStartTimeTag is in the future
+	 */
+	uint16_t numOfPacketStores = request.readUint16();
+	if (numOfPacketStores == 0) {
+		for (auto& packetStore : packetStores) {
+			if (packetStore.second.openRetrievalStatus == PacketStore::InProgress) {
+				ErrorHandler::reportError(
+				    request, ErrorHandler::ExecutionStartErrorType::SetPacketStoreWithOpenRetrievalInProgress);
+				continue;
+			}
+			packetStore.second.openRetrievalStartTimeTag = newStartTimeTag;
+		}
+		return;
+	}
+
+	for (uint16_t i = 0; i < numOfPacketStores; i++) {
+		auto packetStoreId = readPacketStoreId(request);
+		if (packetStores.find(packetStoreId) == packetStores.end()) {
+			ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::NonExistingPacketStore);
+			continue;
+		}
+		if (packetStores[packetStoreId].openRetrievalStatus == PacketStore::InProgress) {
+			ErrorHandler::reportError(request,
+			                          ErrorHandler::ExecutionStartErrorType::SetPacketStoreWithOpenRetrievalInProgress);
+			continue;
+		}
+		packetStores[packetStoreId].openRetrievalStartTimeTag = newStartTimeTag;
+	}
+}
+
+void StorageAndRetrievalService::resumeOpenRetrievalOfPacketStores(Message& request) {
+	request.assertTC(ServiceType, MessageType::ResumeOpenRetrievalOfPacketStores);
+
+	uint16_t numOfPacketStores = request.readUint16();
+	if (numOfPacketStores == 0) {
+		for (auto& packetStore : packetStores) {
+			if (packetStore.second.byTimeRangeRetrievalStatus) {
+				ErrorHandler::reportError(
+				    request, ErrorHandler::ExecutionStartErrorType::SetPacketStoreWithByTimeRangeRetrieval);
+				continue;
+			}
+			packetStore.second.openRetrievalStatus = PacketStore::InProgress;
+		}
+		return;
+	}
+	for (uint16_t i = 0; i < numOfPacketStores; i++) {
+		auto packetStoreId = readPacketStoreId(request);
+		if (packetStores.find(packetStoreId) == packetStores.end()) {
+			ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::NonExistingPacketStore);
+			continue;
+		}
+		auto& packetStore = packetStores[packetStoreId];
+		if (packetStore.byTimeRangeRetrievalStatus) {
+			ErrorHandler::reportError(request,
+			                          ErrorHandler::ExecutionStartErrorType::SetPacketStoreWithByTimeRangeRetrieval);
+			continue;
+		}
+		packetStore.openRetrievalStatus = PacketStore::InProgress;
+	}
+}
+
+void StorageAndRetrievalService::suspendOpenRetrievalOfPacketStores(Message& request) {
+	request.assertTC(ServiceType, MessageType::SuspendOpenRetrievalOfPacketStores);
+
+	uint16_t numOfPacketStores = request.readUint16();
+	if (numOfPacketStores == 0) {
+		for (auto& packetStore : packetStores) {
+			packetStore.second.openRetrievalStatus = PacketStore::Suspended;
+		}
+		return;
+	}
+	for (uint16_t i = 0; i < numOfPacketStores; i++) {
+		auto packetStoreId = readPacketStoreId(request);
+		if (packetStores.find(packetStoreId) == packetStores.end()) {
+			ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::NonExistingPacketStore);
+			continue;
+		}
+		packetStores[packetStoreId].openRetrievalStatus = PacketStore::Suspended;
+	}
+}
+
+void StorageAndRetrievalService::abortByTimeRangeRetrieval(Message& request) {
+	request.assertTC(ServiceType, MessageType::AbortByTimeRangeRetrieval);
+
+	uint16_t numOfPacketStores = request.readUint16();
+	if (numOfPacketStores == 0) {
+		for (auto& packetStore : packetStores) {
+			packetStore.second.byTimeRangeRetrievalStatus = false;
+		}
+		return;
+	}
+	for (uint16_t i = 0; i < numOfPacketStores; i++) {
+		auto packetStoreId = readPacketStoreId(request);
+		if (packetStores.find(packetStoreId) == packetStores.end()) {
+			ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::NonExistingPacketStore);
+			continue;
+		}
+		packetStores[packetStoreId].byTimeRangeRetrievalStatus = false;
+	}
+}
+
+void StorageAndRetrievalService::packetStoresStatusReport(Message& request) {
+	request.assertTC(ServiceType, MessageType::ReportStatusOfPacketStores);
+
+	Message report(ServiceType, MessageType::PacketStoresStatusReport, Message::TM, 1);
+	report.appendUint16(packetStores.size());
+	for (auto& packetStore : packetStores) {
+		auto packetStoreId = packetStore.first;
+		report.appendString(packetStoreId);
+		report.appendBoolean(packetStore.second.storageStatus);
+		report.appendEnum8(packetStore.second.openRetrievalStatus);
+		report.appendBoolean(packetStore.second.byTimeRangeRetrievalStatus);
+	}
+	storeMessage(report);
+}
+
+void StorageAndRetrievalService::createPacketStores(Message& request) {
+	request.assertTC(ServiceType, MessageType::CreatePacketStores);
+
+	uint16_t numOfPacketStores = request.readUint16();
+	for (uint16_t i = 0; i < numOfPacketStores; i++) {
+		if (packetStores.size() >= ECSSMaxPacketStores) {
+			ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::MaxNumberOfPacketStoresReached);
+			return;
+		}
+		auto idToCreate = readPacketStoreId(request);
+
+		if (packetStores.find(idToCreate) != packetStores.end()) {
+			uint16_t numberOfBytesToSkip = 4;
+			request.skipBytes(numberOfBytesToSkip);
+			ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::AlreadyExistingPacketStore);
+			continue;
+		}
+		uint16_t packetStoreSize = request.readUint16();
+		uint8_t typeCode = request.readUint8();
+		PacketStore::PacketStoreType packetStoreType = (typeCode == 0) ? PacketStore::Circular : PacketStore::Bounded;
+		uint8_t virtualChannel = request.readUint8();
+
+		if (virtualChannel < VirtualChannelLimits.min or virtualChannel > VirtualChannelLimits.max) {
+			ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::InvalidVirtualChannel);
+			continue;
+		}
+		PacketStore newPacketStore;
+		newPacketStore.sizeInBytes = packetStoreSize;
+		newPacketStore.packetStoreType = packetStoreType;
+		newPacketStore.storageStatus = false;
+		newPacketStore.byTimeRangeRetrievalStatus = false;
+		newPacketStore.openRetrievalStatus = PacketStore::Suspended;
+		newPacketStore.virtualChannel = virtualChannel;
+		packetStores.insert({idToCreate, newPacketStore});
+	}
+}
+
+void StorageAndRetrievalService::deletePacketStores(Message& request) {
+	request.assertTC(ServiceType, MessageType::DeletePacketStores);
+
+	uint16_t numOfPacketStores = request.readUint16();
+	if (numOfPacketStores == 0) {
+		int numOfPacketStoresToDelete = 0;
+		etl::string<ECSSPacketStoreIdSize> packetStoresToDelete[packetStores.size()];
+		for (auto& packetStore : packetStores) {
+			if (packetStore.second.storageStatus) {
+				ErrorHandler::reportError(
+				    request, ErrorHandler::ExecutionStartErrorType::DeletionOfPacketStoreWithStorageStatusEnabled);
+				continue;
+			}
+			if (packetStore.second.byTimeRangeRetrievalStatus) {
+				ErrorHandler::reportError(
+				    request, ErrorHandler::ExecutionStartErrorType::DeletionOfPacketWithByTimeRangeRetrieval);
+				continue;
+			}
+			if (packetStore.second.openRetrievalStatus == PacketStore::InProgress) {
+				ErrorHandler::reportError(
+				    request, ErrorHandler::ExecutionStartErrorType::DeletionOfPacketWithOpenRetrievalInProgress);
+				continue;
+			}
+			packetStoresToDelete[numOfPacketStoresToDelete] = packetStore.first;
+			numOfPacketStoresToDelete++;
+		}
+		for (uint16_t l = 0; l < numOfPacketStoresToDelete; l++) {
+			uint8_t data[ECSSPacketStoreIdSize];
+			etl::string<ECSSPacketStoreIdSize> idToDelete = packetStoresToDelete[l];
+			std::copy(idToDelete.begin(), idToDelete.end(), data);
+			String<ECSSPacketStoreIdSize> key(data);
+			packetStores.erase(key);
+		}
+		return;
+	}
+
+	for (uint16_t i = 0; i < numOfPacketStores; i++) {
+		auto idToDelete = readPacketStoreId(request);
+		if (packetStores.find(idToDelete) == packetStores.end()) {
+			ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::NonExistingPacketStore);
+			continue;
+		}
+		auto& packetStore = packetStores[idToDelete];
+
+		if (packetStore.storageStatus) {
+			ErrorHandler::reportError(
+			    request, ErrorHandler::ExecutionStartErrorType::DeletionOfPacketStoreWithStorageStatusEnabled);
+			continue;
+		}
+		if (packetStore.byTimeRangeRetrievalStatus) {
+			ErrorHandler::reportError(request,
+			                          ErrorHandler::ExecutionStartErrorType::DeletionOfPacketWithByTimeRangeRetrieval);
+			continue;
+		}
+		if (packetStore.openRetrievalStatus == PacketStore::InProgress) {
+			ErrorHandler::reportError(
+			    request, ErrorHandler::ExecutionStartErrorType::DeletionOfPacketWithOpenRetrievalInProgress);
+			continue;
+		}
+		packetStores.erase(idToDelete);
+	}
+}
+
+void StorageAndRetrievalService::packetStoreConfigurationReport(Message& request) {
+	request.assertTC(ServiceType, MessageType::ReportConfigurationOfPacketStores);
+
+	Message report(ServiceType, MessageType::PacketStoreConfigurationReport, Message::TM, 1);
+	report.appendUint16(packetStores.size());
+	for (auto& packetStore : packetStores) {
+		auto packetStoreId = packetStore.first;
+		report.appendString(packetStoreId);
+		report.appendUint16(packetStore.second.sizeInBytes);
+		uint8_t typeCode = (packetStore.second.packetStoreType == PacketStore::Circular) ? 0 : 1;
+		report.appendUint8(typeCode);
+		report.appendUint8(packetStore.second.virtualChannel);
+	}
+	storeMessage(report);
+}
+
+void StorageAndRetrievalService::copyPacketsInTimeWindow(Message& request) {
+	request.assertTC(ServiceType, MessageType::CopyPacketsInTimeWindow);
+
+	uint8_t typeOfTimeWindow = request.readEnum8();
+	switch (typeOfTimeWindow) {
+		case FromTagToTag:
+			copyFromTagToTag(request);
+			break;
+		case AfterTimeTag:
+			copyAfterTimeTag(request);
+			break;
+		case BeforeTimeTag:
+			copyBeforeTimeTag(request);
+			break;
+		default:
+			ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::InvalidTimeWindow);
+			break;
+	}
+}
+
+void StorageAndRetrievalService::resizePacketStores(Message& request) {
+	request.assertTC(ServiceType, MessageType::ResizePacketStores);
+
+	uint16_t numOfPacketStores = request.readUint16();
+	for (uint16_t i = 0; i < numOfPacketStores; i++) {
+		auto packetStoreId = readPacketStoreId(request);
+		uint16_t packetStoreSize = request.readUint16(); // In bytes
+		if (packetStores.find(packetStoreId) == packetStores.end()) {
+			ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::NonExistingPacketStore);
+			continue;
+		}
+		auto& packetStore = packetStores[packetStoreId];
+
+		if (packetStoreSize >= ECSSMaxPacketStoreSizeInBytes) {
+			ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::UnableToHandlePacketStoreSize);
+			continue;
+		}
+		if (packetStore.storageStatus) {
+			ErrorHandler::reportError(request,
+			                          ErrorHandler::ExecutionStartErrorType::GetPacketStoreWithStorageStatusEnabled);
+			continue;
+		}
+		if (packetStore.openRetrievalStatus == PacketStore::InProgress) {
+			ErrorHandler::reportError(request,
+			                          ErrorHandler::ExecutionStartErrorType::GetPacketStoreWithOpenRetrievalInProgress);
+			continue;
+		}
+		if (packetStore.byTimeRangeRetrievalStatus) {
+			ErrorHandler::reportError(request,
+			                          ErrorHandler::ExecutionStartErrorType::GetPacketStoreWithByTimeRangeRetrieval);
+			continue;
+		}
+		packetStore.sizeInBytes = packetStoreSize;
+	}
+}
+
+void StorageAndRetrievalService::changeTypeToCircular(Message& request) {
+	request.assertTC(ServiceType, MessageType::ChangeTypeToCircular);
+
+	auto idToChange = readPacketStoreId(request);
+	if (packetStores.find(idToChange) == packetStores.end()) {
+		ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::NonExistingPacketStore);
+		return;
+	}
+	auto& packetStore = packetStores[idToChange];
+
+	if (packetStore.storageStatus) {
+		ErrorHandler::reportError(request,
+		                          ErrorHandler::ExecutionStartErrorType::GetPacketStoreWithStorageStatusEnabled);
+		return;
+	}
+	if (packetStore.byTimeRangeRetrievalStatus) {
+		ErrorHandler::reportError(request,
+		                          ErrorHandler::ExecutionStartErrorType::GetPacketStoreWithByTimeRangeRetrieval);
+		return;
+	}
+	if (packetStore.openRetrievalStatus == PacketStore::InProgress) {
+		ErrorHandler::reportError(request,
+		                          ErrorHandler::ExecutionStartErrorType::GetPacketStoreWithOpenRetrievalInProgress);
+		return;
+	}
+	packetStore.packetStoreType = PacketStore::Circular;
+}
+
+void StorageAndRetrievalService::changeTypeToBounded(Message& request) {
+	request.assertTC(ServiceType, MessageType::ChangeTypeToBounded);
+
+	auto idToChange = readPacketStoreId(request);
+	if (packetStores.find(idToChange) == packetStores.end()) {
+		ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::NonExistingPacketStore);
+		return;
+	}
+	auto& packetStore = packetStores[idToChange];
+
+	if (packetStore.storageStatus) {
+		ErrorHandler::reportError(request,
+		                          ErrorHandler::ExecutionStartErrorType::GetPacketStoreWithStorageStatusEnabled);
+		return;
+	}
+	if (packetStore.byTimeRangeRetrievalStatus) {
+		ErrorHandler::reportError(request,
+		                          ErrorHandler::ExecutionStartErrorType::GetPacketStoreWithByTimeRangeRetrieval);
+		return;
+	}
+	if (packetStore.openRetrievalStatus == PacketStore::InProgress) {
+		ErrorHandler::reportError(request,
+		                          ErrorHandler::ExecutionStartErrorType::GetPacketStoreWithOpenRetrievalInProgress);
+		return;
+	}
+	packetStore.packetStoreType = PacketStore::Bounded;
+}
+
+void StorageAndRetrievalService::changeVirtualChannel(Message& request) {
+	request.assertTC(ServiceType, MessageType::ChangeVirtualChannel);
+
+	auto idToChange = readPacketStoreId(request);
+	uint8_t virtualChannel = request.readUint8();
+	if (packetStores.find(idToChange) == packetStores.end()) {
+		ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::NonExistingPacketStore);
+		return;
+	}
+	auto& packetStore = packetStores[idToChange];
+
+	if (virtualChannel < VirtualChannelLimits.min or virtualChannel > VirtualChannelLimits.max) {
+		ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::InvalidVirtualChannel);
+		return;
+	}
+	if (packetStore.byTimeRangeRetrievalStatus) {
+		ErrorHandler::reportError(request,
+		                          ErrorHandler::ExecutionStartErrorType::GetPacketStoreWithByTimeRangeRetrieval);
+		return;
+	}
+	if (packetStore.openRetrievalStatus == PacketStore::InProgress) {
+		ErrorHandler::reportError(request,
+		                          ErrorHandler::ExecutionStartErrorType::GetPacketStoreWithOpenRetrievalInProgress);
+		return;
+	}
+	packetStore.virtualChannel = virtualChannel;
+}
+
+void StorageAndRetrievalService::execute(Message& request) {
+	switch (request.messageType) {
+		case EnableStorageInPacketStores:
+			enableStorageFunction(request);
+			break;
+		case DisableStorageInPacketStores:
+			disableStorageFunction(request);
+			break;
+		case StartByTimeRangeRetrieval:
+			startByTimeRangeRetrieval(request);
+			break;
+		case DeletePacketStoreContent:
+			deletePacketStoreContent(request);
+			break;
+		case ReportContentSummaryOfPacketStores:
+			packetStoreContentSummaryReport(request);
+			break;
+		case ChangeOpenRetrievalStartingTime:
+			changeOpenRetrievalStartTimeTag(request);
+			break;
+		case ResumeOpenRetrievalOfPacketStores:
+			resumeOpenRetrievalOfPacketStores(request);
+			break;
+		case SuspendOpenRetrievalOfPacketStores:
+			suspendOpenRetrievalOfPacketStores(request);
+			break;
+		case AbortByTimeRangeRetrieval:
+			abortByTimeRangeRetrieval(request);
+			break;
+		case ReportStatusOfPacketStores:
+			packetStoresStatusReport(request);
+			break;
+		case CreatePacketStores:
+			createPacketStores(request);
+			break;
+		case DeletePacketStores:
+			deletePacketStores(request);
+			break;
+		case ReportConfigurationOfPacketStores:
+			packetStoreConfigurationReport(request);
+			break;
+		case CopyPacketsInTimeWindow:
+			copyPacketsInTimeWindow(request);
+			break;
+		case ResizePacketStores:
+			resizePacketStores(request);
+			break;
+		case ChangeTypeToCircular:
+			changeTypeToCircular(request);
+			break;
+		case ChangeTypeToBounded:
+			changeTypeToBounded(request);
+			break;
+		case ChangeVirtualChannel:
+			changeVirtualChannel(request);
+			break;
+		default:
+			ErrorHandler::reportInternalError(ErrorHandler::OtherMessageType);
+			break;
+	}
+}
diff --git a/test/Helpers/PacketStore.cpp b/test/Helpers/PacketStore.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..072303a5b3d8a4c5e92316eb3a446b9ff6e5eb21
--- /dev/null
+++ b/test/Helpers/PacketStore.cpp
@@ -0,0 +1,37 @@
+#include "Helpers/PacketStore.hpp"
+#include "catch2/catch.hpp"
+
+TEST_CASE("Counting a packet store's size in bytes") {
+	SECTION("Correct counting of size in bytes") {
+		Message tm1;
+		tm1.appendUint8(4);
+		tm1.appendFloat(5.6);
+
+		PacketStore packetStore;
+		packetStore.storedTelemetryPackets.push_back({2, tm1});
+
+		REQUIRE(packetStore.storedTelemetryPackets.size() == 1);
+		REQUIRE(packetStore.calculateSizeInBytes() == 5);
+
+		Message tm2;
+		tm2.appendBoolean(true);
+		tm2.appendUint16(45);
+		tm2.appendUint8(3);
+		tm2.appendUint32(55);
+
+		packetStore.storedTelemetryPackets.push_back({2, tm2});
+
+		REQUIRE(packetStore.storedTelemetryPackets.size() == 2);
+		REQUIRE(packetStore.calculateSizeInBytes() == 13);
+
+		Message tm3;
+		tm3.appendUint64(743);
+		tm3.appendUint8(3);
+		tm3.appendUint32(55);
+
+		packetStore.storedTelemetryPackets.push_back({3, tm3});
+
+		REQUIRE(packetStore.storedTelemetryPackets.size() == 3);
+		REQUIRE(packetStore.calculateSizeInBytes() == 26);
+	}
+}
\ No newline at end of file
diff --git a/test/Services/StorageAndRetrievalService.cpp b/test/Services/StorageAndRetrievalService.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fd7020db5c5f9deb294b670be75474fd0a45099b
--- /dev/null
+++ b/test/Services/StorageAndRetrievalService.cpp
@@ -0,0 +1,2755 @@
+#include <iostream>
+#include "catch2/catch.hpp"
+#include "Message.hpp"
+#include "ServiceTests.hpp"
+#include "Services/StorageAndRetrievalService.hpp"
+
+StorageAndRetrievalService& storageAndRetrieval = Services.storageAndRetrieval;
+
+uint32_t timestamps1[6] = {2, 4, 5, 7, 9, 11};
+uint32_t timestamps2[5] = {0, 1, 4, 15, 22};
+uint32_t timestamps3[4] = {4, 7, 9, 14};
+uint32_t timestamps4[8] = {4, 6, 34, 40, 44, 51, 52, 58};
+
+void initializePacketStores() {
+	uint16_t numOfPacketStores = 4;
+	uint8_t concatenatedPacketStoreNames[] = "ps2ps25ps799ps5555";
+	uint16_t offsets[5] = {0, 3, 7, 12, 18};
+	uint16_t sizes[4] = {100, 200, 550, 340};
+	uint8_t virtualChannels[4] = {4, 6, 1, 2};
+
+	for (int i = 0; i < numOfPacketStores; i++) {
+		uint8_t packetStoreData[ECSSPacketStoreIdSize];
+		std::fill(std::begin(packetStoreData), std::end(packetStoreData), 0);
+		std::copy(concatenatedPacketStoreNames + offsets[i], concatenatedPacketStoreNames + offsets[i + 1],
+		          packetStoreData);
+
+		String<ECSSPacketStoreIdSize> packetStoreId(packetStoreData);
+		PacketStore newPacketStore;
+		newPacketStore.sizeInBytes = sizes[i];
+		newPacketStore.packetStoreType = ((i % 2) == 0) ? PacketStore::Circular : PacketStore::Bounded;
+		newPacketStore.virtualChannel = virtualChannels[i];
+		storageAndRetrieval.addPacketStore(packetStoreId, newPacketStore);
+	}
+}
+
+void validPacketStoreCreationRequest(Message& request) {
+	uint16_t numOfPacketStores = 4;
+	request.appendUint16(numOfPacketStores);
+	uint8_t concatenatedPacketStoreNames[] = "ps2ps25ps799ps5555";
+	uint16_t offsets[5] = {0, 3, 7, 12, 18};
+	uint16_t sizes[4] = {100, 200, 550, 340};
+	uint8_t virtualChannels[4] = {4, 6, 1, 2};
+	uint8_t packetStoreTypeCode[2] = {0, 1};
+
+	for (int i = 0; i < numOfPacketStores; i++) {
+		uint8_t packetStoreData[ECSSPacketStoreIdSize];
+		std::fill(std::begin(packetStoreData), std::end(packetStoreData), 0);
+		std::copy(concatenatedPacketStoreNames + offsets[i], concatenatedPacketStoreNames + offsets[i + 1],
+		          packetStoreData);
+
+		String<ECSSPacketStoreIdSize> packetStoreId(packetStoreData);
+		request.appendString(packetStoreId);
+		request.appendUint16(sizes[i]);
+		if ((i % 2) == 0) {
+			request.appendUint8(packetStoreTypeCode[0]);
+		} else {
+			request.appendUint8(packetStoreTypeCode[1]);
+		}
+		request.appendUint8(virtualChannels[i]);
+	}
+}
+
+void invalidPacketStoreCreationRequest(Message& request) {
+	uint16_t numOfPacketStores = 5;
+	request.appendUint16(numOfPacketStores);
+	uint8_t concatenatedPacketStoreNames[] = "ps2ps1ps2ps44ps0000";
+	uint16_t offsets[6] = {0, 3, 6, 9, 13, 19};
+	uint16_t sizes[5] = {33, 55, 66, 77, 99};
+	uint8_t invalidChannel1 = VirtualChannelLimits.min - 1;
+	uint8_t invalidChannel2 = VirtualChannelLimits.max + 1;
+	uint8_t virtualChannels[5] = {5, invalidChannel1, 1, invalidChannel2, 2};
+	uint8_t packetStoreTypeCode[2] = {0, 1};
+
+	for (int i = 0; i < numOfPacketStores; i++) {
+		uint8_t packetStoreData[ECSSPacketStoreIdSize];
+		std::fill(std::begin(packetStoreData), std::end(packetStoreData), 0);
+		std::copy(concatenatedPacketStoreNames + offsets[i], concatenatedPacketStoreNames + offsets[i + 1],
+		          packetStoreData);
+
+		String<ECSSPacketStoreIdSize> packetStoreId(packetStoreData);
+		request.appendString(packetStoreId);
+		request.appendUint16(sizes[i]);
+		if ((i % 2) == 0) {
+			request.appendUint8(packetStoreTypeCode[0]);
+		} else {
+			request.appendUint8(packetStoreTypeCode[1]);
+		}
+		request.appendUint8(virtualChannels[i]);
+	}
+}
+
+etl::array<String<ECSSPacketStoreIdSize>, 4> validPacketStoreIds() {
+	uint8_t packetStoreData[ECSSPacketStoreIdSize] = "ps2";
+	uint8_t packetStoreData2[ECSSPacketStoreIdSize] = "ps25";
+	uint8_t packetStoreData3[ECSSPacketStoreIdSize] = "ps799";
+	uint8_t packetStoreData4[ECSSPacketStoreIdSize] = "ps5555";
+
+	String<ECSSPacketStoreIdSize> id(packetStoreData);
+	String<ECSSPacketStoreIdSize> id2(packetStoreData2);
+	String<ECSSPacketStoreIdSize> id3(packetStoreData3);
+	String<ECSSPacketStoreIdSize> id4(packetStoreData4);
+
+	etl::array<String<ECSSPacketStoreIdSize>, 4> validPacketStores = {id, id2, id3, id4};
+	return validPacketStores;
+}
+
+etl::array<String<ECSSPacketStoreIdSize>, 4> invalidPacketStoreIds() {
+	uint8_t packetStoreData[ECSSPacketStoreIdSize] = "ps1";
+	uint8_t packetStoreData2[ECSSPacketStoreIdSize] = "ps36";
+	uint8_t packetStoreData3[ECSSPacketStoreIdSize] = "ps999";
+	uint8_t packetStoreData4[ECSSPacketStoreIdSize] = "ps1234";
+
+	String<ECSSPacketStoreIdSize> id(packetStoreData);
+	String<ECSSPacketStoreIdSize> id2(packetStoreData2);
+	String<ECSSPacketStoreIdSize> id3(packetStoreData3);
+	String<ECSSPacketStoreIdSize> id4(packetStoreData4);
+
+	etl::array<String<ECSSPacketStoreIdSize>, 4> validPacketStores = {id, id2, id3, id4};
+	return validPacketStores;
+}
+
+void padWithZeros(etl::array<String<ECSSPacketStoreIdSize>, 4>& packetStoreIds) {
+	uint8_t offsets[] = {3, 4, 5, 6};
+	int index = 0;
+	// Padding every empty position with zeros, to avoid memory garbage collection, which leads to a faulty result.
+	for (auto& packetStoreId : packetStoreIds) {
+		uint8_t startingPosition = offsets[index++];
+		for (uint8_t i = startingPosition; i < ECSSPacketStoreIdSize; i++) {
+			packetStoreId[i] = 0;
+		}
+	}
+}
+
+void addTelemetryPacketsInPacketStores() {
+	auto packetStoreIds = validPacketStoreIds();
+
+	for (auto& timestamp : timestamps1) {
+		storageAndRetrieval.addTelemetryToPacketStore(packetStoreIds[0], timestamp);
+	}
+	for (auto& timestamp : timestamps2) {
+		storageAndRetrieval.addTelemetryToPacketStore(packetStoreIds[1], timestamp);
+	}
+	for (auto& timestamp : timestamps3) {
+		storageAndRetrieval.addTelemetryToPacketStore(packetStoreIds[2], timestamp);
+	}
+	for (auto& timestamp : timestamps4) {
+		storageAndRetrieval.addTelemetryToPacketStore(packetStoreIds[3], timestamp);
+	}
+}
+
+void resetPacketStores() {
+	storageAndRetrieval.resetPacketStores();
+}
+
+TEST_CASE("Creating packet stores") {
+	SECTION("Valid packet store creation request") {
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::CreatePacketStores, Message::TC, 1);
+		validPacketStoreCreationRequest(request);
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 0);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 0);
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		CHECK(storageAndRetrieval.getPacketStore(packetStoreIds[0]).sizeInBytes == 100);
+		CHECK(storageAndRetrieval.getPacketStore(packetStoreIds[1]).sizeInBytes == 200);
+		CHECK(storageAndRetrieval.getPacketStore(packetStoreIds[2]).sizeInBytes == 550);
+		CHECK(storageAndRetrieval.getPacketStore(packetStoreIds[3]).sizeInBytes == 340);
+
+		CHECK(storageAndRetrieval.getPacketStore(packetStoreIds[0]).virtualChannel == 4);
+		CHECK(storageAndRetrieval.getPacketStore(packetStoreIds[1]).virtualChannel == 6);
+		CHECK(storageAndRetrieval.getPacketStore(packetStoreIds[2]).virtualChannel == 1);
+		CHECK(storageAndRetrieval.getPacketStore(packetStoreIds[3]).virtualChannel == 2);
+
+		CHECK(storageAndRetrieval.getPacketStore(packetStoreIds[0]).packetStoreType ==
+		      PacketStore::PacketStoreType::Circular);
+		CHECK(storageAndRetrieval.getPacketStore(packetStoreIds[1]).packetStoreType ==
+		      PacketStore::PacketStoreType::Bounded);
+		CHECK(storageAndRetrieval.getPacketStore(packetStoreIds[2]).packetStoreType ==
+		      PacketStore::PacketStoreType::Circular);
+		CHECK(storageAndRetrieval.getPacketStore(packetStoreIds[3]).packetStoreType ==
+		      PacketStore::PacketStoreType::Bounded);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Invalid packet store creation request") {
+		uint8_t packetStoreData[ECSSPacketStoreIdSize] = "ps2";
+		String<ECSSPacketStoreIdSize> existingPacketStoreId(packetStoreData);
+		PacketStore existingPacketStore;
+		storageAndRetrieval.addPacketStore(existingPacketStoreId, existingPacketStore);
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 1);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::CreatePacketStores, Message::TC, 1);
+		invalidPacketStoreCreationRequest(request);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 4);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::InvalidVirtualChannel) == 2);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::AlreadyExistingPacketStore) == 2);
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 2);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Exceeding the maximum number of packet stores") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::CreatePacketStores, Message::TC, 1);
+		invalidPacketStoreCreationRequest(request);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 1);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::MaxNumberOfPacketStoresReached) == 1);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Deleting packet stores") {
+	SECTION("Valid deletion of specified packet stores") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::DeletePacketStores, Message::TC, 1);
+		uint16_t numOfPacketStores = 4;
+		request.appendUint16(numOfPacketStores);
+
+		for (auto& packetStoreId : packetStoreIds) {
+			auto& packetStore = storageAndRetrieval.getPacketStore(packetStoreId);
+			packetStore.storageStatus = false;
+			packetStore.byTimeRangeRetrievalStatus = false;
+			packetStore.openRetrievalStatus = PacketStore::Suspended;
+			request.appendString(packetStoreId);
+		}
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 0);
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 0);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Valid deletion of all packet stores") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::DeletePacketStores, Message::TC, 1);
+		uint16_t numOfPacketStores = 0;
+		request.appendUint16(numOfPacketStores);
+
+		for (auto& packetStoreId : packetStoreIds) {
+			auto& packetStore = storageAndRetrieval.getPacketStore(packetStoreId);
+			packetStore.storageStatus = false;
+			packetStore.byTimeRangeRetrievalStatus = false;
+			packetStore.openRetrievalStatus = PacketStore::Suspended;
+		}
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 0);
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 0);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Invalid deletion of specified packet stores") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::DeletePacketStores, Message::TC, 1);
+		uint16_t numOfPacketStores = 4;
+		request.appendUint16(numOfPacketStores);
+
+		for (auto& packetStoreId : packetStoreIds) {
+			auto& packetStore = storageAndRetrieval.getPacketStore(packetStoreId);
+			packetStore.storageStatus = false;
+			packetStore.byTimeRangeRetrievalStatus = false;
+			packetStore.openRetrievalStatus = PacketStore::Suspended;
+			request.appendString(packetStoreId);
+		}
+
+		storageAndRetrieval.getPacketStore(packetStoreIds[0]).storageStatus = true;
+		storageAndRetrieval.getPacketStore(packetStoreIds[1]).byTimeRangeRetrievalStatus = true;
+		storageAndRetrieval.getPacketStore(packetStoreIds[2]).openRetrievalStatus = PacketStore::InProgress;
+		storageAndRetrieval.getPacketStore(packetStoreIds[3]).storageStatus = true;
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 4);
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::DeletionOfPacketStoreWithStorageStatusEnabled) == 2);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::DeletionOfPacketWithByTimeRangeRetrieval) == 1);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::DeletionOfPacketWithOpenRetrievalInProgress) == 1);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Invalid deletion request of non existing packet stores") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = invalidPacketStoreIds();
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::DeletePacketStores, Message::TC, 1);
+		uint16_t numOfPacketStores = 4;
+		request.appendUint16(numOfPacketStores);
+
+		for (auto& packetStoreId : packetStoreIds) {
+			REQUIRE(not storageAndRetrieval.packetStoreExists(packetStoreId));
+			request.appendString(packetStoreId);
+		}
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 4);
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::NonExistingPacketStore) == 4);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Invalid deletion of all packet stores") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::DeletePacketStores, Message::TC, 1);
+		uint16_t numOfPacketStores = 0;
+		request.appendUint16(numOfPacketStores);
+
+		for (auto& packetStoreId : packetStoreIds) {
+			auto& packetStore = storageAndRetrieval.getPacketStore(packetStoreId);
+			packetStore.storageStatus = false;
+			packetStore.byTimeRangeRetrievalStatus = false;
+			packetStore.openRetrievalStatus = PacketStore::Suspended;
+		}
+
+		storageAndRetrieval.getPacketStore(packetStoreIds[0]).storageStatus = true;
+		storageAndRetrieval.getPacketStore(packetStoreIds[1]).byTimeRangeRetrievalStatus = true;
+		storageAndRetrieval.getPacketStore(packetStoreIds[2]).openRetrievalStatus = PacketStore::InProgress;
+		storageAndRetrieval.getPacketStore(packetStoreIds[3]).openRetrievalStatus = PacketStore::InProgress;
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 4);
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::DeletionOfPacketStoreWithStorageStatusEnabled) == 1);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::DeletionOfPacketWithByTimeRangeRetrieval) == 1);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::DeletionOfPacketWithOpenRetrievalInProgress) == 2);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Both valid and invalid deletion requests") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto correctPacketStoreIds = validPacketStoreIds();
+		auto wrongPacketStoreIds = invalidPacketStoreIds();
+		padWithZeros(correctPacketStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::DeletePacketStores, Message::TC, 1);
+		uint16_t numOfPacketStores = 8;
+		request.appendUint16(numOfPacketStores);
+
+		for (auto& packetStoreId : correctPacketStoreIds) {
+			auto& packetStore = storageAndRetrieval.getPacketStore(packetStoreId);
+			packetStore.storageStatus = false;
+			packetStore.byTimeRangeRetrievalStatus = false;
+			packetStore.openRetrievalStatus = PacketStore::Suspended;
+			request.appendString(packetStoreId);
+		}
+
+		for (auto& packetStoreId : wrongPacketStoreIds) {
+			REQUIRE(not storageAndRetrieval.packetStoreExists(packetStoreId));
+			request.appendString(packetStoreId);
+		}
+
+		storageAndRetrieval.getPacketStore(correctPacketStoreIds[0]).storageStatus = true;
+		storageAndRetrieval.getPacketStore(correctPacketStoreIds[1]).byTimeRangeRetrievalStatus = true;
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 6);
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 2);
+		REQUIRE(storageAndRetrieval.packetStoreExists(correctPacketStoreIds[0]));
+		REQUIRE(storageAndRetrieval.packetStoreExists(correctPacketStoreIds[1]));
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::DeletionOfPacketStoreWithStorageStatusEnabled) == 1);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::DeletionOfPacketWithByTimeRangeRetrieval) == 1);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::NonExistingPacketStore) == 4);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Enabling the storage of packet stores") {
+	SECTION("Valid enabling of storage") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::EnableStorageInPacketStores, Message::TC, 1);
+
+		uint16_t numOfPacketStores = 2;
+		request.appendUint16(numOfPacketStores);
+		for (int i = 0; i < numOfPacketStores; i++) {
+			REQUIRE(storageAndRetrieval.packetStoreExists(packetStoreIds[i]));
+			storageAndRetrieval.getPacketStore(packetStoreIds[i]).storageStatus = false;
+			request.appendString(packetStoreIds[i]);
+		}
+		storageAndRetrieval.getPacketStore(packetStoreIds[2]).storageStatus = false;
+		storageAndRetrieval.getPacketStore(packetStoreIds[3]).storageStatus = false;
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 0);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[0]).storageStatus == true);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[1]).storageStatus == true);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).storageStatus == false);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[3]).storageStatus == false);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Invalid enabling of storage") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = invalidPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::EnableStorageInPacketStores, Message::TC, 1);
+
+		uint16_t numOfPacketStores = 3;
+		request.appendUint16(numOfPacketStores);
+		for (int i = 0; i < numOfPacketStores; i++) {
+			REQUIRE(not storageAndRetrieval.packetStoreExists(packetStoreIds[i]));
+			request.appendString(packetStoreIds[i]);
+		}
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 3);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::NonExistingPacketStore) == 3);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Enabling the storage of all packet stores") {
+		initializePacketStores();
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::EnableStorageInPacketStores, Message::TC, 1);
+
+		uint16_t numOfPacketStores = 0;
+		request.appendUint16(numOfPacketStores);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 0);
+		for (auto& packetStoreId : packetStoreIds) {
+			REQUIRE(storageAndRetrieval.getPacketStore(packetStoreId).storageStatus == true);
+		}
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Disabling the storage of packet stores") {
+	SECTION("Valid disabling of storage") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::DisableStorageInPacketStores, Message::TC, 1);
+
+		uint16_t numOfPacketStores = 2;
+		request.appendUint16(numOfPacketStores);
+		for (int i = 0; i < numOfPacketStores; i++) {
+			storageAndRetrieval.getPacketStore(packetStoreIds[i]).storageStatus = true;
+			request.appendString(packetStoreIds[i]);
+		}
+		storageAndRetrieval.getPacketStore(packetStoreIds[2]).storageStatus = true;
+		storageAndRetrieval.getPacketStore(packetStoreIds[3]).storageStatus = true;
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 0);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[0]).storageStatus == false);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[1]).storageStatus == false);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).storageStatus == true);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[3]).storageStatus == true);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Invalid disabling of storage") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = invalidPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::DisableStorageInPacketStores, Message::TC, 1);
+
+		uint16_t numOfPacketStores = 3;
+		request.appendUint16(numOfPacketStores);
+		for (int i = 0; i < numOfPacketStores; i++) {
+			REQUIRE(not storageAndRetrieval.packetStoreExists(packetStoreIds[i]));
+			request.appendString(packetStoreIds[i]);
+		}
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 3);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::NonExistingPacketStore) == 3);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Enabling the storage of all packet stores") {
+		initializePacketStores();
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::DisableStorageInPacketStores, Message::TC, 1);
+
+		uint16_t numOfPacketStores = 0;
+		request.appendUint16(numOfPacketStores);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 0);
+		for (auto& packetStoreId : packetStoreIds) {
+			REQUIRE(storageAndRetrieval.getPacketStore(packetStoreId).storageStatus == false);
+		}
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Changing the open retrieval start-time-tag") {
+	SECTION("Successful change of the start-time-tag") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::ChangeOpenRetrievalStartingTime, Message::TC, 1);
+
+		uint32_t startTimeTag = 200;
+		uint16_t numOfPacketStores = 2;
+		request.appendUint32(startTimeTag);
+		request.appendUint16(numOfPacketStores);
+
+		for (auto& packetStoreId : packetStoreIds) {
+			REQUIRE(storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStartTimeTag == 0);
+			storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStatus = PacketStore::Suspended;
+			request.appendString(packetStoreId);
+		}
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 0);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[0]).openRetrievalStartTimeTag == 200);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[1]).openRetrievalStartTimeTag == 200);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).openRetrievalStartTimeTag == 0);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[3]).openRetrievalStartTimeTag == 0);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Failed change of the start-time-tag") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto correctPacketStoreIds = validPacketStoreIds();
+		auto wrongPacketStoreIds = invalidPacketStoreIds();
+		padWithZeros(correctPacketStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::ChangeOpenRetrievalStartingTime, Message::TC, 1);
+
+		uint32_t startTimeTag = 200;
+		uint16_t numOfPacketStores = 6;
+		request.appendUint32(startTimeTag);
+		request.appendUint16(numOfPacketStores);
+
+		for (int i = 0; i < numOfPacketStores / 2; i++) {
+			auto packetStoreId = correctPacketStoreIds[i];
+			REQUIRE(storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStartTimeTag == 0);
+			storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStatus = PacketStore::InProgress;
+			request.appendString(packetStoreId);
+		}
+
+		for (int i = 0; i < numOfPacketStores / 2; i++) {
+			auto packetStoreId = wrongPacketStoreIds[i];
+			REQUIRE(not storageAndRetrieval.packetStoreExists(packetStoreId));
+			request.appendString(packetStoreId);
+		}
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 6);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::NonExistingPacketStore) == 3);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::SetPacketStoreWithOpenRetrievalInProgress) == 3);
+
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[0]).openRetrievalStartTimeTag == 0);
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[1]).openRetrievalStartTimeTag == 0);
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[2]).openRetrievalStartTimeTag == 0);
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[3]).openRetrievalStartTimeTag == 0);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Both successful and failed attempts to change the start-time-tag of all packet stores") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::ChangeOpenRetrievalStartingTime, Message::TC, 1);
+
+		uint32_t startTimeTag = 200;
+		uint16_t numOfPacketStores = 0;
+		request.appendUint32(startTimeTag);
+		request.appendUint16(numOfPacketStores);
+
+		for (auto& packetStoreId : packetStoreIds) {
+			REQUIRE(storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStartTimeTag == 0);
+			storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStatus = PacketStore::Suspended;
+		}
+		storageAndRetrieval.getPacketStore(packetStoreIds[2]).openRetrievalStatus = PacketStore::InProgress;
+		storageAndRetrieval.getPacketStore(packetStoreIds[3]).openRetrievalStatus = PacketStore::InProgress;
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 2);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::SetPacketStoreWithOpenRetrievalInProgress) == 2);
+
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[0]).openRetrievalStartTimeTag == 200);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[1]).openRetrievalStartTimeTag == 200);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).openRetrievalStartTimeTag == 0);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[3]).openRetrievalStartTimeTag == 0);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Resuming the open retrieval process") {
+	SECTION("Successful resuming of the open retrieval") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::ResumeOpenRetrievalOfPacketStores, Message::TC, 1);
+
+		uint16_t numOfPacketStores = 3;
+		request.appendUint16(numOfPacketStores);
+		for (auto& packetStoreId : packetStoreIds) {
+			storageAndRetrieval.getPacketStore(packetStoreId).byTimeRangeRetrievalStatus = false;
+			storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStatus = PacketStore::Suspended;
+			request.appendString(packetStoreId);
+		}
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 0);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[0]).openRetrievalStatus == PacketStore::InProgress);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[1]).openRetrievalStatus == PacketStore::InProgress);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).openRetrievalStatus == PacketStore::InProgress);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[3]).openRetrievalStatus == PacketStore::Suspended);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Failed resuming of the open retrieval") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto correctPacketStoreIds = validPacketStoreIds();
+		auto wrongPacketStoreIds = invalidPacketStoreIds();
+		padWithZeros(correctPacketStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::ResumeOpenRetrievalOfPacketStores, Message::TC, 1);
+
+		uint16_t numOfPacketStores = 6;
+		request.appendUint16(numOfPacketStores);
+
+		for (int i = 0; i < numOfPacketStores / 2; i++) {
+			auto packetStoreId = correctPacketStoreIds[i];
+			storageAndRetrieval.getPacketStore(packetStoreId).byTimeRangeRetrievalStatus = true;
+			storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStatus = PacketStore::Suspended;
+			request.appendString(packetStoreId);
+		}
+		storageAndRetrieval.getPacketStore(correctPacketStoreIds[3]).openRetrievalStatus = PacketStore::Suspended;
+
+		for (int i = 0; i < numOfPacketStores / 2; i++) {
+			auto packetStoreId = wrongPacketStoreIds[i];
+			REQUIRE(not storageAndRetrieval.packetStoreExists(packetStoreId));
+			request.appendString(packetStoreId);
+		}
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 6);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::NonExistingPacketStore) == 3);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::SetPacketStoreWithByTimeRangeRetrieval) == 3);
+
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[0]).openRetrievalStatus ==
+		        PacketStore::Suspended);
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[1]).openRetrievalStatus ==
+		        PacketStore::Suspended);
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[2]).openRetrievalStatus ==
+		        PacketStore::Suspended);
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[3]).openRetrievalStatus ==
+		        PacketStore::Suspended);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Both successful and failed attempts to resume the open retrieval of all packet stores") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::ResumeOpenRetrievalOfPacketStores, Message::TC, 1);
+
+		uint16_t numOfPacketStores = 0;
+		request.appendUint16(numOfPacketStores);
+
+		for (auto& packetStoreId : packetStoreIds) {
+			storageAndRetrieval.getPacketStore(packetStoreId).byTimeRangeRetrievalStatus = false;
+			storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStatus = PacketStore::Suspended;
+		}
+		storageAndRetrieval.getPacketStore(packetStoreIds[2]).byTimeRangeRetrievalStatus = true;
+		storageAndRetrieval.getPacketStore(packetStoreIds[3]).byTimeRangeRetrievalStatus = true;
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 2);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::SetPacketStoreWithByTimeRangeRetrieval) == 2);
+
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[0]).openRetrievalStatus == PacketStore::InProgress);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[1]).openRetrievalStatus == PacketStore::InProgress);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).openRetrievalStatus == PacketStore::Suspended);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[3]).openRetrievalStatus == PacketStore::Suspended);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Suspending the open retrieval process") {
+	SECTION("Successful suspension of the open retrieval") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::SuspendOpenRetrievalOfPacketStores, Message::TC, 1);
+
+		uint16_t numOfPacketStores = 3;
+		request.appendUint16(numOfPacketStores);
+		for (auto& packetStoreId : packetStoreIds) {
+			storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStatus = PacketStore::InProgress;
+			request.appendString(packetStoreId);
+		}
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 0);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[0]).openRetrievalStatus == PacketStore::Suspended);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[1]).openRetrievalStatus == PacketStore::Suspended);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).openRetrievalStatus == PacketStore::Suspended);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[3]).openRetrievalStatus == PacketStore::InProgress);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Failed suspension of the open retrieval") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto correctPacketStoreIds = validPacketStoreIds();
+		auto wrongPacketStoreIds = invalidPacketStoreIds();
+		padWithZeros(correctPacketStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::SuspendOpenRetrievalOfPacketStores, Message::TC, 1);
+
+		uint16_t numOfPacketStores = 6;
+		request.appendUint16(numOfPacketStores);
+
+		for (int i = 0; i < numOfPacketStores / 2; i++) {
+			auto packetStoreId = correctPacketStoreIds[i];
+			storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStatus = PacketStore::InProgress;
+			request.appendString(packetStoreId);
+		}
+		storageAndRetrieval.getPacketStore(correctPacketStoreIds[3]).openRetrievalStatus = PacketStore::InProgress;
+
+		for (int i = 0; i < numOfPacketStores / 2; i++) {
+			auto packetStoreId = wrongPacketStoreIds[i];
+			REQUIRE(not storageAndRetrieval.packetStoreExists(packetStoreId));
+			request.appendString(packetStoreId);
+		}
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 3);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::NonExistingPacketStore) == 3);
+
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[0]).openRetrievalStatus ==
+		        PacketStore::Suspended);
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[1]).openRetrievalStatus ==
+		        PacketStore::Suspended);
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[2]).openRetrievalStatus ==
+		        PacketStore::Suspended);
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[3]).openRetrievalStatus ==
+		        PacketStore::InProgress);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Successful attempt to suspend the open retrieval of all packet stores") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::SuspendOpenRetrievalOfPacketStores, Message::TC, 1);
+
+		uint16_t numOfPacketStores = 0;
+		request.appendUint16(numOfPacketStores);
+
+		for (auto& packetStoreId : packetStoreIds) {
+			REQUIRE(storageAndRetrieval.packetStoreExists(packetStoreId));
+			storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStatus = PacketStore::InProgress;
+		}
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 0);
+
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[0]).openRetrievalStatus == PacketStore::Suspended);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[1]).openRetrievalStatus == PacketStore::Suspended);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).openRetrievalStatus == PacketStore::Suspended);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[3]).openRetrievalStatus == PacketStore::Suspended);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Starting the by-time-range retrieval of packet stores") {
+	SECTION("Successful starting of the by-time-range retrieval") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::StartByTimeRangeRetrieval, Message::TC, 1);
+
+		uint16_t numOfPacketStores = 3;
+		request.appendUint16(numOfPacketStores);
+
+		uint32_t timeTags1[4] = {20, 30, 40, 50};
+		uint32_t timeTags2[4] = {60, 70, 80, 90};
+
+		int index = 0;
+		for (auto& packetStoreId : packetStoreIds) {
+			storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStatus = PacketStore::Suspended;
+			storageAndRetrieval.getPacketStore(packetStoreId).byTimeRangeRetrievalStatus = false;
+			request.appendString(packetStoreId);
+			uint32_t timeTag1 = timeTags1[index];
+			uint32_t timeTag2 = timeTags2[index++];
+			request.appendUint32(timeTag1);
+			request.appendUint32(timeTag2);
+		}
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 0);
+		for (int i = 0; i < numOfPacketStores; i++) {
+			auto& packetStore = storageAndRetrieval.getPacketStore(packetStoreIds[i]);
+			REQUIRE(packetStore.byTimeRangeRetrievalStatus == true);
+			REQUIRE(packetStore.retrievalStartTime == timeTags1[i]);
+			REQUIRE(packetStore.retrievalEndTime == timeTags2[i]);
+		}
+		auto& packetStore = storageAndRetrieval.getPacketStore(packetStoreIds[3]);
+		REQUIRE(packetStore.byTimeRangeRetrievalStatus == false);
+		REQUIRE(packetStore.retrievalStartTime == 0);
+		REQUIRE(packetStore.retrievalEndTime == 0);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Failed starting of the by-time-range retrieval") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto correctPacketStoreIds = validPacketStoreIds();
+		auto wrongPacketStoreIds = invalidPacketStoreIds();
+		padWithZeros(correctPacketStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::StartByTimeRangeRetrieval, Message::TC, 1);
+
+		uint16_t numOfPacketStores = 6;
+		request.appendUint16(numOfPacketStores);
+
+		for (int i = 0; i < numOfPacketStores / 2; i++) {
+			auto packetStoreId = correctPacketStoreIds[i];
+			storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStatus =
+			    (i % 2 == 0) ? PacketStore::Suspended : PacketStore::InProgress;
+			storageAndRetrieval.getPacketStore(packetStoreId).byTimeRangeRetrievalStatus = i % 2 == 0;
+
+			request.appendString(packetStoreId);
+			uint32_t timeTag1 = 20;
+			uint32_t timeTag2 = 40;
+			request.appendUint32(timeTag1);
+			request.appendUint32(timeTag2);
+		}
+		storageAndRetrieval.getPacketStore(correctPacketStoreIds[3]).byTimeRangeRetrievalStatus = false;
+
+		for (int i = 0; i < numOfPacketStores / 2; i++) {
+			auto packetStoreId = wrongPacketStoreIds[i];
+			REQUIRE(not storageAndRetrieval.packetStoreExists(packetStoreId));
+			request.appendString(packetStoreId);
+			uint32_t timeTag1 = 20;
+			uint32_t timeTag2 = 40;
+			request.appendUint32(timeTag1);
+			request.appendUint32(timeTag2);
+		}
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 6);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::NonExistingPacketStore) == 3);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::ByTimeRangeRetrievalAlreadyEnabled) == 2);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::GetPacketStoreWithOpenRetrievalInProgress) == 1);
+
+		for (int i = 0; i < numOfPacketStores / 2; i++) {
+			auto& packetStore = storageAndRetrieval.getPacketStore(correctPacketStoreIds[i]);
+			REQUIRE(packetStore.byTimeRangeRetrievalStatus == (i % 2 == 0));
+			REQUIRE(packetStore.retrievalStartTime == 0);
+			REQUIRE(packetStore.retrievalEndTime == 0);
+		}
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[3]).byTimeRangeRetrievalStatus == false);
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[3]).retrievalStartTime == 0);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Invalid window requested") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::StartByTimeRangeRetrieval, Message::TC, 1);
+
+		uint16_t numOfPacketStores = 3;
+		request.appendUint16(numOfPacketStores);
+
+		for (auto& packetStoreId : packetStoreIds) {
+			storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStatus = PacketStore::Suspended;
+			storageAndRetrieval.getPacketStore(packetStoreId).byTimeRangeRetrievalStatus = false;
+			request.appendString(packetStoreId);
+			uint32_t timeTag1 = 90;
+			uint32_t timeTag2 = 20;
+			request.appendUint32(timeTag1);
+			request.appendUint32(timeTag2);
+		}
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 3);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::InvalidTimeWindow) == 3);
+
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[0]).byTimeRangeRetrievalStatus == false);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[1]).byTimeRangeRetrievalStatus == false);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).byTimeRangeRetrievalStatus == false);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[3]).byTimeRangeRetrievalStatus == false);
+
+		for (auto& packetStoreId : packetStoreIds) {
+			REQUIRE(storageAndRetrieval.getPacketStore(packetStoreId).retrievalStartTime == 0);
+		}
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Aborting the by-time-range retrieval of packet stores") {
+	SECTION("Successful aborting of the by-time-range retrieval") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::AbortByTimeRangeRetrieval, Message::TC, 1);
+
+		uint16_t numOfPacketStores = 3;
+		request.appendUint16(numOfPacketStores);
+
+		for (auto& packetStoreId : packetStoreIds) {
+			storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStatus = PacketStore::Suspended;
+			storageAndRetrieval.getPacketStore(packetStoreId).byTimeRangeRetrievalStatus = true;
+			request.appendString(packetStoreId);
+		}
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 0);
+		for (int i = 0; i < numOfPacketStores; i++) {
+			REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[i]).byTimeRangeRetrievalStatus == false);
+		}
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[3]).byTimeRangeRetrievalStatus == true);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Failed aborting of the by-time-range retrieval") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto wrongPacketStoreIds = invalidPacketStoreIds();
+		auto correctPacketStoreIds = validPacketStoreIds();
+		padWithZeros(correctPacketStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::AbortByTimeRangeRetrieval, Message::TC, 1);
+
+		uint16_t numOfPacketStores = 3;
+		request.appendUint16(numOfPacketStores);
+
+		for (auto& packetStoreId : correctPacketStoreIds) {
+			storageAndRetrieval.getPacketStore(packetStoreId).byTimeRangeRetrievalStatus = true;
+		}
+
+		for (int i = 0; i < numOfPacketStores; i++) {
+			auto packetStoreId = wrongPacketStoreIds[i];
+			REQUIRE(not storageAndRetrieval.packetStoreExists(packetStoreId));
+			request.appendString(packetStoreId);
+		}
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 3);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::NonExistingPacketStore) == 3);
+		for (auto& packetStoreId : correctPacketStoreIds) {
+			storageAndRetrieval.getPacketStore(packetStoreId).byTimeRangeRetrievalStatus = true;
+		}
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Successful abort of the by-time-range retrieval of all packet stores") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::AbortByTimeRangeRetrieval, Message::TC, 1);
+
+		uint16_t numOfPacketStores = 0;
+		request.appendUint16(numOfPacketStores);
+
+		for (auto& packetStoreId : packetStoreIds) {
+			storageAndRetrieval.getPacketStore(packetStoreId).byTimeRangeRetrievalStatus = true;
+		}
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 0);
+
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[0]).byTimeRangeRetrievalStatus == false);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[1]).byTimeRangeRetrievalStatus == false);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).byTimeRangeRetrievalStatus == false);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[3]).byTimeRangeRetrievalStatus == false);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Reporting the status of packet stores") {
+	SECTION("Valid reporting of the packet store status") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		uint8_t packetStoreData[ECSSPacketStoreIdSize] = "ps2";
+		uint8_t packetStoreData2[ECSSPacketStoreIdSize] = "ps25";
+		uint8_t packetStoreData3[ECSSPacketStoreIdSize] = "ps799";
+		uint8_t packetStoreData4[ECSSPacketStoreIdSize] = "ps5555";
+
+		int count = 0;
+		for (auto& packetStoreId : packetStoreIds) {
+			auto& packetStore = storageAndRetrieval.getPacketStore(packetStoreId);
+			packetStore.storageStatus = (count % 2 == 0);
+			packetStore.byTimeRangeRetrievalStatus = (count % 2 != 0);
+			packetStore.openRetrievalStatus = (count % 2 == 0) ? PacketStore::InProgress : PacketStore::Suspended;
+			count++;
+		}
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::ReportStatusOfPacketStores, Message::TC, 1);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 1);
+		Message report = ServiceTests::get(0);
+
+		REQUIRE(report.messageType == StorageAndRetrievalService::MessageType::PacketStoresStatusReport);
+		REQUIRE(report.readUint16() == 4);
+
+		// Packet store 1
+		uint8_t data[ECSSPacketStoreIdSize];
+		report.readString(data, ECSSPacketStoreIdSize);
+		CHECK(std::equal(std::begin(data), std::end(data), std::begin(packetStoreData)));
+		CHECK(report.readBoolean() == true);
+		CHECK(report.readEnum8() == 1);
+		CHECK(report.readBoolean() == false);
+		// Packet store 2
+		report.readString(data, ECSSPacketStoreIdSize);
+		CHECK(std::equal(std::begin(data), std::end(data), std::begin(packetStoreData2)));
+		CHECK(report.readBoolean() == false);
+		CHECK(report.readEnum8() == 0);
+		CHECK(report.readBoolean() == true);
+		// Packet store 3
+		report.readString(data, ECSSPacketStoreIdSize);
+		CHECK(std::equal(std::begin(data), std::end(data), std::begin(packetStoreData4)));
+		CHECK(report.readBoolean() == false);
+		CHECK(report.readEnum8() == 0);
+		CHECK(report.readBoolean() == true);
+		// Packet store 4
+		report.readString(data, ECSSPacketStoreIdSize);
+		CHECK(std::equal(std::begin(data), std::end(data), std::begin(packetStoreData3)));
+		CHECK(report.readBoolean() == true);
+		CHECK(report.readEnum8() == 1);
+		CHECK(report.readBoolean() == false);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Reporting the configuration of packet stores") {
+	SECTION("Valid reporting of the configuration") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		uint8_t packetStoreData[ECSSPacketStoreIdSize] = "ps2";
+		uint8_t packetStoreData2[ECSSPacketStoreIdSize] = "ps25";
+		uint8_t packetStoreData3[ECSSPacketStoreIdSize] = "ps799";
+		uint8_t packetStoreData4[ECSSPacketStoreIdSize] = "ps5555";
+
+		int count = 0;
+		for (auto& packetStoreId : packetStoreIds) {
+			storageAndRetrieval.getPacketStore(packetStoreId).packetStoreType =
+			    (count % 2 == 0) ? PacketStore::Circular : PacketStore::Bounded;
+			count++;
+		}
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::ReportConfigurationOfPacketStores, Message::TC, 1);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 1);
+		Message report = ServiceTests::get(0);
+
+		REQUIRE(report.messageType == StorageAndRetrievalService::MessageType::PacketStoreConfigurationReport);
+		REQUIRE(report.readUint16() == 4);
+
+		// Packet store 1
+		uint8_t data[ECSSPacketStoreIdSize];
+		report.readString(data, ECSSPacketStoreIdSize);
+		CHECK(std::equal(std::begin(data), std::end(data), std::begin(packetStoreData)));
+		CHECK(report.readUint16() == 100);
+		CHECK(report.readUint8() == 0);
+		CHECK(report.readUint8() == 4);
+		// Packet store 2
+		report.readString(data, ECSSPacketStoreIdSize);
+		CHECK(std::equal(std::begin(data), std::end(data), std::begin(packetStoreData2)));
+		CHECK(report.readUint16() == 200);
+		CHECK(report.readUint8() == 1);
+		CHECK(report.readUint8() == 6);
+		// Packet store 3
+		report.readString(data, ECSSPacketStoreIdSize);
+		CHECK(std::equal(std::begin(data), std::end(data), std::begin(packetStoreData4)));
+		CHECK(report.readUint16() == 340);
+		CHECK(report.readUint8() == 1);
+		CHECK(report.readUint8() == 2);
+		// Packet store 4
+		report.readString(data, ECSSPacketStoreIdSize);
+		CHECK(std::equal(std::begin(data), std::end(data), std::begin(packetStoreData3)));
+		CHECK(report.readUint16() == 550);
+		CHECK(report.readUint8() == 0);
+		CHECK(report.readUint8() == 1);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Resizing the packet stores") {
+	SECTION("Successful resizing of packet stores") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		uint16_t newSizes[4] = {11, 22, 33, 44};
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::ResizePacketStores, Message::TC, 1);
+
+		uint16_t numOfPacketStores = 3;
+		request.appendUint16(numOfPacketStores);
+		int index = 0;
+		for (auto& packetStoreId : packetStoreIds) {
+			auto& packetStore = storageAndRetrieval.getPacketStore(packetStoreId);
+			packetStore.storageStatus = false;
+			packetStore.openRetrievalStatus = PacketStore::Suspended;
+			packetStore.byTimeRangeRetrievalStatus = false;
+
+			request.appendString(packetStoreId);
+			request.appendUint16(newSizes[index]);
+			index++;
+		}
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 0);
+		for (int i = 0; i < numOfPacketStores; i++) {
+			REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[i]).sizeInBytes == newSizes[i]);
+		}
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[3]).sizeInBytes == 340);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Failed resizing of packet stores") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		uint16_t oldSizes[4] = {100, 200, 550, 340};
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::ResizePacketStores, Message::TC, 1);
+
+		uint16_t numOfPacketStores = 4;
+		request.appendUint16(numOfPacketStores);
+		int index = 0;
+		for (auto& packetStoreId : packetStoreIds) {
+			auto& packetStore = storageAndRetrieval.getPacketStore(packetStoreId);
+			packetStore.storageStatus = (index % 2 == 0);
+			packetStore.byTimeRangeRetrievalStatus = (index == 1);
+			packetStore.openRetrievalStatus = (index == 3) ? PacketStore::InProgress : PacketStore::Suspended;
+
+			request.appendString(packetStoreId);
+			request.appendUint16(35);
+			index++;
+		}
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 4);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::GetPacketStoreWithStorageStatusEnabled) == 2);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::GetPacketStoreWithOpenRetrievalInProgress) == 1);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::GetPacketStoreWithByTimeRangeRetrieval) == 1);
+		int i = 0;
+
+		for (auto& packetStoreId : packetStoreIds) {
+			REQUIRE(storageAndRetrieval.getPacketStore(packetStoreId).sizeInBytes == oldSizes[i++]);
+		}
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Memory unable to handle the requested size") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		uint16_t newSizes[4] = {1000, 2000, 3400, 5500};
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::ResizePacketStores, Message::TC, 1);
+
+		uint16_t numOfPacketStores = 4;
+		request.appendUint16(numOfPacketStores);
+		int index = 0;
+		for (auto& packetStoreId : packetStoreIds) {
+			auto& packetStore = storageAndRetrieval.getPacketStore(packetStoreId);
+			packetStore.storageStatus = false;
+			packetStore.byTimeRangeRetrievalStatus = false;
+			packetStore.openRetrievalStatus = PacketStore::Suspended;
+
+			request.appendString(packetStoreId);
+			request.appendUint16(newSizes[index++]);
+		}
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 4);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::UnableToHandlePacketStoreSize) == 4);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Request to resize non existing packet stores") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto wrongPacketStoreIds = invalidPacketStoreIds();
+		auto correctPacketStoreIds = validPacketStoreIds();
+		padWithZeros(correctPacketStoreIds);
+
+		uint16_t oldSizes[4] = {100, 200, 550, 340};
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::ResizePacketStores, Message::TC, 1);
+
+		uint16_t numOfPacketStores = 4;
+		request.appendUint16(numOfPacketStores);
+		for (auto& packetStoreId : wrongPacketStoreIds) {
+			request.appendString(packetStoreId);
+			request.appendUint16(35);
+		}
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 4);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::NonExistingPacketStore) == 4);
+		int i = 0;
+		for (auto& packetStoreId : correctPacketStoreIds) {
+			REQUIRE(storageAndRetrieval.getPacketStore(packetStoreId).sizeInBytes == oldSizes[i++]);
+		}
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Changing the packet store type to circular") {
+	SECTION("Successful changing of type to circular") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		for (auto& packetStoreId : packetStoreIds) {
+			auto& packetStore = storageAndRetrieval.getPacketStore(packetStoreId);
+			packetStore.packetStoreType = PacketStore::Bounded;
+			packetStore.storageStatus = false;
+			packetStore.byTimeRangeRetrievalStatus = false;
+			packetStore.openRetrievalStatus = PacketStore::Suspended;
+		}
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::ChangeTypeToCircular, Message::TC, 1);
+
+		request.appendString(packetStoreIds[0]);
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 0);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[0]).packetStoreType == PacketStore::Circular);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[1]).packetStoreType == PacketStore::Bounded);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).packetStoreType == PacketStore::Bounded);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[3]).packetStoreType == PacketStore::Bounded);
+
+		Message request2(StorageAndRetrievalService::ServiceType,
+		                 StorageAndRetrievalService::MessageType::ChangeTypeToCircular, Message::TC, 1);
+
+		request2.appendString(packetStoreIds[3]);
+		MessageParser::execute(request2);
+
+		CHECK(ServiceTests::count() == 0);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[0]).packetStoreType == PacketStore::Circular);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[1]).packetStoreType == PacketStore::Bounded);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).packetStoreType == PacketStore::Bounded);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[3]).packetStoreType == PacketStore::Circular);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Failed changing of type to circular") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto correctPacketStoreIds = validPacketStoreIds();
+		auto wrongPacketStoreIds = invalidPacketStoreIds();
+		padWithZeros(correctPacketStoreIds);
+
+		int count = 0;
+		for (auto& packetStoreId : correctPacketStoreIds) {
+			auto& packetStore = storageAndRetrieval.getPacketStore(packetStoreId);
+			packetStore.packetStoreType = PacketStore::Bounded;
+			packetStore.storageStatus = (count == 0);
+			packetStore.byTimeRangeRetrievalStatus = (count == 1);
+			packetStore.openRetrievalStatus = (count == 2) ? PacketStore::InProgress : PacketStore::Suspended;
+			count++;
+		}
+
+		String<ECSSPacketStoreIdSize> finalIds[4] = {wrongPacketStoreIds[0], correctPacketStoreIds[0],
+		                                                correctPacketStoreIds[1], correctPacketStoreIds[2]};
+
+		ErrorHandler::ExecutionStartErrorType expectedErrors[4] = {
+		    ErrorHandler::ExecutionStartErrorType::NonExistingPacketStore,
+		    ErrorHandler::ExecutionStartErrorType::GetPacketStoreWithStorageStatusEnabled,
+		    ErrorHandler::ExecutionStartErrorType::GetPacketStoreWithByTimeRangeRetrieval,
+		    ErrorHandler::ExecutionStartErrorType::GetPacketStoreWithOpenRetrievalInProgress};
+
+		for (int i = 0; i < 4; i++) {
+			Message request(StorageAndRetrievalService::ServiceType,
+			                StorageAndRetrievalService::MessageType::ChangeTypeToCircular, Message::TC, 1);
+
+			request.appendString(finalIds[i]);
+			MessageParser::execute(request);
+			CHECK(ServiceTests::count() == i + 1);
+			CHECK(ServiceTests::countThrownErrors(expectedErrors[i]) == 1);
+		}
+
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[0]).packetStoreType == PacketStore::Bounded);
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[1]).packetStoreType == PacketStore::Bounded);
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[2]).packetStoreType == PacketStore::Bounded);
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[3]).packetStoreType == PacketStore::Bounded);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Changing the packet store type to bounded") {
+	SECTION("Successful changing of type to bounded") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		for (auto& packetStoreId : packetStoreIds) {
+			storageAndRetrieval.getPacketStore(packetStoreId).packetStoreType = PacketStore::Circular;
+			storageAndRetrieval.getPacketStore(packetStoreId).storageStatus = false;
+			storageAndRetrieval.getPacketStore(packetStoreId).byTimeRangeRetrievalStatus = false;
+			storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStatus = PacketStore::Suspended;
+		}
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::ChangeTypeToBounded, Message::TC, 1);
+
+		request.appendString(packetStoreIds[0]);
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 0);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[0]).packetStoreType == PacketStore::Bounded);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[1]).packetStoreType == PacketStore::Circular);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).packetStoreType == PacketStore::Circular);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[3]).packetStoreType == PacketStore::Circular);
+
+		Message request2(StorageAndRetrievalService::ServiceType,
+		                 StorageAndRetrievalService::MessageType::ChangeTypeToBounded, Message::TC, 1);
+
+		request2.appendString(packetStoreIds[3]);
+		MessageParser::execute(request2);
+
+		CHECK(ServiceTests::count() == 0);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[0]).packetStoreType == PacketStore::Bounded);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[1]).packetStoreType == PacketStore::Circular);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).packetStoreType == PacketStore::Circular);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[3]).packetStoreType == PacketStore::Bounded);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Failed changing of type to bounded") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto correctPacketStoreIds = validPacketStoreIds();
+		auto wrongPacketStoreIds = invalidPacketStoreIds();
+		padWithZeros(correctPacketStoreIds);
+
+		int count = 0;
+		for (auto& packetStoreId : correctPacketStoreIds) {
+			storageAndRetrieval.getPacketStore(packetStoreId).packetStoreType = PacketStore::Circular;
+			storageAndRetrieval.getPacketStore(packetStoreId).storageStatus = (count == 0);
+			storageAndRetrieval.getPacketStore(packetStoreId).byTimeRangeRetrievalStatus = (count == 1);
+			storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStatus =
+			    (count == 2) ? PacketStore::InProgress : PacketStore::Suspended;
+			count++;
+		}
+
+		String<ECSSPacketStoreIdSize> finalIds[4] = {wrongPacketStoreIds[0], correctPacketStoreIds[0],
+		                                                correctPacketStoreIds[1], correctPacketStoreIds[2]};
+
+		ErrorHandler::ExecutionStartErrorType expectedErrors[4] = {
+		    ErrorHandler::ExecutionStartErrorType::NonExistingPacketStore,
+		    ErrorHandler::ExecutionStartErrorType::GetPacketStoreWithStorageStatusEnabled,
+		    ErrorHandler::ExecutionStartErrorType::GetPacketStoreWithByTimeRangeRetrieval,
+		    ErrorHandler::ExecutionStartErrorType::GetPacketStoreWithOpenRetrievalInProgress};
+
+		for (int i = 0; i < 4; i++) {
+			Message request(StorageAndRetrievalService::ServiceType,
+			                StorageAndRetrievalService::MessageType::ChangeTypeToBounded, Message::TC, 1);
+
+			request.appendString(finalIds[i]);
+			MessageParser::execute(request);
+			CHECK(ServiceTests::count() == i + 1);
+			CHECK(ServiceTests::countThrownErrors(expectedErrors[i]) == 1);
+		}
+
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[0]).packetStoreType == PacketStore::Circular);
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[1]).packetStoreType == PacketStore::Circular);
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[2]).packetStoreType == PacketStore::Circular);
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[3]).packetStoreType == PacketStore::Circular);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Changing the virtual channel of packet stores") {
+	SECTION("Successful change of virtual channel") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		uint8_t virtualChannels[2] = {1, 5};
+
+		for (auto& packetStoreId : packetStoreIds) {
+			storageAndRetrieval.getPacketStore(packetStoreId).byTimeRangeRetrievalStatus = false;
+			storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStatus = PacketStore::Suspended;
+		}
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::ChangeVirtualChannel, Message::TC, 1);
+
+		request.appendString(packetStoreIds[0]);
+		request.appendUint8(virtualChannels[0]);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 0);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[0]).virtualChannel == virtualChannels[0]);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[1]).virtualChannel == 6);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).virtualChannel == 1);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[3]).virtualChannel == 2);
+
+		Message request2(StorageAndRetrievalService::ServiceType,
+		                 StorageAndRetrievalService::MessageType::ChangeVirtualChannel, Message::TC, 1);
+
+		request2.appendString(packetStoreIds[3]);
+		request2.appendUint8(virtualChannels[1]);
+
+		MessageParser::execute(request2);
+
+		CHECK(ServiceTests::count() == 0);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[0]).virtualChannel == virtualChannels[0]);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[1]).virtualChannel == 6);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).virtualChannel == 1);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[3]).virtualChannel == virtualChannels[1]);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Failed change of virtual channel") {
+		initializePacketStores();
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto correctPacketStoreIds = validPacketStoreIds();
+		auto wrongPacketStoreIds = invalidPacketStoreIds();
+		padWithZeros(correctPacketStoreIds);
+
+		uint8_t oldVirtualChannels[4] = {4, 6, 1, 2};
+
+		int count = 0;
+		for (auto& packetStoreId : correctPacketStoreIds) {
+			storageAndRetrieval.getPacketStore(packetStoreId).byTimeRangeRetrievalStatus = (count == 0);
+			storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStatus =
+			    (count == 1) ? PacketStore::InProgress : PacketStore::Suspended;
+			count++;
+		}
+
+		String<ECSSPacketStoreIdSize> finalIds[4] = {wrongPacketStoreIds[0], correctPacketStoreIds[0],
+		                                                correctPacketStoreIds[1], correctPacketStoreIds[2]};
+
+		ErrorHandler::ExecutionStartErrorType expectedErrors[4] = {
+		    ErrorHandler::ExecutionStartErrorType::NonExistingPacketStore,
+		    ErrorHandler::ExecutionStartErrorType::GetPacketStoreWithByTimeRangeRetrieval,
+		    ErrorHandler::ExecutionStartErrorType::GetPacketStoreWithOpenRetrievalInProgress,
+		    ErrorHandler::ExecutionStartErrorType::InvalidVirtualChannel};
+
+		for (int i = 0; i < 4; i++) {
+			Message request(StorageAndRetrievalService::ServiceType,
+			                StorageAndRetrievalService::MessageType::ChangeVirtualChannel, Message::TC, 1);
+
+			request.appendString(finalIds[i]);
+			request.appendUint8(i == 3 ? VirtualChannelLimits.max + 1 : 3);
+			MessageParser::execute(request);
+			CHECK(ServiceTests::count() == i + 1);
+			CHECK(ServiceTests::countThrownErrors(expectedErrors[i]) == 1);
+		}
+
+		int index = 0;
+		for (auto& packetStoreId : correctPacketStoreIds) {
+			REQUIRE(storageAndRetrieval.getPacketStore(packetStoreId).virtualChannel == oldVirtualChannels[index]);
+			index++;
+		}
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Reporting the content summary of packet stores") {
+	SECTION("Successful content summary report of specified packet stores") {
+		initializePacketStores();
+		addTelemetryPacketsInPacketStores();
+
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::ReportContentSummaryOfPacketStores, Message::TC, 1);
+
+		uint16_t numOfPacketStores = 2;
+		request.appendUint16(numOfPacketStores);
+		for (int i = 0; i < numOfPacketStores; i++) {
+			storageAndRetrieval.getPacketStore(packetStoreIds[i]).openRetrievalStartTimeTag = 5;
+			request.appendString(packetStoreIds[i]);
+		}
+
+		uint8_t packetStoreData[ECSSPacketStoreIdSize] = "ps2";
+		uint8_t packetStoreData2[ECSSPacketStoreIdSize] = "ps25";
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 1);
+		Message report = ServiceTests::get(0);
+		REQUIRE(report.messageType == StorageAndRetrievalService::MessageType::PacketStoreContentSummaryReport);
+		REQUIRE(report.readUint16() == 2);
+
+		// Packet store 1
+		uint8_t data[ECSSPacketStoreIdSize];
+		report.readString(data, ECSSPacketStoreIdSize);
+		CHECK(std::equal(std::begin(packetStoreData), std::end(packetStoreData), std::begin(data)));
+		CHECK(report.readUint32() == timestamps1[0]);
+		CHECK(report.readUint32() == timestamps1[5]);
+		CHECK(report.readUint32() == 5);
+		CHECK(report.readUint16() == 30);
+		CHECK(report.readUint16() == 20);
+		// Packet store 2
+		report.readString(data, ECSSPacketStoreIdSize);
+		CHECK(std::equal(std::begin(packetStoreData2), std::end(packetStoreData2), std::begin(data)));
+		CHECK(report.readUint32() == timestamps2[0]);
+		CHECK(report.readUint32() == timestamps2[4]);
+		CHECK(report.readUint32() == 5);
+		CHECK(report.readUint16() == 25);
+		CHECK(report.readUint16() == 10);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Successful content summary report of all packet stores") {
+		initializePacketStores();
+		addTelemetryPacketsInPacketStores();
+
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		int count = 0;
+		for (auto& packetStoreId : packetStoreIds) {
+			storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStartTimeTag = (count == 3) ? 20 : 15;
+			count++;
+		}
+
+		uint8_t packetStoreData[ECSSPacketStoreIdSize] = "ps2";
+		uint8_t packetStoreData2[ECSSPacketStoreIdSize] = "ps25";
+		uint8_t packetStoreData3[ECSSPacketStoreIdSize] = "ps5555";
+		uint8_t packetStoreData4[ECSSPacketStoreIdSize] = "ps799";
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::ReportContentSummaryOfPacketStores, Message::TC, 1);
+
+		uint16_t numOfPacketStores = 0;
+		request.appendUint16(numOfPacketStores);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 1);
+		Message report = ServiceTests::get(0);
+		REQUIRE(report.messageType == StorageAndRetrievalService::MessageType::PacketStoreContentSummaryReport);
+		REQUIRE(report.readUint16() == 4);
+
+		// Packet store 1
+		uint8_t data[ECSSPacketStoreIdSize];
+		report.readString(data, ECSSPacketStoreIdSize);
+		CHECK(std::equal(std::begin(packetStoreData), std::end(packetStoreData), std::begin(data)));
+		CHECK(report.readUint32() == timestamps1[0]);
+		CHECK(report.readUint32() == timestamps1[5]);
+		CHECK(report.readUint32() == 15);
+		CHECK(report.readUint16() == 30);
+		CHECK(report.readUint16() == 0);
+		// Packet store 2
+		report.readString(data, ECSSPacketStoreIdSize);
+		CHECK(std::equal(std::begin(packetStoreData2), std::end(packetStoreData2), std::begin(data)));
+		CHECK(report.readUint32() == timestamps2[0]);
+		CHECK(report.readUint32() == timestamps2[4]);
+		CHECK(report.readUint32() == 15);
+		CHECK(report.readUint16() == 25);
+		CHECK(report.readUint16() == 10);
+		// Packet store 3
+		report.readString(data, ECSSPacketStoreIdSize);
+		CHECK(std::equal(std::begin(packetStoreData3), std::end(packetStoreData3), std::begin(data)));
+		CHECK(report.readUint32() == timestamps4[0]);
+		CHECK(report.readUint32() == timestamps4[7]);
+		CHECK(report.readUint32() == 20);
+		CHECK(report.readUint16() == 40);
+		CHECK(report.readUint16() == 30);
+		// Packet store 4
+		report.readString(data, ECSSPacketStoreIdSize);
+		CHECK(std::equal(std::begin(packetStoreData4), std::end(packetStoreData4), std::begin(data)));
+		CHECK(report.readUint32() == timestamps3[0]);
+		CHECK(report.readUint32() == timestamps3[3]);
+		CHECK(report.readUint32() == 15);
+		CHECK(report.readUint16() == 20);
+		CHECK(report.readUint16() == 0);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Failed content summary report of packet stores") {
+		initializePacketStores();
+		addTelemetryPacketsInPacketStores();
+
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto correctPacketStoreIds = validPacketStoreIds();
+		auto wrongPacketStoreIds = invalidPacketStoreIds();
+		padWithZeros(correctPacketStoreIds);
+
+		String<ECSSPacketStoreIdSize> finalIds[3] = {wrongPacketStoreIds[0], wrongPacketStoreIds[1],
+		                                                correctPacketStoreIds[0]};
+
+		storageAndRetrieval.getPacketStore(correctPacketStoreIds[0]).openRetrievalStartTimeTag = 5;
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::ReportContentSummaryOfPacketStores, Message::TC, 1);
+
+		uint16_t numOfPacketStores = 3;
+		request.appendUint16(numOfPacketStores);
+		for (int i = 0; i < numOfPacketStores; i++) {
+			request.appendString(finalIds[i]);
+		}
+
+		uint8_t packetStoreData[ECSSPacketStoreIdSize] = "ps2";
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 3);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::NonExistingPacketStore) == 2);
+
+		Message report = ServiceTests::get(2);
+		REQUIRE(report.messageType == StorageAndRetrievalService::MessageType::PacketStoreContentSummaryReport);
+		REQUIRE(report.readUint16() == 1);
+
+		// Packet store 1
+		uint8_t data[ECSSPacketStoreIdSize];
+		report.readString(data, ECSSPacketStoreIdSize);
+		CHECK(std::equal(std::begin(packetStoreData), std::end(packetStoreData), std::begin(data)));
+		CHECK(report.readUint32() == timestamps1[0]);
+		CHECK(report.readUint32() == timestamps1[5]);
+		CHECK(report.readUint32() == 5);
+		CHECK(report.readUint16() == 30);
+		CHECK(report.readUint16() == 20);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Deleting packet store content") {
+	SECTION("Successful deletion of content, specified time-tag in the middle of the packets stored") {
+		initializePacketStores();
+		addTelemetryPacketsInPacketStores();
+
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::DeletePacketStoreContent, Message::TC, 1);
+
+		uint32_t storageTime = 5;
+		uint16_t numOfPacketStores = 2;
+		request.appendUint32(storageTime);
+		request.appendUint16(numOfPacketStores);
+
+		for (int i = 0; i < numOfPacketStores; i++) {
+			auto packetStoreId = packetStoreIds[i];
+			storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStatus = PacketStore::Suspended;
+			storageAndRetrieval.getPacketStore(packetStoreId).byTimeRangeRetrievalStatus = false;
+			request.appendString(packetStoreId);
+		}
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[0]).storedTelemetryPackets.size() == 6);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[1]).storedTelemetryPackets.size() == 5);
+
+		MessageParser::execute(request);
+		CHECK(ServiceTests::count() == 0);
+
+		uint32_t expectedTimeStamps1[3] = {7, 9, 11};
+		uint32_t expectedTimeStamps2[2] = {15, 22};
+		uint32_t leftTimeStamps1[3];
+		uint32_t leftTimeStamps2[2];
+
+		int count = 0;
+		for (auto& tmPacket : storageAndRetrieval.getPacketStore(packetStoreIds[0]).storedTelemetryPackets) {
+			leftTimeStamps1[count++] = tmPacket.first;
+		}
+		count = 0;
+		for (auto& tmPacket : storageAndRetrieval.getPacketStore(packetStoreIds[1]).storedTelemetryPackets) {
+			leftTimeStamps2[count++] = tmPacket.first;
+		}
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[0]).storedTelemetryPackets.size() == 3);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[1]).storedTelemetryPackets.size() == 2);
+		REQUIRE(
+		    std::equal(std::begin(expectedTimeStamps1), std::end(expectedTimeStamps1), std::begin(leftTimeStamps1)));
+		REQUIRE(
+		    std::equal(std::begin(expectedTimeStamps2), std::end(expectedTimeStamps2), std::begin(leftTimeStamps2)));
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Successful deletion of content, specified time-tag is smaller than the min stored timestamp") {
+		initializePacketStores();
+		addTelemetryPacketsInPacketStores();
+
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::DeletePacketStoreContent, Message::TC, 1);
+
+		uint32_t storageTime = 3;
+		uint16_t numOfPacketStores = 2;
+		request.appendUint32(storageTime);
+		request.appendUint16(numOfPacketStores);
+
+		for (int i = 2; i < numOfPacketStores + 2; i++) {
+			auto packetStoreId = packetStoreIds[i];
+			storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStatus = PacketStore::Suspended;
+			storageAndRetrieval.getPacketStore(packetStoreId).byTimeRangeRetrievalStatus = false;
+			request.appendString(packetStoreId);
+		}
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.size() == 4);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[3]).storedTelemetryPackets.size() == 8);
+
+		MessageParser::execute(request);
+		CHECK(ServiceTests::count() == 0);
+
+		uint32_t expectedTimeStamps1[4] = {4, 7, 9, 14};
+		uint32_t expectedTimeStamps2[8] = {4, 6, 34, 40, 44, 51, 52, 58};
+		uint32_t leftTimeStamps1[4];
+		uint32_t leftTimeStamps2[8];
+
+		int count = 0;
+		for (auto& tmPacket : storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets) {
+			leftTimeStamps1[count++] = tmPacket.first;
+		}
+		count = 0;
+		for (auto& tmPacket : storageAndRetrieval.getPacketStore(packetStoreIds[3]).storedTelemetryPackets) {
+			leftTimeStamps2[count++] = tmPacket.first;
+		}
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.size() == 4);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[3]).storedTelemetryPackets.size() == 8);
+		REQUIRE(
+		    std::equal(std::begin(expectedTimeStamps1), std::end(expectedTimeStamps1), std::begin(leftTimeStamps1)));
+		REQUIRE(
+		    std::equal(std::begin(expectedTimeStamps2), std::end(expectedTimeStamps2), std::begin(leftTimeStamps2)));
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Successful deletion of content, specified time-tag is larger than the max stored timestamp") {
+		initializePacketStores();
+		addTelemetryPacketsInPacketStores();
+
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::DeletePacketStoreContent, Message::TC, 1);
+
+		uint32_t storageTime = 59;
+		uint16_t numOfPacketStores = 2;
+		request.appendUint32(storageTime);
+		request.appendUint16(numOfPacketStores);
+
+		for (int i = 2; i < numOfPacketStores + 2; i++) {
+			auto packetStoreId = packetStoreIds[i];
+			storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStatus = PacketStore::Suspended;
+			storageAndRetrieval.getPacketStore(packetStoreId).byTimeRangeRetrievalStatus = false;
+			request.appendString(packetStoreId);
+		}
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.size() == 4);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[3]).storedTelemetryPackets.size() == 8);
+
+		MessageParser::execute(request);
+		CHECK(ServiceTests::count() == 0);
+
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.empty());
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[3]).storedTelemetryPackets.empty());
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Both successful and failed deletion of content for all packet stores") {
+		initializePacketStores();
+		addTelemetryPacketsInPacketStores();
+
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::DeletePacketStoreContent, Message::TC, 1);
+
+		uint32_t storageTime = 15;
+		uint16_t numOfPacketStores = 0;
+		request.appendUint32(storageTime);
+		request.appendUint16(numOfPacketStores);
+
+		int count = 0;
+		for (auto& packetStoreId : packetStoreIds) {
+			storageAndRetrieval.getPacketStore(packetStoreId).byTimeRangeRetrievalStatus = (count == 0);
+			storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStatus =
+			    (count == 1) ? PacketStore::InProgress : PacketStore::Suspended;
+			count++;
+		}
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[0]).storedTelemetryPackets.size() == 6);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[1]).storedTelemetryPackets.size() == 5);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.size() == 4);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[3]).storedTelemetryPackets.size() == 8);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 2);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::SetPacketStoreWithByTimeRangeRetrieval) == 1);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::SetPacketStoreWithOpenRetrievalInProgress) == 1);
+
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[0]).storedTelemetryPackets.size() == 6);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[1]).storedTelemetryPackets.size() == 5);
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.empty());
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[3]).storedTelemetryPackets.size() == 6);
+
+		uint32_t expectedTimeStamps1[6] = {2, 4, 5, 7, 9, 11};
+		uint32_t expectedTimeStamps2[5] = {0, 1, 4, 15, 22};
+		uint32_t expectedTimeStamps4[6] = {34, 40, 44, 51, 52, 58};
+
+		uint32_t leftTimeStamps1[6];
+		uint32_t leftTimeStamps2[5];
+		uint32_t leftTimeStamps4[6];
+
+		count = 0;
+		for (auto& tmPacket : storageAndRetrieval.getPacketStore(packetStoreIds[0]).storedTelemetryPackets) {
+			leftTimeStamps1[count++] = tmPacket.first;
+		}
+		count = 0;
+		for (auto& tmPacket : storageAndRetrieval.getPacketStore(packetStoreIds[1]).storedTelemetryPackets) {
+			leftTimeStamps2[count++] = tmPacket.first;
+		}
+		count = 0;
+		for (auto& tmPacket : storageAndRetrieval.getPacketStore(packetStoreIds[3]).storedTelemetryPackets) {
+			leftTimeStamps4[count++] = tmPacket.first;
+		}
+
+		REQUIRE(
+		    std::equal(std::begin(expectedTimeStamps1), std::end(expectedTimeStamps1), std::begin(leftTimeStamps1)));
+		REQUIRE(
+		    std::equal(std::begin(expectedTimeStamps2), std::end(expectedTimeStamps2), std::begin(leftTimeStamps2)));
+		REQUIRE(
+		    std::equal(std::begin(expectedTimeStamps4), std::end(expectedTimeStamps4), std::begin(leftTimeStamps4)));
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Failed deletion of content") {
+		initializePacketStores();
+		addTelemetryPacketsInPacketStores();
+
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto correctPacketStoreIds = validPacketStoreIds();
+		auto wrongPacketStoreIds = invalidPacketStoreIds();
+		padWithZeros(correctPacketStoreIds);
+
+		String<ECSSPacketStoreIdSize> finalIds[7] = {
+		    wrongPacketStoreIds[0],   wrongPacketStoreIds[1],   wrongPacketStoreIds[2],  correctPacketStoreIds[0],
+		    correctPacketStoreIds[1], correctPacketStoreIds[2], correctPacketStoreIds[3]};
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::DeletePacketStoreContent, Message::TC, 1);
+
+		uint32_t storageTime = 59;
+		uint16_t numOfPacketStores = 7;
+		request.appendUint32(storageTime);
+		request.appendUint16(numOfPacketStores);
+
+		for (int i = 0; i < 3; i++) {
+			auto packetStoreId = finalIds[i];
+			request.appendString(packetStoreId);
+		}
+
+		for (int i = 3; i < 7; i++) {
+			auto packetStoreId = finalIds[i];
+			storageAndRetrieval.getPacketStore(packetStoreId).byTimeRangeRetrievalStatus = (i == 4 || i == 6);
+			storageAndRetrieval.getPacketStore(packetStoreId).openRetrievalStatus =
+			    (i == 3 || i == 5) ? PacketStore::InProgress : PacketStore::Suspended;
+			request.appendString(packetStoreId);
+		}
+
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[0]).storedTelemetryPackets.size() == 6);
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[1]).storedTelemetryPackets.size() == 5);
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[2]).storedTelemetryPackets.size() == 4);
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[3]).storedTelemetryPackets.size() == 8);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 7);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::NonExistingPacketStore) == 3);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::SetPacketStoreWithByTimeRangeRetrieval) == 2);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::SetPacketStoreWithOpenRetrievalInProgress) == 2);
+
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[0]).storedTelemetryPackets.size() == 6);
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[1]).storedTelemetryPackets.size() == 5);
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[2]).storedTelemetryPackets.size() == 4);
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[3]).storedTelemetryPackets.size() == 8);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Copying packets in time window, from tag to tag") {
+	SECTION("Both time-tags earlier than the earliest time-tag") {
+		/**
+		 * CASE 0:
+		 *
+		 * 	(tag1)-------(tag2)-------(earliest packet timestamp)-----(..more packets..)-----(latest packet timestamp)
+		 * 				              left-most packet in deque	     tag2 somewhere inside   right-most packet in deque
+		 */
+		initializePacketStores();
+		addTelemetryPacketsInPacketStores();
+
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		// Empty the target packet store, so the copy can occur
+		storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.clear();
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.empty());
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::CopyPacketsInTimeWindow, Message::TC, 1);
+
+		uint8_t typeOfTimeWindow = StorageAndRetrievalService::TimeWindowType::FromTagToTag;
+		uint32_t timeTag1 = 0;
+		uint32_t timeTag2 = 1;
+		auto fromPacketStoreId = packetStoreIds[0];
+		auto toPacketStoreId = packetStoreIds[2];
+
+		request.appendEnum8(typeOfTimeWindow);
+		request.appendUint32(timeTag1);
+		request.appendUint32(timeTag2);
+		request.appendString(fromPacketStoreId);
+		request.appendString(toPacketStoreId);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 1);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::CopyOfPacketsFailed) == 1);
+		auto& targetPacketStore = storageAndRetrieval.getPacketStore(toPacketStoreId);
+		REQUIRE(targetPacketStore.storedTelemetryPackets.empty());
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Time-tag1 earlier than the earliest stored time-tag, and time-tag2 in between the existing ones") {
+		/**
+		 * CASE 1:
+		 *
+		 * 	(tag1)--------(earliest packet timestamp)-----(..more packets..)-----(tag2)--------(latest packet timestamp)
+		 * 				left-most packet in deque				tag2 somewhere inside		right-most packet in deque
+		 */
+		initializePacketStores();
+		addTelemetryPacketsInPacketStores();
+
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		// Empty the target packet store, so the copy can occur
+		storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.clear();
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.empty());
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::CopyPacketsInTimeWindow, Message::TC, 1);
+
+		uint8_t typeOfTimeWindow = StorageAndRetrievalService::TimeWindowType::FromTagToTag;
+		uint32_t timeTag1 = 0;
+		uint32_t timeTag2 = 4;
+		auto fromPacketStoreId = packetStoreIds[0];
+		auto toPacketStoreId = packetStoreIds[2];
+
+		request.appendEnum8(typeOfTimeWindow);
+		request.appendUint32(timeTag1);
+		request.appendUint32(timeTag2);
+		request.appendString(fromPacketStoreId);
+		request.appendString(toPacketStoreId);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 0);
+		auto& targetPacketStore = storageAndRetrieval.getPacketStore(toPacketStoreId);
+		REQUIRE(targetPacketStore.storedTelemetryPackets.size() == 2);
+		int index = 0;
+		for (auto& tmPacket : targetPacketStore.storedTelemetryPackets) {
+			REQUIRE(tmPacket.first == timestamps1[index++]);
+		}
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Both time-tags in between the stored timestamps") {
+		/**
+		 * CASE 2:
+		 *
+		 * 	(earlier packet timestamp)-------(tag1)-----(..more packets)-----(tag2)--------(latest packet timestamp)
+		 * 	left-most packet in deque						both tag1 and tag2 inside 		right-most packet in deque
+		 */
+		initializePacketStores();
+		addTelemetryPacketsInPacketStores();
+
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		// Empty the target packet store, so the copy can occur
+		storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.clear();
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.empty());
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::CopyPacketsInTimeWindow, Message::TC, 1);
+
+		uint8_t typeOfTimeWindow = StorageAndRetrievalService::TimeWindowType::FromTagToTag;
+		uint32_t timeTag1 = 35;
+		uint32_t timeTag2 = 52;
+		auto fromPacketStoreId = packetStoreIds[3];
+		auto toPacketStoreId = packetStoreIds[2];
+
+		request.appendEnum8(typeOfTimeWindow);
+		request.appendUint32(timeTag1);
+		request.appendUint32(timeTag2);
+		request.appendString(fromPacketStoreId);
+		request.appendString(toPacketStoreId);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 0);
+		auto& targetPacketStore = storageAndRetrieval.getPacketStore(toPacketStoreId);
+		REQUIRE(targetPacketStore.storedTelemetryPackets.size() == 4);
+		int index = 3;
+		for (auto& tmPacket : targetPacketStore.storedTelemetryPackets) {
+			REQUIRE(tmPacket.first == timestamps4[index++]);
+		}
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Time-tag1 in between the stored timestamps and tag2 larger than the max timestamp") {
+		/**
+		 * CASE 3:
+		 *
+		 * 	(earlier packet timestamp)-------(tag1)-----(..more packets)-----(latest packet timestamp)--------(tag2)
+		 * 	left-most packet in deque		tag1 inside						right-most packet in deque
+		 */
+		initializePacketStores();
+		addTelemetryPacketsInPacketStores();
+
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		// Empty the target packet store, so the copy can occur
+		storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.clear();
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.empty());
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::CopyPacketsInTimeWindow, Message::TC, 1);
+
+		uint8_t typeOfTimeWindow = StorageAndRetrievalService::TimeWindowType::FromTagToTag;
+		uint32_t timeTag1 = 3;
+		uint32_t timeTag2 = 27;
+		auto fromPacketStoreId = packetStoreIds[1];
+		auto toPacketStoreId = packetStoreIds[2];
+
+		request.appendEnum8(typeOfTimeWindow);
+		request.appendUint32(timeTag1);
+		request.appendUint32(timeTag2);
+		request.appendString(fromPacketStoreId);
+		request.appendString(toPacketStoreId);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 0);
+		auto& targetPacketStore = storageAndRetrieval.getPacketStore(toPacketStoreId);
+		REQUIRE(targetPacketStore.storedTelemetryPackets.size() == 3);
+		int index = 2;
+		for (auto& tmPacket : targetPacketStore.storedTelemetryPackets) {
+			REQUIRE(tmPacket.first == timestamps2[index++]);
+		}
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Both time-tags larger than largest stored time-tag") {
+		/**
+		 * CASE 4:
+		 *
+		 * 	(earliest packet timestamp)-----(..more packets..)-----(latest packet timestamp)-----(tag1)-------(tag2)
+		 *   left-most packet in deque	     tag2 somewhere inside   right-most packet in deque
+		 */
+		initializePacketStores();
+		addTelemetryPacketsInPacketStores();
+
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		// Empty the target packet store, so the copy can occur
+		storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.clear();
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.empty());
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::CopyPacketsInTimeWindow, Message::TC, 1);
+
+		uint8_t typeOfTimeWindow = StorageAndRetrievalService::TimeWindowType::FromTagToTag;
+		uint32_t timeTag1 = 12;
+		uint32_t timeTag2 = 14;
+		auto fromPacketStoreId = packetStoreIds[0];
+		auto toPacketStoreId = packetStoreIds[2];
+
+		request.appendEnum8(typeOfTimeWindow);
+		request.appendUint32(timeTag1);
+		request.appendUint32(timeTag2);
+		request.appendString(fromPacketStoreId);
+		request.appendString(toPacketStoreId);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 1);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::CopyOfPacketsFailed) == 1);
+		auto& targetPacketStore = storageAndRetrieval.getPacketStore(toPacketStoreId);
+		REQUIRE(targetPacketStore.storedTelemetryPackets.empty());
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Invalid packet store requested") {
+		initializePacketStores();
+		addTelemetryPacketsInPacketStores();
+
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto correctPacketStoreIds = validPacketStoreIds();
+		auto wrongPacketStoreIds = invalidPacketStoreIds();
+		padWithZeros(correctPacketStoreIds);
+
+		// Empty the target packet store, so the copy can occur
+		storageAndRetrieval.getPacketStore(correctPacketStoreIds[2]).storedTelemetryPackets.clear();
+		REQUIRE(storageAndRetrieval.getPacketStore(correctPacketStoreIds[2]).storedTelemetryPackets.empty());
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::CopyPacketsInTimeWindow, Message::TC, 1);
+
+		uint8_t typeOfTimeWindow = StorageAndRetrievalService::TimeWindowType::FromTagToTag;
+		uint32_t timeTag1 = 3;
+		uint32_t timeTag2 = 27;
+		auto fromPacketStoreId = wrongPacketStoreIds[0];
+		auto toPacketStoreId = correctPacketStoreIds[2];
+
+		request.appendEnum8(typeOfTimeWindow);
+		request.appendUint32(timeTag1);
+		request.appendUint32(timeTag2);
+		request.appendString(fromPacketStoreId);
+		request.appendString(toPacketStoreId);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 1);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::NonExistingPacketStore) == 1);
+		REQUIRE(storageAndRetrieval.getPacketStore(toPacketStoreId).storedTelemetryPackets.empty());
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Invalid time window requested") {
+		initializePacketStores();
+		addTelemetryPacketsInPacketStores();
+
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		// Empty the target packet store, so the copy can occur
+		storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.clear();
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.empty());
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::CopyPacketsInTimeWindow, Message::TC, 1);
+
+		uint8_t typeOfTimeWindow = StorageAndRetrievalService::TimeWindowType::FromTagToTag;
+		uint32_t timeTag1 = 26;
+		uint32_t timeTag2 = 17;
+		auto fromPacketStoreId = packetStoreIds[0];
+		auto toPacketStoreId = packetStoreIds[2];
+
+		request.appendEnum8(typeOfTimeWindow);
+		request.appendUint32(timeTag1);
+		request.appendUint32(timeTag2);
+		request.appendString(fromPacketStoreId);
+		request.appendString(toPacketStoreId);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 1);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::InvalidTimeWindow) == 1);
+		REQUIRE(storageAndRetrieval.getPacketStore(toPacketStoreId).storedTelemetryPackets.empty());
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Destination packet not empty") {
+		initializePacketStores();
+		addTelemetryPacketsInPacketStores();
+
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		REQUIRE(not storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.empty());
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::CopyPacketsInTimeWindow, Message::TC, 1);
+
+		uint8_t typeOfTimeWindow = StorageAndRetrievalService::TimeWindowType::FromTagToTag;
+		uint32_t timeTag1 = 3;
+		uint32_t timeTag2 = 7;
+		auto fromPacketStoreId = packetStoreIds[0];
+		auto toPacketStoreId = packetStoreIds[2];
+
+		request.appendEnum8(typeOfTimeWindow);
+		request.appendUint32(timeTag1);
+		request.appendUint32(timeTag2);
+		request.appendString(fromPacketStoreId);
+		request.appendString(toPacketStoreId);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 1);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::DestinationPacketStoreNotEmtpy) == 1);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("No packets contained into the requested time-window") {
+		initializePacketStores();
+		addTelemetryPacketsInPacketStores();
+
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		// Empty the target packet store, so the copy can occur
+		storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.clear();
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.empty());
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::CopyPacketsInTimeWindow, Message::TC, 1);
+
+		uint8_t typeOfTimeWindow = StorageAndRetrievalService::TimeWindowType::FromTagToTag;
+		uint32_t timeTag1 = 0;
+		uint32_t timeTag2 = 3;
+		auto fromPacketStoreId = packetStoreIds[3];
+		auto toPacketStoreId = packetStoreIds[2];
+
+		request.appendEnum8(typeOfTimeWindow);
+		request.appendUint32(timeTag1);
+		request.appendUint32(timeTag2);
+		request.appendString(fromPacketStoreId);
+		request.appendString(toPacketStoreId);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 1);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::CopyOfPacketsFailed) == 1);
+		CHECK(storageAndRetrieval.getPacketStore(toPacketStoreId).storedTelemetryPackets.empty());
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Copying packets in time window, after time-tag") {
+	SECTION("Time-tag in between the stored time-tags") {
+		initializePacketStores();
+		addTelemetryPacketsInPacketStores();
+
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		// Empty the target packet store, so the copy can occur
+		storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.clear();
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.empty());
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::CopyPacketsInTimeWindow, Message::TC, 1);
+
+		uint8_t typeOfTimeWindow = StorageAndRetrievalService::TimeWindowType::AfterTimeTag;
+		uint32_t timeTag1 = 6;
+		auto fromPacketStoreId = packetStoreIds[0];
+		auto toPacketStoreId = packetStoreIds[2];
+
+		request.appendEnum8(typeOfTimeWindow);
+		request.appendUint32(timeTag1);
+		request.appendString(fromPacketStoreId);
+		request.appendString(toPacketStoreId);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 0);
+		auto& targetPacketStore = storageAndRetrieval.getPacketStore(toPacketStoreId);
+		REQUIRE(targetPacketStore.storedTelemetryPackets.size() == 3);
+		uint32_t expectedTimestamps[3] = {7, 9, 11};
+		uint32_t existingTimestamps[3];
+
+		int index = 0;
+		for (auto& tmPacket : targetPacketStore.storedTelemetryPackets) {
+			existingTimestamps[index++] = tmPacket.first;
+		}
+		REQUIRE(
+		    std::equal(std::begin(expectedTimestamps), std::end(expectedTimestamps), std::begin(existingTimestamps)));
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Time-tag earlier than the earliest stored time-tag") {
+		initializePacketStores();
+		addTelemetryPacketsInPacketStores();
+
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		// Empty the target packet store, so the copy can occur
+		storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.clear();
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.empty());
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::CopyPacketsInTimeWindow, Message::TC, 1);
+
+		uint8_t typeOfTimeWindow = StorageAndRetrievalService::TimeWindowType::AfterTimeTag;
+		uint32_t timeTag1 = 1;
+		auto fromPacketStoreId = packetStoreIds[0];
+		auto toPacketStoreId = packetStoreIds[2];
+
+		request.appendEnum8(typeOfTimeWindow);
+		request.appendUint32(timeTag1);
+		request.appendString(fromPacketStoreId);
+		request.appendString(toPacketStoreId);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 0);
+		auto& targetPacketStore = storageAndRetrieval.getPacketStore(toPacketStoreId);
+		REQUIRE(targetPacketStore.storedTelemetryPackets.size() == 6);
+		uint32_t existingTimestamps[6];
+
+		int index = 0;
+		for (auto& tmPacket : targetPacketStore.storedTelemetryPackets) {
+			existingTimestamps[index++] = tmPacket.first;
+		}
+		REQUIRE(std::equal(std::begin(timestamps1), std::end(timestamps1), std::begin(existingTimestamps)));
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Time-tag larger than the largest stored time-tag") {
+		initializePacketStores();
+		addTelemetryPacketsInPacketStores();
+
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		// Empty the target packet store, so the copy can occur
+		storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.clear();
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.empty());
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::CopyPacketsInTimeWindow, Message::TC, 1);
+
+		uint8_t typeOfTimeWindow = StorageAndRetrievalService::TimeWindowType::AfterTimeTag;
+		uint32_t timeTag1 = 25;
+		auto fromPacketStoreId = packetStoreIds[0];
+		auto toPacketStoreId = packetStoreIds[2];
+
+		request.appendEnum8(typeOfTimeWindow);
+		request.appendUint32(timeTag1);
+		request.appendString(fromPacketStoreId);
+		request.appendString(toPacketStoreId);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 1);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::CopyOfPacketsFailed) == 1);
+		auto& targetPacketStore = storageAndRetrieval.getPacketStore(toPacketStoreId);
+		REQUIRE(targetPacketStore.storedTelemetryPackets.empty());
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Copying packets in time window, before time-tag") {
+	SECTION("Time-tag in between the stored time-tags") {
+		initializePacketStores();
+		addTelemetryPacketsInPacketStores();
+
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		// Empty the target packet store, so the copy can occur
+		storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.clear();
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.empty());
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::CopyPacketsInTimeWindow, Message::TC, 1);
+
+		uint8_t typeOfTimeWindow = StorageAndRetrievalService::TimeWindowType::BeforeTimeTag;
+		uint32_t timeTag2 = 6;
+		auto fromPacketStoreId = packetStoreIds[0];
+		auto toPacketStoreId = packetStoreIds[2];
+
+		request.appendEnum8(typeOfTimeWindow);
+		request.appendUint32(timeTag2);
+		request.appendString(fromPacketStoreId);
+		request.appendString(toPacketStoreId);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 0);
+		auto& targetPacketStore = storageAndRetrieval.getPacketStore(toPacketStoreId);
+		REQUIRE(targetPacketStore.storedTelemetryPackets.size() == 3);
+		uint32_t expectedTimestamps[3] = {2, 4, 5};
+		uint32_t existingTimestamps[3];
+
+		int index = 0;
+		for (auto& tmPacket : targetPacketStore.storedTelemetryPackets) {
+			existingTimestamps[index++] = tmPacket.first;
+		}
+		REQUIRE(
+		    std::equal(std::begin(expectedTimestamps), std::end(expectedTimestamps), std::begin(existingTimestamps)));
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Time-tag larger than the largest stored time-tag") {
+		initializePacketStores();
+		addTelemetryPacketsInPacketStores();
+
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		// Empty the target packet store, so the copy can occur
+		storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.clear();
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.empty());
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::CopyPacketsInTimeWindow, Message::TC, 1);
+
+		uint8_t typeOfTimeWindow = StorageAndRetrievalService::TimeWindowType::BeforeTimeTag;
+		uint32_t timeTag2 = 56;
+		auto fromPacketStoreId = packetStoreIds[0];
+		auto toPacketStoreId = packetStoreIds[2];
+
+		request.appendEnum8(typeOfTimeWindow);
+		request.appendUint32(timeTag2);
+		request.appendString(fromPacketStoreId);
+		request.appendString(toPacketStoreId);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 0);
+		auto& targetPacketStore = storageAndRetrieval.getPacketStore(toPacketStoreId);
+		REQUIRE(targetPacketStore.storedTelemetryPackets.size() == 6);
+		uint32_t existingTimestamps[6];
+
+		int index = 0;
+		for (auto& tmPacket : targetPacketStore.storedTelemetryPackets) {
+			existingTimestamps[index++] = tmPacket.first;
+		}
+		REQUIRE(std::equal(std::begin(timestamps1), std::end(timestamps1), std::begin(existingTimestamps)));
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Time-tag earlier than the earliest stored time-tag") {
+		initializePacketStores();
+		addTelemetryPacketsInPacketStores();
+
+		REQUIRE(storageAndRetrieval.currentNumberOfPacketStores() == 4);
+		auto packetStoreIds = validPacketStoreIds();
+		padWithZeros(packetStoreIds);
+
+		// Empty the target packet store, so the copy can occur
+		storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.clear();
+		REQUIRE(storageAndRetrieval.getPacketStore(packetStoreIds[2]).storedTelemetryPackets.empty());
+
+		Message request(StorageAndRetrievalService::ServiceType,
+		                StorageAndRetrievalService::MessageType::CopyPacketsInTimeWindow, Message::TC, 1);
+
+		uint8_t typeOfTimeWindow = StorageAndRetrievalService::TimeWindowType::BeforeTimeTag;
+		uint32_t timeTag2 = 1;
+		auto fromPacketStoreId = packetStoreIds[0];
+		auto toPacketStoreId = packetStoreIds[2];
+
+		request.appendEnum8(typeOfTimeWindow);
+		request.appendUint32(timeTag2);
+		request.appendString(fromPacketStoreId);
+		request.appendString(toPacketStoreId);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 1);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::CopyOfPacketsFailed) == 1);
+		auto& targetPacketStore = storageAndRetrieval.getPacketStore(toPacketStoreId);
+		REQUIRE(targetPacketStore.storedTelemetryPackets.empty());
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}