Packages
macula
0.20.11
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,
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).
%% Gossip Protocol messages (0x70-0x7F range)
-define(MSG_GOSSIP_PUSH, 16#70). % Push local CRDT state to peer
-define(MSG_GOSSIP_PULL, 16#71). % Request CRDT state from peer
-define(MSG_GOSSIP_PULL_REPLY, 16#72). % Reply with CRDT state
-define(MSG_GOSSIP_SYNC, 16#73). % Full anti-entropy sync request
-define(MSG_GOSSIP_SYNC_REPLY, 16#74). % Full anti-entropy sync response
%% Registry System messages (0x80-0x8F range)
-define(MSG_REGISTRY_PUBLISH, 16#80). % Publish package to registry
-define(MSG_REGISTRY_PUBLISH_ACK, 16#81). % Acknowledge publish success
-define(MSG_REGISTRY_FETCH, 16#82). % Fetch package from registry
-define(MSG_REGISTRY_FETCH_REPLY, 16#83). % Package data response
-define(MSG_REGISTRY_QUERY, 16#84). % Query package metadata
-define(MSG_REGISTRY_QUERY_REPLY, 16#85). % Package metadata response
-define(MSG_REGISTRY_VERIFY, 16#86). % Verify package signature
-define(MSG_REGISTRY_VERIFY_REPLY, 16#87). % Verification result
-define(MSG_REGISTRY_SYNC, 16#88). % Sync registry index with peer
-define(MSG_REGISTRY_SYNC_REPLY, 16#89). % Registry index response
%% Content System messages (0x90-0x9F range)
-define(MSG_CONTENT_WANT, 16#90). % Request blocks by MCID
-define(MSG_CONTENT_HAVE, 16#91). % Announce available blocks
-define(MSG_CONTENT_BLOCK, 16#92). % Block data transfer
-define(MSG_CONTENT_MANIFEST_REQ, 16#93). % Request manifest by MCID
-define(MSG_CONTENT_MANIFEST_RES, 16#94). % Manifest data response
-define(MSG_CONTENT_CANCEL, 16#95). % Cancel pending wants
%%%===================================================================
%%% 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 |
gossip_push | gossip_pull | gossip_pull_reply | gossip_sync | gossip_sync_reply |
registry_publish | registry_publish_ack | registry_fetch | registry_fetch_reply |
registry_query | registry_query_reply | registry_verify | registry_verify_reply |
registry_sync | registry_sync_reply |
content_want | content_have | content_block |
content_manifest_req | content_manifest_res | content_cancel.
-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
%% Authorization fields (v0.17.0+)
default_ucan => binary() % Optional: default UCAN for session-wide grants
}.
-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
%% Authorization fields (v0.17.0+)
publisher_did => binary(), % Optional: publisher's DID
ucan_token => binary() % Optional: UCAN for cross-namespace publish
}.
-type subscribe_msg() :: #{
topics := [binary()], % List of topic patterns
qos := 0 | 1 | 2, % Requested QoS level
%% Authorization fields (v0.17.0+)
subscriber_did => binary(), % Optional: subscriber's DID
ucan_token => binary() % Optional: UCAN for cross-namespace subscribe
}.
-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
%% Authorization fields (v0.17.0+)
caller_did => binary(), % Optional: caller's DID
ucan_token => binary() % Optional: UCAN for cross-namespace call
}.
-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)
%% Authorization fields (v0.17.0+)
caller_did => binary(), % Optional: caller's DID
ucan_token => binary() % Optional: UCAN for cross-namespace cast
}.
%% 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
}.
%% Gossip Protocol Messages
-type gossip_push_msg() :: #{
node_id := binary(), % Sender node ID
state_type := atom(), % Type of CRDT (or_set, lww_register, etc.)
state_key := binary(), % Key identifying this state
state := term(), % Serialized CRDT state
vector_clock := map() % Vector clock for causal ordering
}.
-type gossip_pull_msg() :: #{
node_id := binary(), % Requester node ID
state_keys := [binary()] % Keys to request state for (empty = all)
}.
-type gossip_pull_reply_msg() :: #{
node_id := binary(), % Responder node ID
states := [#{ % List of state entries
key := binary(),
type := atom(),
state := term(),
vector_clock := map()
}]
}.
-type gossip_sync_msg() :: #{
node_id := binary(), % Sender node ID
digest := map() % Map of key -> {type, vector_clock} for local state
}.
-type gossip_sync_reply_msg() :: #{
node_id := binary(), % Responder node ID
states := [#{ % States that need to be synced
key := binary(),
type := atom(),
state := term(),
vector_clock := map()
}],
missing := [binary()] % Keys we don't have that sender has
}.
-export_type([
gossip_push_msg/0,
gossip_pull_msg/0,
gossip_pull_reply_msg/0,
gossip_sync_msg/0,
gossip_sync_reply_msg/0
]).
%% Registry System Messages
-type registry_publish_msg() :: #{
package_name := binary(), % Package name (e.g., <<"my_app">>)
version := binary(), % SemVer version (e.g., <<"1.0.0">>)
manifest := map(), % Parsed manifest
beam_archive := binary(), % Gzipped BEAM files
signature := binary(), % Ed25519 signature
public_key := binary() % Publisher's public key
}.
-type registry_publish_ack_msg() :: #{
package_name := binary(),
version := binary(),
checksum := binary(), % SHA-256 of beam_archive
published_at := integer() % Unix timestamp
}.
-type registry_fetch_msg() :: #{
package_name := binary(),
version => binary(), % Optional: specific version (latest if omitted)
include_deps => boolean() % Whether to include dependencies
}.
-type registry_fetch_reply_msg() :: #{
package_name := binary(),
version := binary(),
manifest := map(),
beam_archive := binary(),
signature := binary(),
public_key := binary(),
dependencies => [map()] % Optional dependency packages
}.
-type registry_query_msg() :: #{
package_name := binary(),
pattern => binary() % Optional: search pattern
}.
-type registry_query_reply_msg() :: #{
packages := [#{
name := binary(),
versions := [binary()],
latest := binary(),
description => binary()
}]
}.
-type registry_verify_msg() :: #{
package_name := binary(),
version := binary(),
checksum := binary() % SHA-256 to verify
}.
-type registry_verify_reply_msg() :: #{
package_name := binary(),
version := binary(),
valid := boolean(),
reason => binary() % Only if valid=false
}.
-type registry_sync_msg() :: #{
node_id := binary(),
package_index := [#{ % List of known packages
name := binary(),
version := binary(),
checksum := binary()
}]
}.
-type registry_sync_reply_msg() :: #{
node_id := binary(),
missing := [#{ % Packages we don't have
name := binary(),
version := binary()
}],
updates := [#{ % Packages with newer versions
name := binary(),
version := binary()
}]
}.
-export_type([
registry_publish_msg/0,
registry_publish_ack_msg/0,
registry_fetch_msg/0,
registry_fetch_reply_msg/0,
registry_query_msg/0,
registry_query_reply_msg/0,
registry_verify_msg/0,
registry_verify_reply_msg/0,
registry_sync_msg/0,
registry_sync_reply_msg/0
]).
%% Content System Messages
-type content_want_msg() :: #{
request_id := binary(), % Unique request ID
wants := [#{
mcid := binary(), % Block MCID to request
priority => 1..255 % Higher = more urgent (default: 128)
}],
max_blocks => pos_integer(), % Flow control: max blocks in response
from_node := binary() % Requester node ID
}.
-type content_have_msg() :: #{
haves := [binary()], % List of MCIDs we have
manifest_mcid => binary(), % Optional: we have all chunks of this manifest
from_node := binary()
}.
-type content_block_msg() :: #{
request_id := binary(), % Correlates with want request
mcid := binary(), % Block MCID
data := binary(), % Raw block data
from_node := binary()
}.
-type content_manifest_req_msg() :: #{
request_id := binary(),
mcid := binary(), % Manifest MCID
from_node := binary()
}.
-type content_manifest_res_msg() :: #{
request_id := binary(),
mcid := binary(),
manifest := binary(), % MessagePack-encoded manifest
from_node := binary()
}.
-type content_cancel_msg() :: #{
request_id := binary(), % Request to cancel
from_node := binary()
}.
-export_type([
content_want_msg/0,
content_have_msg/0,
content_block_msg/0,
content_manifest_req_msg/0,
content_manifest_res_msg/0,
content_cancel_msg/0
]).
%%%===================================================================
%%% 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;
message_type_id(gossip_push) -> ?MSG_GOSSIP_PUSH;
message_type_id(gossip_pull) -> ?MSG_GOSSIP_PULL;
message_type_id(gossip_pull_reply) -> ?MSG_GOSSIP_PULL_REPLY;
message_type_id(gossip_sync) -> ?MSG_GOSSIP_SYNC;
message_type_id(gossip_sync_reply) -> ?MSG_GOSSIP_SYNC_REPLY;
message_type_id(registry_publish) -> ?MSG_REGISTRY_PUBLISH;
message_type_id(registry_publish_ack) -> ?MSG_REGISTRY_PUBLISH_ACK;
message_type_id(registry_fetch) -> ?MSG_REGISTRY_FETCH;
message_type_id(registry_fetch_reply) -> ?MSG_REGISTRY_FETCH_REPLY;
message_type_id(registry_query) -> ?MSG_REGISTRY_QUERY;
message_type_id(registry_query_reply) -> ?MSG_REGISTRY_QUERY_REPLY;
message_type_id(registry_verify) -> ?MSG_REGISTRY_VERIFY;
message_type_id(registry_verify_reply) -> ?MSG_REGISTRY_VERIFY_REPLY;
message_type_id(registry_sync) -> ?MSG_REGISTRY_SYNC;
message_type_id(registry_sync_reply) -> ?MSG_REGISTRY_SYNC_REPLY;
message_type_id(content_want) -> ?MSG_CONTENT_WANT;
message_type_id(content_have) -> ?MSG_CONTENT_HAVE;
message_type_id(content_block) -> ?MSG_CONTENT_BLOCK;
message_type_id(content_manifest_req) -> ?MSG_CONTENT_MANIFEST_REQ;
message_type_id(content_manifest_res) -> ?MSG_CONTENT_MANIFEST_RES;
message_type_id(content_cancel) -> ?MSG_CONTENT_CANCEL.
%% @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(?MSG_GOSSIP_PUSH) -> {ok, gossip_push};
message_type_name(?MSG_GOSSIP_PULL) -> {ok, gossip_pull};
message_type_name(?MSG_GOSSIP_PULL_REPLY) -> {ok, gossip_pull_reply};
message_type_name(?MSG_GOSSIP_SYNC) -> {ok, gossip_sync};
message_type_name(?MSG_GOSSIP_SYNC_REPLY) -> {ok, gossip_sync_reply};
message_type_name(?MSG_REGISTRY_PUBLISH) -> {ok, registry_publish};
message_type_name(?MSG_REGISTRY_PUBLISH_ACK) -> {ok, registry_publish_ack};
message_type_name(?MSG_REGISTRY_FETCH) -> {ok, registry_fetch};
message_type_name(?MSG_REGISTRY_FETCH_REPLY) -> {ok, registry_fetch_reply};
message_type_name(?MSG_REGISTRY_QUERY) -> {ok, registry_query};
message_type_name(?MSG_REGISTRY_QUERY_REPLY) -> {ok, registry_query_reply};
message_type_name(?MSG_REGISTRY_VERIFY) -> {ok, registry_verify};
message_type_name(?MSG_REGISTRY_VERIFY_REPLY) -> {ok, registry_verify_reply};
message_type_name(?MSG_REGISTRY_SYNC) -> {ok, registry_sync};
message_type_name(?MSG_REGISTRY_SYNC_REPLY) -> {ok, registry_sync_reply};
message_type_name(?MSG_CONTENT_WANT) -> {ok, content_want};
message_type_name(?MSG_CONTENT_HAVE) -> {ok, content_have};
message_type_name(?MSG_CONTENT_BLOCK) -> {ok, content_block};
message_type_name(?MSG_CONTENT_MANIFEST_REQ) -> {ok, content_manifest_req};
message_type_name(?MSG_CONTENT_MANIFEST_RES) -> {ok, content_manifest_res};
message_type_name(?MSG_CONTENT_CANCEL) -> {ok, content_cancel};
message_type_name(_) -> {error, unknown_type}.