Packages
macula
0.8.16
7.0.0
6.0.0
5.2.2
5.2.1
5.2.0
5.1.0
5.0.0
4.8.0
4.7.1
4.7.0
4.6.0
4.5.0
4.4.10
4.4.9
4.4.8
4.4.7
4.4.6
4.4.5
4.4.4
4.4.3
4.4.2
4.4.1
4.4.0
4.3.1
4.3.0
4.2.9
4.2.8
4.2.7
4.2.6
4.2.5
4.2.4
4.2.3
4.2.2
4.2.1
4.2.0
4.1.1
4.1.0
4.0.0
3.16.0
3.15.3
3.15.2
3.15.1
3.14.0
3.13.0
3.12.1
3.12.0
3.11.1
3.11.0
3.10.3
3.10.2
3.10.1
3.9.0
3.8.0
3.7.0
3.5.0
3.4.0
3.3.0
3.2.0
3.1.0
3.0.0
2.1.1
2.1.0
2.0.0
1.5.2
1.5.1
1.4.30
1.4.29
1.4.28
1.4.27
1.4.26
1.4.25
1.4.24
1.4.23
1.4.22
1.4.21
1.4.20
1.4.19
1.4.18
1.4.17
1.4.16
1.4.15
1.4.14
1.4.13
1.4.11
1.4.10
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.1
1.3.0
1.2.0
1.1.0
1.0.10
1.0.9
1.0.8
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.48.6
0.48.5
0.48.4
0.48.3
0.48.2
0.48.1
0.48.0
0.47.1
0.47.0
0.46.3
0.46.1
0.46.0
0.45.3
0.45.2
0.45.1
0.45.0
0.44.2
0.44.1
0.44.0
0.43.3
0.43.2
0.43.1
0.43.0
0.42.9
0.42.8
0.42.7
0.42.6
0.42.5
0.42.4
0.42.3
0.42.2
0.42.1
0.42.0
0.41.1
0.41.0
0.40.1
0.40.0
0.39.9
0.39.8
0.39.7
0.39.6
0.39.5
0.39.4
0.39.3
0.39.2
0.39.1
0.39.0
0.38.8
0.38.7
0.38.6
0.38.5
0.38.4
0.38.3
0.38.2
0.38.1
0.38.0
0.37.7
0.37.6
0.37.5
0.37.4
0.37.3
0.37.2
0.37.1
0.37.0
0.36.6
0.36.5
0.36.4
0.36.3
0.36.2
0.36.1
0.36.0
0.35.4
0.35.3
0.35.2
0.35.1
0.35.0
0.34.1
0.34.0
0.33.1
0.33.0
0.32.5
0.32.4
0.32.3
0.32.2
0.32.1
0.32.0
0.31.9
0.31.8
0.31.7
0.31.6
0.31.5
0.31.4
0.31.3
0.31.2
0.31.1
0.31.0
0.30.10
0.30.9
0.30.8
0.30.7
0.30.6
0.30.5
0.30.4
0.30.3
0.30.2
0.30.1
0.30.0
0.29.0
0.28.3
0.28.2
0.28.1
0.28.0
0.27.1
0.27.0
0.26.1
0.26.0
0.25.6
0.25.5
0.25.4
0.25.3
0.25.2
0.25.1
0.25.0
0.24.6
0.24.5
0.24.4
0.24.3
0.24.2
0.24.1
0.24.0
0.23.3
0.23.2
0.23.1
0.23.0
0.22.12
0.22.11
0.22.10
0.22.9
0.22.8
0.22.7
0.22.6
0.22.5
0.22.4
0.22.3
0.22.2
0.22.1
0.22.0
0.21.7
0.21.6
0.21.5
0.21.4
0.21.2
0.21.1
0.21.0
0.20.25
0.20.24
0.20.23
0.20.22
0.20.21
0.20.20
0.20.19
0.20.18
0.20.17
0.20.16
0.20.15
0.20.14
0.20.13
0.20.12
0.20.11
0.20.10
0.20.9
0.20.8
0.20.7
0.20.6
0.20.5
0.20.3
0.20.2
0.20.1
0.20.0
0.19.2
0.19.1
0.19.0
0.18.1
0.18.0
0.17.4
0.17.3
0.17.2
0.17.1
0.17.0
0.16.6
0.16.5
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.1
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.12.6
0.12.5
0.12.3
0.11.3
0.10.2
0.10.1
0.10.0
0.9.2
0.9.1
0.9.0
0.8.25
0.8.24
0.8.23
0.8.22
0.8.21
0.8.20
0.8.19
0.8.18
0.8.17
0.8.16
0.8.15
0.8.14
0.8.13
0.8.12
0.8.11
0.8.10
0.8.9
0.8.8
0.8.7
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.30
0.7.29
0.7.28
0.7.27
0.7.26
0.7.25
0.7.24
0.7.23
0.7.22
0.7.21
0.7.20
0.7.19
0.7.18
0.7.17
0.7.16
0.7.15
0.7.14
0.7.13
0.7.12
0.7.11
0.7.10
0.7.9
0.7.8
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.0
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.4
0.3.3
0.3.2
0.3.1
Macula HTTP/3 Mesh SDK — connect, subscribe, publish, call, advertise
Current section
Files
Jump to
Current section
Files
src/macula_protocol_types.erl
%%%-------------------------------------------------------------------
%%% @doc
%%% Protocol message type definitions and constants for Macula mesh.
%%% Defines all message types that can be sent over QUIC streams.
%%% @end
%%%-------------------------------------------------------------------
-module(macula_protocol_types).
%% Message type constants
-export([
message_type_id/1,
message_type_name/1
]).
%% Type exports
-export_type([
message_type/0,
message/0,
connect_msg/0,
disconnect_msg/0,
ping_msg/0,
pong_msg/0,
publish_msg/0,
subscribe_msg/0,
unsubscribe_msg/0,
call_msg/0,
reply_msg/0,
cast_msg/0,
rpc_route_msg/0,
pubsub_route_msg/0
]).
%%%===================================================================
%%% Message Type IDs
%%%===================================================================
%% Control messages
-define(MSG_CONNECT, 16#01).
-define(MSG_DISCONNECT, 16#02).
-define(MSG_PING, 16#03).
-define(MSG_PONG, 16#04).
%% Pub/Sub messages
-define(MSG_PUBLISH, 16#10).
-define(MSG_SUBSCRIBE, 16#11).
-define(MSG_UNSUBSCRIBE, 16#12).
-define(MSG_PUBSUB_ROUTE, 16#13).
%% RPC messages
-define(MSG_CALL, 16#20).
-define(MSG_REPLY, 16#21).
-define(MSG_CAST, 16#22).
-define(MSG_RPC_ROUTE, 16#23).
%% SWIM membership messages
-define(MSG_SWIM_PING, 16#30).
-define(MSG_SWIM_ACK, 16#31).
-define(MSG_SWIM_PING_REQ, 16#32).
%% Kademlia routing messages
-define(MSG_FIND_NODE, 16#40).
-define(MSG_FIND_NODE_REPLY,16#41).
-define(MSG_STORE, 16#42).
-define(MSG_FIND_VALUE, 16#43).
-define(MSG_FIND_VALUE_REPLY,16#44).
%%%===================================================================
%%% Type Definitions
%%%===================================================================
-type message_type() ::
connect | disconnect | ping | pong |
publish | subscribe | unsubscribe | pubsub_route |
call | reply | cast | rpc_route |
swim_ping | swim_ack | swim_ping_req |
find_node | find_node_reply | store | find_value | find_value_reply.
-type message() ::
{connect, connect_msg()} |
{disconnect, disconnect_msg()} |
{ping, ping_msg()} |
{pong, pong_msg()} |
{publish, publish_msg()} |
{subscribe, subscribe_msg()} |
{unsubscribe, unsubscribe_msg()} |
{pubsub_route, pubsub_route_msg()} |
{call, call_msg()} |
{reply, reply_msg()} |
{cast, cast_msg()} |
{rpc_route, rpc_route_msg()}.
%% Control Messages
-type connect_msg() :: #{
version := binary(), % Protocol version "1.0"
node_id := binary(), % 32-byte node ID
realm_id := binary(), % 32-byte realm ID
capabilities := [atom()], % List of supported features
endpoint => binary() % Optional: "https://host:port" for peer connections
}.
-type disconnect_msg() :: #{
reason := atom(), % normal | error | timeout
message := binary() % Human-readable reason
}.
-type ping_msg() :: #{
timestamp := integer() % Monotonic timestamp (milliseconds)
}.
-type pong_msg() :: #{
timestamp := integer(), % Original ping timestamp
server_time := integer() % Server's monotonic timestamp
}.
%% Pub/Sub Messages
-type publish_msg() :: #{
topic := binary(), % Topic name
payload := binary(), % Message payload
qos := 0 | 1 | 2, % Quality of service
retain := boolean(), % Retain flag
message_id := binary() % 16-byte unique message ID
}.
-type subscribe_msg() :: #{
topics := [binary()], % List of topic patterns
qos := 0 | 1 | 2 % Requested QoS level
}.
-type unsubscribe_msg() :: #{
topics := [binary()] % Topics to unsubscribe from
}.
%% RPC Messages
-type call_msg() :: #{
procedure := binary(), % Procedure name (e.g., "my.app.get_user")
args := binary(), % JSON-encoded arguments
call_id := binary(), % 16-byte unique call ID
timeout => integer() % Optional timeout in milliseconds
}.
-type reply_msg() :: #{
call_id := binary(), % Matching call_id from call_msg
result => binary(), % JSON-encoded result (on success)
error => #{ % Error details (on failure)
code := binary(), % Error code
message := binary() % Error message
}
}.
-type cast_msg() :: #{
procedure := binary(), % Procedure name
args := binary() % JSON-encoded arguments (no reply expected)
}.
%% RPC Routing Message (for multi-hop DHT routing)
-type rpc_route_msg() :: #{
destination_node_id := binary(), % 32-byte destination node ID
source_node_id := binary(), % 32-byte source node ID
hop_count := non_neg_integer(), % Current hop count (for debugging/metrics)
max_hops := pos_integer(), % Max hops allowed (TTL protection, default: 10)
payload_type := call | reply, % Type of wrapped message
payload := call_msg() | reply_msg() % The actual RPC message
}.
%% Pub/Sub Routing Message (for multi-hop DHT routing)
-type pubsub_route_msg() :: #{
destination_node_id := binary(), % 32-byte subscriber node ID
source_node_id := binary(), % 32-byte publisher node ID
hop_count := non_neg_integer(), % Current hop count (for debugging/metrics)
max_hops := pos_integer(), % Max hops allowed (TTL protection, default: 10)
topic := binary(), % Pub/sub topic
payload := publish_msg() % The actual PUBLISH message
}.
%%%===================================================================
%%% API Functions
%%%===================================================================
%% @doc Get numeric ID for a message type.
-spec message_type_id(message_type()) -> byte().
message_type_id(connect) -> ?MSG_CONNECT;
message_type_id(disconnect) -> ?MSG_DISCONNECT;
message_type_id(ping) -> ?MSG_PING;
message_type_id(pong) -> ?MSG_PONG;
message_type_id(publish) -> ?MSG_PUBLISH;
message_type_id(subscribe) -> ?MSG_SUBSCRIBE;
message_type_id(unsubscribe) -> ?MSG_UNSUBSCRIBE;
message_type_id(pubsub_route) -> ?MSG_PUBSUB_ROUTE;
message_type_id(call) -> ?MSG_CALL;
message_type_id(reply) -> ?MSG_REPLY;
message_type_id(cast) -> ?MSG_CAST;
message_type_id(rpc_route) -> ?MSG_RPC_ROUTE;
message_type_id(swim_ping) -> ?MSG_SWIM_PING;
message_type_id(swim_ack) -> ?MSG_SWIM_ACK;
message_type_id(swim_ping_req) -> ?MSG_SWIM_PING_REQ;
message_type_id(find_node) -> ?MSG_FIND_NODE;
message_type_id(find_node_reply) -> ?MSG_FIND_NODE_REPLY;
message_type_id(store) -> ?MSG_STORE;
message_type_id(find_value) -> ?MSG_FIND_VALUE;
message_type_id(find_value_reply) -> ?MSG_FIND_VALUE_REPLY.
%% @doc Get message type name from numeric ID.
-spec message_type_name(byte()) -> {ok, message_type()} | {error, unknown_type}.
message_type_name(?MSG_CONNECT) -> {ok, connect};
message_type_name(?MSG_DISCONNECT) -> {ok, disconnect};
message_type_name(?MSG_PING) -> {ok, ping};
message_type_name(?MSG_PONG) -> {ok, pong};
message_type_name(?MSG_PUBLISH) -> {ok, publish};
message_type_name(?MSG_SUBSCRIBE) -> {ok, subscribe};
message_type_name(?MSG_UNSUBSCRIBE) -> {ok, unsubscribe};
message_type_name(?MSG_PUBSUB_ROUTE) -> {ok, pubsub_route};
message_type_name(?MSG_CALL) -> {ok, call};
message_type_name(?MSG_REPLY) -> {ok, reply};
message_type_name(?MSG_CAST) -> {ok, cast};
message_type_name(?MSG_RPC_ROUTE) -> {ok, rpc_route};
message_type_name(?MSG_SWIM_PING) -> {ok, swim_ping};
message_type_name(?MSG_SWIM_ACK) -> {ok, swim_ack};
message_type_name(?MSG_SWIM_PING_REQ) -> {ok, swim_ping_req};
message_type_name(?MSG_FIND_NODE) -> {ok, find_node};
message_type_name(?MSG_FIND_NODE_REPLY) -> {ok, find_node_reply};
message_type_name(?MSG_STORE) -> {ok, store};
message_type_name(?MSG_FIND_VALUE) -> {ok, find_value};
message_type_name(?MSG_FIND_VALUE_REPLY) -> {ok, find_value_reply};
message_type_name(_) -> {error, unknown_type}.