diff --git a/inc/ECSS_Definitions.hpp b/inc/ECSS_Definitions.hpp index 86b0561c79808435fdf8a701e54de49ae7e839c6..38b44d007fc205b0a9483e82d6286cd83c7490af 100644 --- a/inc/ECSS_Definitions.hpp +++ b/inc/ECSS_Definitions.hpp @@ -24,10 +24,25 @@ */ inline const uint16_t ECSSMaxMessageSize = 1024U; +/** + * The size of each CCSDS Space packet primary header + */ +inline const uint16_t CCSDSPrimaryHeaderSize = 6U; + +/** + * The size of each ECSS Telemetry packet's secondary header + */ +inline const uint16_t ECSSSecondaryTMHeaderSize = 11U; + +/** + * The size of each ECSS Telecommand packet's secondary header + */ +inline const uint16_t ECSSSecondaryTCHeaderSize = 5U; + /** * The maximum size of a regular ECSS message, plus its headers and trailing data, in bytes */ -inline const uint16_t CCSDSMaxMessageSize = ECSSMaxMessageSize + 6u + 6u + 2u; +inline const uint16_t CCSDSMaxMessageSize = ECSSMaxMessageSize + CCSDSPrimaryHeaderSize + ECSSSecondaryTMHeaderSize + 2u; /** * The maximum size of a string to be read or appended to a Message, in bytes diff --git a/src/MessageParser.cpp b/src/MessageParser.cpp index 7ce06c23b64058b079a73eb0bf449462cd471b82..e7d9544ae60c0762b5e801a443640bac012106c7 100644 --- a/src/MessageParser.cpp +++ b/src/MessageParser.cpp @@ -86,7 +86,7 @@ void MessageParser::execute(Message& message) { } Message MessageParser::parse(uint8_t* data, uint32_t length) { - ASSERT_INTERNAL(length >= 6, ErrorHandler::UnacceptablePacket); + ASSERT_INTERNAL(length >= CCSDSPrimaryHeaderSize, ErrorHandler::UnacceptablePacket); uint16_t packetHeaderIdentification = (data[0] << 8) | data[1]; uint16_t packetSequenceControl = (data[2] << 8) | data[3]; @@ -104,22 +104,22 @@ Message MessageParser::parse(uint8_t* data, uint32_t length) { ASSERT_INTERNAL(versionNumber == 0U, ErrorHandler::UnacceptablePacket); ASSERT_INTERNAL(secondaryHeaderFlag, ErrorHandler::UnacceptablePacket); ASSERT_INTERNAL(sequenceFlags == 0x3U, ErrorHandler::UnacceptablePacket); - ASSERT_INTERNAL(packetDataLength == (length - 6U), ErrorHandler::UnacceptablePacket); + ASSERT_INTERNAL(packetDataLength == (length - CCSDSPrimaryHeaderSize), ErrorHandler::UnacceptablePacket); Message message(0, 0, packetType, APID); message.packetSequenceCount = packetSequenceCount; if (packetType == Message::TC) { - parseECSSTCHeader(data + 6, packetDataLength, message); + parseECSSTCHeader(data + CCSDSPrimaryHeaderSize, packetDataLength, message); } else { - parseECSSTMHeader(data + 6, packetDataLength, message); + parseECSSTMHeader(data + CCSDSPrimaryHeaderSize, packetDataLength, message); } return message; } void MessageParser::parseECSSTCHeader(const uint8_t* data, uint16_t length, Message& message) { - ErrorHandler::assertRequest(length >= 5, message, ErrorHandler::UnacceptableMessage); + ErrorHandler::assertRequest(length >= ECSSSecondaryTCHeaderSize, message, ErrorHandler::UnacceptableMessage); // Individual fields of the TC header uint8_t pusVersion = data[0] >> 4; @@ -129,12 +129,12 @@ void MessageParser::parseECSSTCHeader(const uint8_t* data, uint16_t length, Mess ErrorHandler::assertRequest(pusVersion == 2U, message, ErrorHandler::UnacceptableMessage); // Remove the length of the header - length -= 5; + length -= ECSSSecondaryTCHeaderSize; // Copy the data to the message message.serviceType = serviceType; message.messageType = messageType; - std::copy(data + 5, data + 5 + length, message.data); + std::copy(data + ECSSSecondaryTCHeaderSize, data + ECSSSecondaryTCHeaderSize + length, message.data); message.dataSize = length; } @@ -154,23 +154,33 @@ Message MessageParser::parseECSSTC(uint8_t* data) { } String<CCSDSMaxMessageSize> MessageParser::composeECSS(const Message& message, uint16_t size) { - uint8_t header[5]; + uint8_t headerSize = ((message.packetType == Message::TM) ? ECSSSecondaryTMHeaderSize : ECSSSecondaryTCHeaderSize); + uint8_t header[headerSize]; if (message.packetType == Message::TC) { header[0] = ECSSPUSVersion << 4U; // Assign the pusVersion = 2 + header[0] |= 0x00; //ack flags header[1] = message.serviceType; header[2] = message.messageType; - header[3] = 0; - header[4] = 0; + header[3] = message.applicationId >> 8U; + header[4] = message.applicationId; } else { header[0] = ECSSPUSVersion << 4U; // Assign the pusVersion = 2 + header[0] |= 0x00; // Spacecraft time reference status header[1] = message.serviceType; header[2] = message.messageType; header[3] = static_cast<uint8_t>(message.messageTypeCounter >> 8U); header[4] = static_cast<uint8_t>(message.messageTypeCounter & 0xffU); + header[5] = message.applicationId >> 8U; // DestinationID + header[6] = message.applicationId; + uint64_t ticks = TimeGetter::getCurrentTimeCustomCUC().elapsed100msTicks; + header[7] = (ticks >> 24) & 0xffU; + header[8] = (ticks >> 16) & 0xffU; + header[9] = (ticks >> 8) & 0xffU; + header[10] = (ticks) & 0xffU; } - String<CCSDSMaxMessageSize> dataString(header, 5); + String<CCSDSMaxMessageSize> dataString(header, headerSize); dataString.append(message.data, message.dataSize); // Make sure to reach the requested size @@ -190,13 +200,13 @@ String<CCSDSMaxMessageSize> MessageParser::composeECSS(const Message& message, u } String<CCSDSMaxMessageSize> MessageParser::compose(const Message& message) { - uint8_t header[6]; + uint8_t header[CCSDSPrimaryHeaderSize]; // First, compose the ECSS part String<CCSDSMaxMessageSize> ecssMessage = MessageParser::composeECSS(message); // Sanity check that there is enough space for the string - ASSERT_INTERNAL((ecssMessage.size() + 6U) <= CCSDSMaxMessageSize, ErrorHandler::StringTooLarge); + ASSERT_INTERNAL((ecssMessage.size() + CCSDSPrimaryHeaderSize) <= CCSDSMaxMessageSize, ErrorHandler::StringTooLarge); // Parts of the header uint16_t packetId = message.applicationId; @@ -214,7 +224,7 @@ String<CCSDSMaxMessageSize> MessageParser::compose(const Message& message) { header[5] = packetDataLength & 0xffU; // Compile the final message by appending the header - String<CCSDSMaxMessageSize> ccsdsMessage(header, 6); + String<CCSDSMaxMessageSize> ccsdsMessage(header, CCSDSPrimaryHeaderSize); ccsdsMessage.append(ecssMessage); #if ECSS_CRC_INCLUDED @@ -228,7 +238,7 @@ String<CCSDSMaxMessageSize> MessageParser::compose(const Message& message) { } void MessageParser::parseECSSTMHeader(const uint8_t* data, uint16_t length, Message& message) { - ErrorHandler::assertRequest(length >= 5, message, ErrorHandler::UnacceptableMessage); + ErrorHandler::assertRequest(length >= ECSSSecondaryTMHeaderSize, message, ErrorHandler::UnacceptableMessage); // Individual fields of the TM header uint8_t pusVersion = data[0] >> 4; @@ -238,11 +248,11 @@ void MessageParser::parseECSSTMHeader(const uint8_t* data, uint16_t length, Mess ErrorHandler::assertRequest(pusVersion == 2U, message, ErrorHandler::UnacceptableMessage); // Remove the length of the header - length -= 5; + length -= ECSSSecondaryTMHeaderSize; // Copy the data to the message message.serviceType = serviceType; message.messageType = messageType; - std::copy(data + 5, data + 5 + length, message.data); + std::copy(data + ECSSSecondaryTMHeaderSize, data + ECSSSecondaryTMHeaderSize + length, message.data); message.dataSize = length; } diff --git a/src/Platform/x86/main.cpp b/src/Platform/x86/main.cpp index 016647fda0cf1e2142123300802652a6b2899222..d8be71a147455f01d1cd29f37d01ca2fc8dcfa52 100644 --- a/src/Platform/x86/main.cpp +++ b/src/Platform/x86/main.cpp @@ -365,4 +365,4 @@ int main() { std::cout << UTCTimestamp() << std::endl; return 0; -} +} \ No newline at end of file diff --git a/test/MessageParserTests.cpp b/test/MessageParserTests.cpp index 3a2f7b05b76b48f0e5df5ac31d27c8e702597d40..9d8eb910fe22c1377fd0050891d612c5b135cca5 100644 --- a/test/MessageParserTests.cpp +++ b/test/MessageParserTests.cpp @@ -3,6 +3,7 @@ #include <catch2/catch_all.hpp> #include <cstring> #include "Helpers/CRCHelper.hpp" +#include "Helpers/TimeGetter.hpp" TEST_CASE("TC message parsing", "[MessageParser]") { uint8_t packet[] = {0x18, 0x07, 0xe0, 0x07, 0x00, 0x0a, 0x20, 0x81, 0x1f, 0x00, 0x00, 0x68, 0x65, 0x6c, 0x6c, 0x6f}; @@ -19,7 +20,7 @@ TEST_CASE("TC message parsing", "[MessageParser]") { TEST_CASE("TC Message parsing into a string", "[MessageParser]") { uint8_t wantedPacket[] = {0x18, 0x07, 0xe0, 0x07, 0x00, 0x0a, 0x20, 0x81, - 0x1f, 0x00, 0x00, 0x68, 0x65, 0x6c, 0x6c, 0x6f}; + 0x1f, 0x00, 0x07, 0x68, 0x65, 0x6c, 0x6c, 0x6f}; Message message; message.packetType = Message::TC; @@ -43,13 +44,21 @@ TEST_CASE("TC Message parsing into a string", "[MessageParser]") { CHECK(createdPacket.size() == 16); CHECK((createdPacket == String<16>(wantedPacket))); #endif + } TEST_CASE("TM message parsing", "[MessageParser]") { - uint8_t packet[] = {0x08, 0x02, 0xc0, 0x4d, 0x00, 0x0c, 0x20, 0x16, 0x11, - 0x00, 0x00, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x68, 0x69}; + uint8_t packet[] = {0x08, 0x02, 0xc0, 0x4d, 0x00, 0x12, 0x20, 0x16, + 0x11,0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, + 0x00, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x68, 0x69}; + //save time + uint64_t tenths = TimeGetter::getCurrentTimeCustomCUC().elapsed100msTicks; + packet[13] = (tenths >> 24) & 0xFF; + packet[14] = (tenths >> 16) & 0xFF; + packet[15] = (tenths >> 8) & 0xFF; + packet[16] = (tenths) & 0xFF; - Message message = MessageParser::parse(packet, 18); + Message message = MessageParser::parse(packet, 24); CHECK(message.packetType == Message::TM); CHECK(message.applicationId == 2); CHECK(message.packetSequenceCount == 77); @@ -57,11 +66,24 @@ TEST_CASE("TM message parsing", "[MessageParser]") { CHECK(message.serviceType == 22); CHECK(message.messageType == 17); CHECK(memcmp(message.data, "hellohi", 7) == 0); + + // Add ECSS and CCSDS header + String<CCSDSMaxMessageSize> createdPacket = MessageParser::compose(message); + uint32_t messageTime = (createdPacket[16] & 0xFF) | ((createdPacket[15] & 0xFF ) << 8) | ((createdPacket[14] & 0xFF) << 16) | ((createdPacket[13] & 0xFF ) << 24); + CHECK(messageTime == tenths); + } TEST_CASE("TM Message parsing into a string", "[MessageParser]") { - uint8_t wantedPacket[] = {0x08, 0x02, 0xc0, 0x4d, 0x00, 0x0c, 0x20, 0x16, 0x11, - 0x00, 0x00, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x68, 0x69}; + uint8_t wantedPacket[] = {0x08, 0x02, 0xc0, 0x4d, 0x00, 0x12, 0x20, 0x16, + 0x11,0x00, 0x00,0x00, 0x02,0x00, 0x00,0x00, + 0x00, 0x68,0x65, 0x6c, 0x6c, 0x6f, 0x68, 0x69}; + //save time + uint64_t tenths = TimeGetter::getCurrentTimeCustomCUC().elapsed100msTicks; + wantedPacket[13] = (tenths >> 24) & 0xFF; + wantedPacket[14] = (tenths >> 16) & 0xFF; + wantedPacket[15] = (tenths >> 8) & 0xFF; + wantedPacket[16] = (tenths) & 0xFF; Message message; message.packetType = Message::TM; @@ -75,14 +97,14 @@ TEST_CASE("TM Message parsing into a string", "[MessageParser]") { String<CCSDSMaxMessageSize> createdPacket = MessageParser::compose(message); #if ECSS_CRC_INCLUDED - CHECK(createdPacket.size() == 20); - CHECK(memcmp(createdPacket.data(), wantedPacket, 18) == 0); + CHECK(createdPacket.size() == 26); + CHECK(memcmp(createdPacket.data(), wantedPacket, 24) == 0); const uint8_t* packet = reinterpret_cast<uint8_t*>(&createdPacket.data()[0]); - uint8_t crc_verification = CRCHelper::validateCRC(packet, 20); + uint8_t crc_verification = CRCHelper::validateCRC(packet, 26); CHECK(crc_verification == 0); #else - CHECK(createdPacket.size() == 18); - CHECK((createdPacket == String<18>(wantedPacket))); + CHECK(createdPacket.size() == 24); + CHECK((createdPacket == String<24>(wantedPacket))); #endif } diff --git a/test/TestPlatform.cpp b/test/TestPlatform.cpp index 6a56dd7d7dc1db19268269f29a5457bffeebad33..29a222854d4f48ccd437b8b64dfc468ed5fd032f 100644 --- a/test/TestPlatform.cpp +++ b/test/TestPlatform.cpp @@ -1,5 +1,6 @@ #define CATCH_CONFIG_EXTERNAL_INTERFACES + #include <Logger.hpp> #include <Message.hpp> #include <Service.hpp>