Packages
macula
0.7.26
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_routing_protocol.erl
%%%-------------------------------------------------------------------
%%% @doc
%%% DHT protocol message encoding/decoding.
%%% Maps DHT operations to/from message format.
%%% @end
%%%-------------------------------------------------------------------
-module(macula_routing_protocol).
%% API - Encoding
-export([
encode_find_node/1,
encode_find_node_reply/1,
encode_store/2,
encode_find_value/1,
encode_find_value_reply/1,
encode_node_info/1
]).
%% API - Decoding
-export([
decode_find_node/1,
decode_find_node_reply/1,
decode_store/1,
decode_find_value/1,
decode_find_value_reply/1,
decode_node_info/1
]).
%% API - Message type checks
-export([
is_find_node/1,
is_store/1,
is_find_value/1
]).
%% Types
-type message() :: map().
-export_type([message/0]).
%%%===================================================================
%%% Encoding Functions
%%%===================================================================
%% @doc Encode FIND_NODE request.
-spec encode_find_node(binary()) -> message().
encode_find_node(Target) ->
#{
type => find_node,
target => Target
}.
%% @doc Encode FIND_NODE reply.
-spec encode_find_node_reply([macula_routing_bucket:node_info()]) -> message().
encode_find_node_reply(Nodes) ->
#{
type => find_node_reply,
nodes => Nodes
}.
%% @doc Encode STORE request.
-spec encode_store(binary(), term()) -> message().
encode_store(Key, Value) ->
#{
type => store,
key => Key,
value => Value
}.
%% @doc Encode FIND_VALUE request.
-spec encode_find_value(binary()) -> message().
encode_find_value(Key) ->
#{
type => find_value,
key => Key
}.
%% @doc Encode FIND_VALUE reply.
-spec encode_find_value_reply({value, term()} | {nodes, [macula_routing_bucket:node_info()]}) -> message().
encode_find_value_reply({value, Value}) ->
#{
type => find_value_reply,
result => value,
value => Value
};
encode_find_value_reply({nodes, Nodes}) ->
#{
type => find_value_reply,
result => nodes,
nodes => Nodes
}.
%% @doc Encode node info (for transmission).
-spec encode_node_info(macula_routing_bucket:node_info()) -> map().
encode_node_info(NodeInfo) ->
#{
node_id => maps:get(node_id, NodeInfo),
address => maps:get(address, NodeInfo)
}.
%%%===================================================================
%%% Decoding Functions
%%%===================================================================
%% @doc Decode FIND_NODE request.
-spec decode_find_node(message()) -> {ok, binary()} | {error, invalid_message}.
decode_find_node(#{<<"type">> := <<"find_node">>, <<"target">> := Target}) ->
{ok, Target};
decode_find_node(_) ->
{error, invalid_message}.
%% @doc Decode FIND_NODE reply.
-spec decode_find_node_reply(message()) -> {ok, [macula_routing_bucket:node_info()]} | {error, invalid_message}.
decode_find_node_reply(#{<<"type">> := <<"find_node_reply">>, <<"nodes">> := Nodes}) ->
{ok, Nodes};
decode_find_node_reply(_) ->
{error, invalid_message}.
%% @doc Decode STORE request.
-spec decode_store(message()) -> {ok, binary(), term()} | {error, invalid_message}.
decode_store(#{<<"type">> := <<"store">>, <<"key">> := Key, <<"value">> := Value}) ->
{ok, Key, Value};
decode_store(_) ->
{error, invalid_message}.
%% @doc Decode FIND_VALUE request.
-spec decode_find_value(message()) -> {ok, binary()} | {error, invalid_message}.
decode_find_value(#{<<"type">> := <<"find_value">>, <<"key">> := Key}) ->
{ok, Key};
decode_find_value(_) ->
{error, invalid_message}.
%% @doc Decode FIND_VALUE reply.
-spec decode_find_value_reply(message()) ->
{ok, {value, term()} | {nodes, [macula_routing_bucket:node_info()]}} |
{error, invalid_message}.
decode_find_value_reply(#{<<"type">> := <<"find_value_reply">>, <<"result">> := <<"value">>, <<"value">> := Value}) ->
{ok, {value, Value}};
decode_find_value_reply(#{<<"type">> := <<"find_value_reply">>, <<"result">> := <<"nodes">>, <<"nodes">> := Nodes}) ->
{ok, {nodes, Nodes}};
decode_find_value_reply(_) ->
{error, invalid_message}.
%% @doc Decode node info.
-spec decode_node_info(map()) -> {ok, macula_routing_bucket:node_info()} | {error, invalid_node_info}.
decode_node_info(#{<<"node_id">> := NodeId, <<"address">> := Address}) ->
{ok, #{
node_id => NodeId,
address => Address
}};
decode_node_info(_) ->
{error, invalid_node_info}.
%%%===================================================================
%%% Message Type Checks
%%%===================================================================
%% @doc Check if message is FIND_NODE.
-spec is_find_node(message()) -> boolean().
is_find_node(#{<<"type">> := <<"find_node">>}) -> true;
is_find_node(_) -> false.
%% @doc Check if message is STORE.
-spec is_store(message()) -> boolean().
is_store(#{<<"type">> := <<"store">>}) -> true;
is_store(_) -> false.
%% @doc Check if message is FIND_VALUE.
-spec is_find_value(message()) -> boolean().
is_find_value(#{<<"type">> := <<"find_value">>}) -> true;
is_find_value(_) -> false.