From 31bee53bedd390577865be1780126a50ede65a48 Mon Sep 17 00:00:00 2001
From: Sedictious <ele.hatzy@gmail.com>
Date: Tue, 11 Aug 2020 22:45:27 +0300
Subject: [PATCH] Append CRC to packets

---
 inc/ECSS_Definitions.hpp |  6 ++++++
 src/MessageParser.cpp    |  9 +++++++++
 test/MessageParser.cpp   | 20 +++++++++++++++++++-
 3 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/inc/ECSS_Definitions.hpp b/inc/ECSS_Definitions.hpp
index a8523462..14e36fa0 100644
--- a/inc/ECSS_Definitions.hpp
+++ b/inc/ECSS_Definitions.hpp
@@ -145,4 +145,10 @@
  * @brief Size of the array holding the Parameter objects for the ST[20] parameter service
  */
 #define ECSS_PARAMETER_COUNT 3
+
+/**
+ * @brief Defines whether the optional CRC field is included
+ */
+#define ECSS_CRC_INCLUDE true
+
 #endif // ECSS_SERVICES_ECSS_DEFINITIONS_H
diff --git a/src/MessageParser.cpp b/src/MessageParser.cpp
index b4eb3953..15849da9 100644
--- a/src/MessageParser.cpp
+++ b/src/MessageParser.cpp
@@ -5,6 +5,7 @@
 #include "macros.hpp"
 #include "Services/TestService.hpp"
 #include "Services/RequestVerificationService.hpp"
+#include "Helpers/CRCHelper.hpp"
 
 void MessageParser::execute(Message& message) {
 	switch (message.serviceType) {
@@ -194,6 +195,14 @@ String<CCSDS_MAX_MESSAGE_SIZE> MessageParser::compose(const Message& message) {
 	String<CCSDS_MAX_MESSAGE_SIZE> ccsdsMessage(header, 6);
 	ccsdsMessage.append(ecssMessage);
 
+#if ECSS_CRC_INCLUDE
+	// Append CRC field
+	uint16_t crcField = CRCHelper::calculateCRC(reinterpret_cast<uint8_t*>(ccsdsMessage.data()), 6 +
+	packetDataLength);
+	ccsdsMessage.push_back(static_cast<uint8_t>(crcField >> 8U));
+	ccsdsMessage.push_back(static_cast<uint8_t>(crcField & 0xFF));
+#endif
+
 	return ccsdsMessage;
 }
 
diff --git a/test/MessageParser.cpp b/test/MessageParser.cpp
index c416f1b5..108224ab 100644
--- a/test/MessageParser.cpp
+++ b/test/MessageParser.cpp
@@ -3,6 +3,7 @@
 #include <Services/RequestVerificationService.hpp>
 #include <Message.hpp>
 #include <cstring>
+#include "Helpers/CRCHelper.hpp"
 #include "MessageParser.hpp"
 #include "Services/ServiceTests.hpp"
 #include "ServicePool.hpp"
@@ -35,10 +36,18 @@ TEST_CASE("TC Message parsing into a string", "[MessageParser]") {
 	message.dataSize = 5;
 
 	String<CCSDS_MAX_MESSAGE_SIZE> createdPacket = MessageParser::compose(message);
+#if ECSS_CRC_INCLUDE
+	CHECK(createdPacket.size() == 18);
+	CHECK(memcmp(createdPacket.data(), wantedPacket, 16) == 0);
 
+	uint16_t crcField = CRCHelper::calculateCRC(wantedPacket, 16);
+	uint16_t calculatedCRC = (static_cast<uint16_t>(createdPacket.data()[16]) << 0x8U) | (static_cast<uint16_t>(createdPacket.data()[17]) & 0xFF);
+	CHECK(calculatedCRC == crcField);
+#else
 	CHECK(createdPacket.size() == 16);
 	// The two parentheses are necessary so that Catch2 doesn't try to parse the strings here
 	CHECK((createdPacket == String<16>(wantedPacket)));
+#endif
 }
 
 TEST_CASE("TM message parsing", "[MessageParser]") {
@@ -67,10 +76,19 @@ TEST_CASE("TM Message parsing into a string", "[MessageParser]") {
 	message.messageType = 17;
 	memcpy(message.data, "hellohi", 7);
 	message.dataSize = 7;
-
 	String<CCSDS_MAX_MESSAGE_SIZE> createdPacket = MessageParser::compose(message);
 
+#if ECSS_CRC_INCLUDE
+	CHECK(createdPacket.size() == 20);
+	CHECK(memcmp(createdPacket.data(), wantedPacket, 18) == 0);
+
+	uint16_t crcField = CRCHelper::calculateCRC(wantedPacket, 18);
+	uint16_t calculatedCRC = (static_cast<uint16_t>(createdPacket.data()[18]) << 0x8U) | (static_cast<uint16_t>
+		(createdPacket.data()[19]) & 0xFFU);
+	CHECK(calculatedCRC == crcField);
+#else
 	CHECK(createdPacket.size() == 18);
 	// The two parentheses are necessary so that Catch2 doesn't try to parse the strings here
 	CHECK((createdPacket == String<18>(wantedPacket)));
+#endif
 }
-- 
GitLab