Packages

macula

0.14.1
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
macula src macula_protocol_types.erl
Raw

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,
bridge_rpc_msg/0,
bridge_data_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).
-define(MSG_RPC_REQUEST, 16#24). % NATS-style async RPC request
-define(MSG_RPC_REPLY, 16#25). % NATS-style async RPC reply
%% 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).
%% NAT Traversal messages (0x50-0x5F range)
-define(MSG_NAT_PROBE, 16#50).
-define(MSG_NAT_PROBE_REPLY, 16#51).
-define(MSG_PUNCH_REQUEST, 16#52).
-define(MSG_PUNCH_COORDINATE, 16#53).
-define(MSG_PUNCH_EXECUTE, 16#54).
-define(MSG_PUNCH_RESULT, 16#55).
-define(MSG_RELAY_REQUEST, 16#56).
-define(MSG_RELAY_DATA, 16#57).
%% Bridge System messages (0x60-0x6F range)
-define(MSG_BRIDGE_RPC, 16#60).
-define(MSG_BRIDGE_DATA, 16#61).
%%%===================================================================
%%% Type Definitions
%%%===================================================================
-type message_type() ::
connect | disconnect | ping | pong |
publish | subscribe | unsubscribe | pubsub_route |
call | reply | cast | rpc_route | rpc_request | rpc_reply |
swim_ping | swim_ack | swim_ping_req |
find_node | find_node_reply | store | find_value | find_value_reply |
nat_probe | nat_probe_reply | punch_request | punch_coordinate |
punch_execute | punch_result | relay_request | relay_data |
bridge_rpc | bridge_data.
-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)
%% Note: Binary keys (<<"key">>) are used because MsgPack decoder returns binary keys.
-type rpc_route_msg() :: #{
binary() => term() % Binary keys: destination_node_id, source_node_id,
% hop_count, max_hops, payload_type, payload
}.
%% Pub/Sub Routing Message (for multi-hop DHT routing)
%% Note: Binary keys (<<"key">>) are used because MsgPack decoder returns binary keys.
-type pubsub_route_msg() :: #{
binary() => term() % Binary keys: destination_node_id, source_node_id,
% hop_count, max_hops, topic, payload
}.
%% Bridge System Messages (for hierarchical DHT)
-type bridge_rpc_msg() :: #{
procedure := binary(), % Internal procedure name (e.g., "_dht.find_value")
args := map(), % Procedure arguments
call_id := binary(), % Unique call ID for correlation
source_level := atom(), % Source mesh level (cluster, street, etc.)
timeout => integer() % Optional timeout in milliseconds
}.
-type bridge_data_msg() :: #{
payload := term(), % Arbitrary payload data
source_node_id => binary(), % Optional source node ID
metadata => map() % Optional metadata
}.
%%%===================================================================
%%% 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(rpc_request) -> ?MSG_RPC_REQUEST;
message_type_id(rpc_reply) -> ?MSG_RPC_REPLY;
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;
message_type_id(nat_probe) -> ?MSG_NAT_PROBE;
message_type_id(nat_probe_reply) -> ?MSG_NAT_PROBE_REPLY;
message_type_id(punch_request) -> ?MSG_PUNCH_REQUEST;
message_type_id(punch_coordinate) -> ?MSG_PUNCH_COORDINATE;
message_type_id(punch_execute) -> ?MSG_PUNCH_EXECUTE;
message_type_id(punch_result) -> ?MSG_PUNCH_RESULT;
message_type_id(relay_request) -> ?MSG_RELAY_REQUEST;
message_type_id(relay_data) -> ?MSG_RELAY_DATA;
message_type_id(bridge_rpc) -> ?MSG_BRIDGE_RPC;
message_type_id(bridge_data) -> ?MSG_BRIDGE_DATA.
%% @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_RPC_REQUEST) -> {ok, rpc_request};
message_type_name(?MSG_RPC_REPLY) -> {ok, rpc_reply};
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(?MSG_NAT_PROBE) -> {ok, nat_probe};
message_type_name(?MSG_NAT_PROBE_REPLY) -> {ok, nat_probe_reply};
message_type_name(?MSG_PUNCH_REQUEST) -> {ok, punch_request};
message_type_name(?MSG_PUNCH_COORDINATE) -> {ok, punch_coordinate};
message_type_name(?MSG_PUNCH_EXECUTE) -> {ok, punch_execute};
message_type_name(?MSG_PUNCH_RESULT) -> {ok, punch_result};
message_type_name(?MSG_RELAY_REQUEST) -> {ok, relay_request};
message_type_name(?MSG_RELAY_DATA) -> {ok, relay_data};
message_type_name(?MSG_BRIDGE_RPC) -> {ok, bridge_rpc};
message_type_name(?MSG_BRIDGE_DATA) -> {ok, bridge_data};
message_type_name(_) -> {error, unknown_type}.