BF:BFD[
2.1140] → [
2.1157:1193]
BF:BFD[
2.1193] → [
4.13:13]
BFD:BFD[
3.5319] → [
4.3381:3415]
BF:BFD[
4.3415] → [
4.13:13]
B:BD[
4.680] → [
4.680:3046]
B:BD[
4.3047] → [
4.3047:3380]
%% experiment to interface with the veilid json API for message transmission
-module(veilid).
-behavior(gen_server).
-export([start_link/0, debug/2]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, code_change/3, terminate/2]).
start_link() ->
gen_server:start_link(?MODULE, [], []).
debug(Pid, Command) ->
Reply = gen_server:call(Pid, {debug, Command}),
binary_to_list(Reply).
%% gen_server things
init([]) ->
ConnOpts = [binary, {active, true}, {packet, line}, {buffer, 1024*64}],
{ok, Sock} = gen_tcp:connect("localhost", 5959, ConnOpts),
ReaderProc = spawn(fun() -> loop([{sock, Sock}, {activeIds, maps:new()}]) end),
ok = gen_tcp:controlling_process(Sock, ReaderProc),
{ok, [{sock, Sock}, {idCount, 0}, {reader, ReaderProc}]}.
handle_call({debug, Command}, From, State) ->
[{sock, Sock}, {idCount, IdCount}, {reader, RP}] = State,
NextId = IdCount+1,
RP ! {commandId, NextId, From},
%% io:format("[veilid-debug] sending ~p as Id:~p~n", [Command, NextId]),
Json = io_lib:format("{\"op\":\"Debug\",\"command\":~p,\"id\":~p}~n", [Command, NextId]),
gen_tcp:send(Sock, list_to_binary(Json)),
NewState = lists:keyreplace(idCount, 1, State, {idCount, NextId}),
{noreply, NewState}.
handle_cast(Msg, State) ->
io:format("Unexpected cast: ~p~n", [Msg]),
{noreply, ok, State}.
handle_info(Msg, State) ->
io:format("Unexpected message: ~p~n", [Msg]),
{noreply, State}.
terminate(normal, [{sock, Sock}, _]) ->
gen_tcp:close(Sock),
ok.
code_change(_OldVsn, State, _Extra) ->
%% no change planned. The functionm is there for the behaviour,
%% but will not be used.
{ok, State}.
%% private
loop(State = [{sock, Sock}, {activeIds, ActiveIds}]) ->
receive
{commandId, Id, From} ->
%% io:format("[veilid-tracking] id: ~p for ~p~n", [Id, From]),
NewActive = ActiveIds#{Id => From},
NewState = lists:keyreplace(activeIds, 1, State, {activeIds, NewActive}),
loop(NewState);
{tcp, Sock, Data} ->
Decoded = jsone:decode(Data),
case Decoded of
#{<<"type">> := <<"Update">>, <<"kind">> := <<"Network">>} -> %,<<"peers">> := Peers, <<"bps_down">> := Down, <<"bps_up">> := Up} ->
noop;
%% io:format("[veilid-update] Peers: ~p | Down: ~p | Up: ~p~n", [length(Peers), binary_to_integer(Down), binary_to_integer(Up)]);
#{<<"type">> := <<"Response">>, <<"op">> := <<"Debug">>, <<"id">> := Id, <<"value">> := Value} ->
case maps:take(Id, ActiveIds) of
{From, NewActive} ->
gen_server:reply(From, Value),
NewState = lists:keyreplace(activeIds, 1, State, {activeIds, NewActive}),
loop(NewState);
error ->
io:format("[veilid-error] Response for unknown ID: ~p with Value: ~p~n", [Id, Value])
end;
Unknown ->
K = maps:keys(Decoded),
io:format("Unknown veilid data: Keys:~p~n~p~n", [K, Unknown])
end,
loop(State);
{tcp_closed, S} ->
io:format("Socket ~w closed [~w]~n",[S,self()]),
ok
end.
%% TODO: link the sock to the gen_server