diff --git a/inc/ECSS_Definitions.hpp b/inc/ECSS_Definitions.hpp index 2fe9218df54d72b0c965e75983ec99bb312d0f7d..99a86024a235d92ab2860221a52685ffd21c0b8f 100644 --- a/inc/ECSS_Definitions.hpp +++ b/inc/ECSS_Definitions.hpp @@ -7,6 +7,11 @@ #define ECSS_MAX_FIXED_OCTET_STRING_SIZE 256u // For the ST13 large packet transfer service +/** + * The total number of different message types that can be handled by this project + */ +#define ECSS_TOTAL_MESSAGE_TYPES (10 * 20) + // 7.4.1 #define CCSDS_PACKET_VERSION 0 diff --git a/inc/Message.hpp b/inc/Message.hpp index 6cd0ef1d73f06c6a2dda9fad42d17c8f4c86f3e4..55a5f05b394d7362154f27f2de313cd154c2523b 100644 --- a/inc/Message.hpp +++ b/inc/Message.hpp @@ -108,7 +108,7 @@ public: * multiple of the padding word size declared for the application process * @todo Confirm that the overall packet size is an integer multiple of the padding word size * declared for every application process - * @todo check if wee need to define the spare field for the telemetry and telecommand + * @todo check if we need to define the spare field for the telemetry and telecommand * secondary headers */ void finalize(); diff --git a/inc/ServicePool.hpp b/inc/ServicePool.hpp index 707ae91f1300ba2db2651d7f3297aa9577cf78bc..f6a7ea23ecc2e1d865c9ff3f454249e0b0520f94 100644 --- a/inc/ServicePool.hpp +++ b/inc/ServicePool.hpp @@ -23,12 +23,16 @@ class ServicePool { /** * A counter for messages * - * Each key-value pair corresponds to one MessageType within a Service. The most significant 8 bits are the number - * of the service, while the least significant 8 bits are the number of the Message. - * - * @todo Update this according to the final number of Services and Messages + * Each key-value pair corresponds to one MessageType within a Service. For the key, the most significant 8 bits are + * the number of the service, while the least significant 8 bits are the number of the Message. The value is the + * counter of each MessageType. */ - etl::map<uint16_t, uint16_t, 10*20> messageTypeCounter; + etl::map<uint16_t, uint16_t, ECSS_TOTAL_MESSAGE_TYPES> messageTypeCounter; + + /** + * A counter for messages that corresponds to the total number of TM packets sent from an APID + */ + uint16_t packetSequenceCounter = 0; public: RequestVerificationService requestVerification; EventReportService eventReport; @@ -64,7 +68,16 @@ public: * @param messageType The message type ID * @return The message type count */ - uint16_t getMessageTypeCounter(uint8_t serviceType, uint8_t messageType); + uint16_t getAndUpdateMessageTypeCounter(uint8_t serviceType, uint8_t messageType); + + /** + * Get and increase the "packet sequence count" for the next message + * + * The packet sequence count is incremented each time a packet is released, with a maximum value of 2^14 - 1 + * + * @return The packet sequence count + */ + uint16_t getAndUpdatePacketSequenceCounter(); }; /** diff --git a/src/Message.cpp b/src/Message.cpp index 7fb5974e00e6f59d8574a72c1aad1126be7cdfc0..a5fea247e6a4fa91c2757eeaf90ef8b7bfaf7091 100644 --- a/src/Message.cpp +++ b/src/Message.cpp @@ -39,12 +39,13 @@ void Message::finalize() { // Define the spare field in telemetry and telecommand user data field (7.4.3.2.c and 7.4.4.2.c) if (currentBit != 0) { currentBit = 0; - data[dataSize] = 0; // Make sure that the last bit is zero + data[dataSize] = 0; // Make sure that the last byte is zero dataSize++; } if (packetType == PacketType::TM) { - messageTypeCounter = Services.getMessageTypeCounter(serviceType, messageType); + messageTypeCounter = Services.getAndUpdateMessageTypeCounter(serviceType, messageType); + packetSequenceCount = Services.getAndUpdatePacketSequenceCounter(); } } diff --git a/src/ServicePool.cpp b/src/ServicePool.cpp index 7c203e7f2c10473ee1d5d104fdf7202ee18ef738..f3a529fd0cc2a8b0dada8cd2493807a9f2fdc9af 100644 --- a/src/ServicePool.cpp +++ b/src/ServicePool.cpp @@ -13,7 +13,18 @@ void ServicePool::reset() { new (this) ServicePool(); } -uint16_t ServicePool::getMessageTypeCounter(uint8_t serviceType, uint8_t messageType) { +uint16_t ServicePool::getAndUpdateMessageTypeCounter(uint8_t serviceType, uint8_t messageType) { uint16_t key = (serviceType << 8u) | messageType; // Create the key of the map return (messageTypeCounter[key])++; // Fetch and increase the value } + +uint16_t ServicePool::getAndUpdatePacketSequenceCounter() { + uint16_t value = packetSequenceCounter; + + // Increase the value + if ((++packetSequenceCounter) >= (1u << 14u)) { // The value of the packet sequence counter is <= (2^14 - 1) + packetSequenceCounter = 0; + } + + return value; +} diff --git a/test/Message.cpp b/test/Message.cpp index 8088d9450b8a770effb82d3f1d0a2f9f8add94f0..f6eba2461bc679f411b37e88eb4f18ce2a33bb97 100644 --- a/test/Message.cpp +++ b/test/Message.cpp @@ -1,5 +1,6 @@ #include <catch2/catch.hpp> #include <Message.hpp> +#include <ServicePool.hpp> TEST_CASE("Message is usable", "[message]") { Message message(5, 17, Message::TC, 3); @@ -290,3 +291,37 @@ TEST_CASE("Message type counter", "[message]") { CHECK(message2.messageTypeCounter == 0); } } + +TEST_CASE("Packet sequence counter", "[message]") { + SECTION("Packet counting") { + Message message1(0, 0, Message::TM, 0); + message1.finalize(); + CHECK(message1.packetSequenceCount == 0); + + Message message2(0, 0, Message::TM, 0); + message2.finalize(); + CHECK(message2.packetSequenceCount == 1); + + // Different message type check + Message message3(1, 2, Message::TM, 0); + message3.finalize(); + CHECK(message3.packetSequenceCount == 2); + } + + SECTION("Packet counter overflow") { + Services.reset(); + + for (int i = 0; i <= 16382; i++) { + Message message(0, 3, Message::TM, 0); + message.finalize(); + } + + Message message1(0, 3, Message::TM, 0); + message1.finalize(); + CHECK(message1.packetSequenceCount == 16383); + + Message message2(0, 3, Message::TM, 0); + message2.finalize(); + CHECK(message2.packetSequenceCount == 0); + } +}