67 lines
1.6 KiB
Elixir
67 lines
1.6 KiB
Elixir
defmodule P2pChat.TransportProto do
|
|
defmodule Messages do
|
|
defmodule Hello do
|
|
defstruct [:netid]
|
|
end
|
|
|
|
defmodule InformNeighbor do
|
|
defstruct [:netid, :addr, :port]
|
|
end
|
|
|
|
defmodule Goodbye do
|
|
defstruct []
|
|
end
|
|
end
|
|
|
|
#
|
|
# Public API
|
|
#
|
|
|
|
def encode_message(%Messages.Hello{} = msg) do
|
|
[encode_version(), <<0x01::8>>, encode_string(msg.netid)]
|
|
end
|
|
|
|
def encode_message(%Messages.InformNeighbor{} = msg) do
|
|
[encode_version(), <<0x02::8>>, encode_string(msg.netid), encode_ip_addr(msg.addr)]
|
|
end
|
|
|
|
def encode_message(%Messages.Goodbye{} = _msg) do
|
|
[encode_version(), <<0x03::8>>]
|
|
end
|
|
|
|
def decode_message(<<0x01::8, 0x01::8, payload::binary>>) do
|
|
<<netid_len::16, netid::size(netid_len)-binary>> = payload
|
|
%Messages.Hello{netid: netid}
|
|
end
|
|
|
|
def decode_message(<<0x01::8, 0x02::8, payload::binary>>) do
|
|
<<netid_len::16, netid::size(netid_len)-binary, addr_len::16, addr::size(addr_len)-binary>> = payload
|
|
%Messages.InformNeighbor{netid: netid, addr: addr}
|
|
end
|
|
|
|
def decode_message(<<0x01::8, 0x03::8>>) do
|
|
%Messages.Goodbye{}
|
|
end
|
|
|
|
def decode_message(<<0x01::8, _::binary>>), do: :error
|
|
def decode_message(<<_::binary>>), do: :error
|
|
|
|
#
|
|
# Private Utilities
|
|
#
|
|
|
|
defp encode_version() do
|
|
<<0x01::8>>
|
|
end
|
|
|
|
defp encode_string(str) do
|
|
[<<byte_size(str)::16>>, str]
|
|
end
|
|
|
|
defp encode_ip_addr({a1, a2, a3, a4, a5, a6, a7, a8}) do
|
|
<<6::8, a1::8, a2::8, a3::8, a4::8, a5::8, a6::8, a7::8, a8::8>>
|
|
end
|
|
defp encode_ip_addr({a1, a2, a3, a4}) do
|
|
<<4::8, a1::8, a2::8, a3::8, a4::8>>
|
|
end
|
|
end
|