From 27189a2098165742cee3aae2979e84e263a8f516 Mon Sep 17 00:00:00 2001
From: Dimitrios Stoupis <dimitris.apple@gmail.com>
Date: Wed, 21 Nov 2018 10:54:59 +0000
Subject: [PATCH] Fully implemented the loadRawData subservice and added some
 error checkings

- Added service assertions to check if the correct packet is received
- Fully implemented the loadRawData function, with passing tests
- Tests to follow
---
 src/Services/MemMangService.cpp | 55 ++++++++++++++++++++++++++-------
 src/main.cpp                    | 20 +++++++++++-
 2 files changed, 62 insertions(+), 13 deletions(-)

diff --git a/src/Services/MemMangService.cpp b/src/Services/MemMangService.cpp
index d5c54539..fddf19a7 100644
--- a/src/Services/MemMangService.cpp
+++ b/src/Services/MemMangService.cpp
@@ -12,7 +12,7 @@ MemoryManagementService::RawDataMemoryManagement::RawDataMemoryManagement(
 
 
 // Function declarations for the raw data memory management subservice
-//void MemoryManagementService::RawDataMemoryManagement::loadRawData(Message &request) {
+void MemoryManagementService::RawDataMemoryManagement::loadRawData(Message &request) {
 	/**
 	 * Bare in mind that there is currently no error checking for invalid parameters.
 	 * A future version will include error checking and the corresponding error report/notification,
@@ -21,25 +21,56 @@ MemoryManagementService::RawDataMemoryManagement::RawDataMemoryManagement(
 	 * @todo Add error checking and reporting for the parameters
 	 * @todo Add failure reporting
 	 */
-	/*uint8_t memoryID = request.readEnum8(); // Read the memory ID from the request
-	uint8_t iterationCount = 0; // Get the iteration count
+	// Check if we have the correct packet
+	assert(request.serviceType == 6);
+	assert(request.messageType == 2);
+
+	uint8_t memoryID = request.readEnum8(); // Read the memory ID from the request
+
+	// Variable declaration
+	uint8_t *readData = nullptr; // Pointer to store the data read from the memory
+	uint16_t iterationCount = 0; // Get the iteration count
 	uint16_t dataLength = 0; // Data length to read (updated for each new iteration)
-	uint32_t startAddress = 0; // Start address for the memory read (updated in each new iteration)
+	uint16_t allocatedLength = 0; // Length allocated for the readData array
+	uint64_t startAddress = 0; // Start address for the memory read (updated in each new iteration)
 
 	// Read the packet's values
-	iterationCount = request.readUint8();
-	startAddress = request.readUint32();
+	iterationCount = request.readUint16();
 
 	if (memoryID == MemoryManagementService::MemoryID::RAM) {
-		for (std::size_t i = 0; i < dataLength; i++) {
-			//\*(uint64_t *)startAddress = memoryData[i];
+		for (std::size_t j =0; j < iterationCount; j++) {
+			startAddress = request.readUint64(); // Start address of the memory
+			dataLength = request.readUint16(); // Data length to append
+
+			// Allocate more array space if needed
+			if (allocatedLength < dataLength) {
+				readData = static_cast<uint8_t *>(realloc(readData, dataLength));
+				if (readData == nullptr) {
+					// todo: Add error logging and reporting
+					free(readData);
+					return;
+				}
+			}
+
+			for (std::size_t i = 0; i < dataLength; i++) {
+				readData[i] = request.readByte();
+			}
+			// todo: Continue only if the checksum passes (when the checksum will be implemented)
+
+			for (std::size_t i = 0; i < dataLength; i++) {
+				*(reinterpret_cast<uint8_t *>(startAddress) + i) = readData[i];
+			}
 		}
 	} else if (memoryID == MemoryManagementService::MemoryID::FLASH) {
-
+		// todo: Define FLASH specific access code when we transfer to embedded
 	}
-}*/
+}
 
 void MemoryManagementService::RawDataMemoryManagement::dumpRawData(Message &request) {
+	// Check if we have the correct packet
+	assert(request.serviceType == 6);
+	assert(request.messageType == 5);
+
 	// Create the report message object of telemetry message subtype 6
 	Message report = mainService->createTM(6);
 
@@ -68,7 +99,7 @@ void MemoryManagementService::RawDataMemoryManagement::dumpRawData(Message &requ
 		// Allocate more array space if needed
 		if (allocatedLength < readLength) {
 			readData = static_cast<uint8_t *>(realloc(readData, readLength));
-			if (!readData) {
+			if (readData == nullptr) {
 				// todo: Add error logging and reporting
 				free(readData);
 				return;
@@ -88,6 +119,6 @@ void MemoryManagementService::RawDataMemoryManagement::dumpRawData(Message &requ
 	// todo: implement and append the checksum part of the reporting packet
 
 	mainService->storeMessage(report); // Save the report message
-	report.resetRead(); // Reset the reading count
+	request.resetRead(); // Reset the reading count
 	free(readData); // Free the allocated memory
 }
diff --git a/src/main.cpp b/src/main.cpp
index 4cd9a8ed..ff81c0a6 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -31,8 +31,12 @@ int main() {
 	// ST[06] testing
 	char anotherStr[8] = "Fgthred";
 	char yetAnotherStr[2] = "F";
+	char *pStr = static_cast<char *>(malloc(4));
+	*pStr = 'T';
+	*(pStr + 1) = 'G';
+	*(pStr + 2) = '\0';
 	MemoryManagementService memMangService;
-	Message rcvPack = Message(6, 2, Message::TC, 1);
+	Message rcvPack = Message(6, 5, Message::TC, 1);
 	rcvPack.appendEnum8(MemoryManagementService::MemoryID::RAM); // Memory ID
 	rcvPack.appendUint16(3); // Iteration count
 	rcvPack.appendUint64(reinterpret_cast<uint64_t >(string)); // Start address
@@ -46,5 +50,19 @@ int main() {
 
 	memMangService.rawDataMemorySubservice.dumpRawData(rcvPack);
 
+	rcvPack = Message(6, 2, Message::TC, 1);
+	uint8_t data[2] = {'h', 'R'};
+	rcvPack.appendEnum8(MemoryManagementService::MemoryID::RAM); // Memory ID
+	rcvPack.appendUint16(2); // Iteration count
+	rcvPack.appendUint64(reinterpret_cast<uint64_t >(pStr)); // Start address
+	rcvPack.appendUint16(2); // Data length to append
+	rcvPack.appendOctetString(2, data);
+	rcvPack.appendUint64(reinterpret_cast<uint64_t >(pStr + 1)); // Start address
+	rcvPack.appendUint16(1);
+	rcvPack.appendOctetString(1, data);
+	memMangService.rawDataMemorySubservice.loadRawData(rcvPack);
+
+	std::cout << pStr << std::endl;
+
 	return 0;
 }
-- 
GitLab