CommRaT 2.0.0
C++20 Real-Time Messaging Framework
Loading...
Searching...
No Matches
message_id.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cstdint>
4#include <type_traits>
5
6namespace commrat {
7
8// ============================================================================
9// Message ID Structure: 0xPSMM
10// P = Prefix (1 byte) - System(0x00) or UserDefined(0x01+)
11// S = SubPrefix (1 byte) - Category within prefix
12// MM = Message ID (2 bytes) - Specific message within category
13// ============================================================================
14
16enum class MessagePrefix : uint8_t {
17 System = 0x00,
18 UserDefined = 0x01
19};
20
22enum class SystemSubPrefix : uint8_t {
23 Subscription = 0x00,
24 Control = 0x01,
25 Reserved = 0xFF
26};
27
29enum class UserSubPrefix : uint8_t {
30 Data = 0x00,
31 Commands = 0x01,
32 Events = 0x02,
33 Custom = 0x03
34};
35
37constexpr uint32_t make_message_id(uint8_t prefix, uint8_t subprefix, uint16_t id) {
38 return (static_cast<uint32_t>(prefix) << 24) |
39 (static_cast<uint32_t>(subprefix) << 16) |
40 static_cast<uint32_t>(id);
41}
42
44constexpr uint32_t system_message_id(SystemSubPrefix subprefix, uint16_t id) {
45 return make_message_id(
46 static_cast<uint8_t>(MessagePrefix::System),
47 static_cast<uint8_t>(subprefix),
48 id
49 );
50}
51
53constexpr uint32_t user_message_id(UserSubPrefix subprefix, uint16_t id) {
54 return make_message_id(
55 static_cast<uint8_t>(MessagePrefix::UserDefined),
56 static_cast<uint8_t>(subprefix),
57 id
58 );
59}
60
61// ============================================================================
62// Message Definition - Compile-time message metadata
63// ============================================================================
64
70 static constexpr uint16_t id = 0xFFFF; // Auto-assign marker
71};
72
86template<
87 typename PayloadT,
89 auto SubPrefix_ = DefaultMessageDef::user_subprefix, // auto to accept both enum types
90 uint16_t ID_ = DefaultMessageDef::id
91>
93 using Payload = PayloadT;
94 static constexpr MessagePrefix prefix = Prefix_;
95 static constexpr uint16_t local_id = ID_;
96
97 // Extract subprefix value based on prefix type
98 static constexpr uint8_t subprefix = []() constexpr {
99 if constexpr (Prefix_ == MessagePrefix::System) {
100 if constexpr (std::is_same_v<decltype(SubPrefix_), SystemSubPrefix>) {
101 return static_cast<uint8_t>(SubPrefix_);
102 } else {
103 return static_cast<uint8_t>(DefaultMessageDef::system_subprefix);
104 }
105 } else {
106 if constexpr (std::is_same_v<decltype(SubPrefix_), UserSubPrefix>) {
107 return static_cast<uint8_t>(SubPrefix_);
108 } else {
109 return static_cast<uint8_t>(DefaultMessageDef::user_subprefix);
110 }
111 }
112 }();
113
114 // Full message ID (set during registry construction with auto-increment)
115 static constexpr bool needs_auto_id = (ID_ == 0xFFFF);
116};
117
118// ============================================================================
119// Request-Reply Pairing (RACK-style: reply = -request_id)
120// ============================================================================
121
127template<typename MessageDef>
128struct Request : MessageDef {
129 static constexpr bool is_request = true;
130};
131
137template<typename RequestMessageDef>
138struct Reply {
139 using Payload = typename RequestMessageDef::Payload; // Can be different, override if needed
140 static constexpr MessagePrefix prefix = RequestMessageDef::prefix;
141 static constexpr uint8_t subprefix = RequestMessageDef::subprefix;
142
143 // Reply ID is negative of request ID (in int16_t space)
144 static constexpr uint16_t local_id = []() constexpr {
145 int16_t signed_id = static_cast<int16_t>(RequestMessageDef::local_id);
146 return static_cast<uint16_t>(-signed_id);
147 }();
148
149 static constexpr bool is_reply = true;
150 static constexpr bool needs_auto_id = false; // Always explicit from request
151};
152
153// ============================================================================
154// Empty message support (commands with no payload)
155// ============================================================================
156
158struct EmptyPayload {};
159
160} // namespace commrat
CommRaT - Modern C++ Real-Time Communication Framework.
constexpr uint32_t make_message_id(uint8_t prefix, uint8_t subprefix, uint16_t id)
Compile-time message ID construction.
constexpr uint32_t system_message_id(SystemSubPrefix subprefix, uint16_t id)
System message ID helper.
SystemSubPrefix
System message sub-categories (when Prefix == System)
@ Subscription
Subscription protocol messages.
@ Reserved
Reserved for future use.
@ Control
Module control (on/off/reset/etc.)
MessagePrefix
Message ID prefixes.
@ System
Framework control messages (subscription, etc.)
@ UserDefined
User application messages (start from 0x01)
constexpr uint32_t user_message_id(UserSubPrefix subprefix, uint16_t id)
User message ID helper.
UserSubPrefix
User-defined message sub-categories (when Prefix == UserDefined)
@ Events
Event notifications.
@ Custom
User can start custom categories from here.
@ Commands
Command messages.
@ Data
Data messages (sensor data, state, etc.)
Default values for message definition.
static constexpr uint16_t id
static constexpr UserSubPrefix user_subprefix
static constexpr MessagePrefix prefix
static constexpr SystemSubPrefix system_subprefix
Empty payload for messages that only need their ID.
Message definition with compile-time ID assignment.
static constexpr uint8_t subprefix
static constexpr bool needs_auto_id
static constexpr MessagePrefix prefix
static constexpr uint16_t local_id
Define a reply message paired with a request.
static constexpr uint8_t subprefix
static constexpr uint16_t local_id
static constexpr MessagePrefix prefix
typename RequestMessageDef::Payload Payload
static constexpr bool needs_auto_id
static constexpr bool is_reply
Mark a message as a request that expects a reply.
static constexpr bool is_request