Skip to content

Instantly share code, notes, and snippets.

@niamtokik
Created February 8, 2018 06:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save niamtokik/dc264838a62980108a0bd915a9679d68 to your computer and use it in GitHub Desktop.
Save niamtokik/dc264838a62980108a0bd915a9679d68 to your computer and use it in GitHub Desktop.
Erlang/OTP IRC Client Test
-module(irc_connection).
-compile(export_all).
-behaviour(gen_statem).
%%====================================================================
%%
%%====================================================================
start() ->
start([]).
start(Args) ->
gen_statem:start(?MODULE, Args, []).
start_link() ->
start_link([]).
start_link(Args) ->
gen_statem:start_link(?MODULE, Args, []).
%%====================================================================
%%
%%====================================================================
callback_mode() ->
[state_functions, state_enter].
init(Args) ->
Host = proplists:get_value(host, Args, localhost),
Port = proplists:get_value(port, Args, 6667),
io:format("try to connect to: ~p:~p~n", [Host, Port]),
Socket = connect(Host, Port),
Data = {Host, Port, Socket},
{ok, connected, Data}.
terminate(_,_,_) ->
ok.
%%====================================================================
%%
%%====================================================================
connected(enter, OldState, {Host, Port, Socket}) ->
io:format("connected: ~p~n", [OldState]),
resp(Socket, {pass, null}),
resp(Socket, {nick, <<"test">>}),
resp(Socket, {user, <<"test">>}),
{keep_state, {Host, Port, Socket}};
connected(info, {tcp, Socket, <<"PING ", _Rest/bitstring>>}, Data) ->
{match, [ServerName]} = re:run(_Rest, ":([[:print:]]+)\r\n", [{capture, [1], binary}]),
resp(Socket, {pong, ServerName}),
{keep_state, Data};
connected(info, {tcp_closed, _}, {Host, Port, _}) ->
io:format("disconnected from ~p:~p~n", [Host, Port]),
{next_state, disconnected, {Host, Port, undefined}};
connected(Event, EventContent, Data) ->
io:format("~p, ~p, ~p~n", [Event, EventContent, Data]),
{keep_state, Data}.
disconnected(enter, Oldstate, Data) ->
io:format("disconnected~p~n", [Data]),
{keep_state, Data};
disconnected(cast, retry, Data) ->
{next_state, try_connection, Data};
disconnected(Event, EventContent, Data) ->
io:format("Got: ~p, ~p", [Event, EventContent]),
{keep_state, Data}.
%%====================================================================
%%
%%====================================================================
connect(Host) ->
connect(Host, 6667).
connect(Host, Port) ->
{ok, Socket} = gen_tcp:connect(Host, Port, [binary]),
Socket.
resp(Socket, {pass, null}) ->
resp(Socket, <<"PASS\r\n\r\n">>, []);
resp(Socket, {pass, Pass}) ->
resp(Socket, <<"PASS ", Pass/bitstring,"\r\n\r\n">>, []);
resp(Socket, {user, User}) ->
resp(Socket, <<"USER ", User/bitstring, " 0 * :test\r\n\r\n">>, []);
resp(Socket, {pong, ServerName}) ->
resp(Socket, <<"PONG ", ServerName/bitstring, "\r\n\r\n">>, []);
resp(Socket, {nick, Nick}) ->
resp(Socket, <<"NICK ", Nick/bitstring, "\r\n\r\n">>, []).
resp(Socket, Msg, _Opts) ->
io:format("send: ~p~n", [Msg]),
gen_tcp:send(Socket, Msg).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment