diff --git a/inc/ECSS_Definitions.hpp b/inc/ECSS_Definitions.hpp index a8523462496cad6652af9cb1c8eeb05d02fee2f4..14e36fa0eb76db874eed106c25bfdfb121a964c1 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 b4eb3953d2e6ecba5f4115759ba0ac062fb2847e..15849da94fa230e68efd32f66eeb94480978edf7 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 c416f1b5d6cdecf2c0b19f311bde1963540b3716..108224abd2983566c7f03ca346d5dd7b5cf87ae4 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 }