From 4de202651fdd7a62eb76716f00cfc6e85a2400a9 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Tue, 3 Nov 2015 01:29:15 +0100 Subject: Rename tda to tapi --- src/tapi.erl | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 src/tapi.erl (limited to 'src/tapi.erl') diff --git a/src/tapi.erl b/src/tapi.erl new file mode 100644 index 0000000..4faba65 --- /dev/null +++ b/src/tapi.erl @@ -0,0 +1,128 @@ +-module(tapi). +-behaviour(gen_server). +-define(SERVER, ?MODULE). + +-export([start_link/0]). +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, + terminate/2, code_change/3]). + +-export([start/0, client/1, stop/0, decode/1]). +-export([send/1, ext/0, co/0, snapshot/1, monitor/1, button/1, dial/2]). + +-include("config.hrl"). +-include("opcodes.hrl"). + +start_link() -> + gen_server:start_link({local, ?SERVER}, ?MODULE, [?HOST, ?PORT], []). + +init(Args) -> + [Host, Port] = Args, + gen_tcp:connect(Host, Port, [binary, {packet, 2}], ?TIMEOUT). + +handle_call({ok, Reply}, _From, Socket) -> + gen_tcp:send(Socket, Reply), + {noreply, ok, Socket}; +handle_call({tcp, Socket, Data}, _From, Socket) -> + decode(Data), + {noreply, ok, Socket}; +handle_call({tcp_closed, _}, _From, Socket) -> + {stop, closed, Socket}; +handle_call(_Request, _From, State) -> + {reply, ok, State}. + +handle_cast(_Msg, State) -> + {noreply, State}. + +handle_info(_Info, State) -> + {noreply, State}. + +terminate(_Reason, State) -> + gen_tcp:close(State). + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +start() -> + register(?MODULE, spawn(?MODULE, client, [{dial, ?HOST, ?PORT}])). + +stop() -> + counter:stop(), + ?MODULE ! acse:release(). + +ext() -> + ?MODULE ! rose:invoke(?ESCAPE, escape:lines(station)). + +co() -> + ?MODULE ! rose:invoke(?ESCAPE, escape:lines(networkInterface)). + +send(Reply) -> + ?MODULE ! Reply. + +snapshot(Device) -> + ?MODULE ! rose:invoke(?SNAPSHOT, snapshot:encode({dialingNumber, Device})). + +button(Device) -> + ?MODULE ! rose:invoke(?BUTTON, button:encode({deviceNumber, Device})). + +monitor(Device) -> + ?MODULE ! rose:invoke(?MONITOR, monitor:encode({dialingNumber, Device})). + +dial(From, To) -> + ?MODULE ! rose:invoke(?MAKECALL, dial:encode({dialingNumber, From}, {dialingNumber, To})). + +client({dial, Host, Port}) -> + io:format("Dial ~p:~p~n", [Host, Port]), + Conn = gen_tcp:connect(Host, Port, [binary, {packet, 2}], ?TIMEOUT), + counter:start(), + client(Conn); + +client({ok, Sock}) -> + io:format("Connected~n", []), + ?MODULE ! acse:associate(), + loop(Sock); + +client({error, Reason}) -> + io:format("Error: ~p~n", [Reason]), + {error, Reason}. + +loop(Sock) -> + %inet:setopts(Sock, [{active, once}]), + receive + {ok, Reply} -> + io:format("Send ~p~n", [Reply]), + spawn(gen_tcp, send, [Sock, Reply]); + {tcp, Sock, Data} -> + io:format("Recv ~p~n", [Data]), + spawn(?MODULE, decode, [Data]); + {tcp_closed, _} -> + io:format("Connection closed~n", []), + exit(closed) + after ?TIMEOUT -> + io:format("Connection timed out~n", []), + exit(timeout) + end, + loop(Sock). + +decode(Data) -> + case kind(Data) of + rose -> + {ok, Rose} = rose:decode(Data), + io:format("ROSE> ~p~n", [Rose]), + rose:dispatch(Rose); + acse -> + {ok, Acse} = acse:decode(Data), + io:format("ACSE> ~p~n", [Acse]), + case acse:dispatch(Acse) of + error -> + stop(); + _ -> + ok + end + end. + +kind(<>) -> + proplists:get_value(Head, [{96, acse}, {97, acse}, {98, acse}, + {99, acse}, {100, acse}, {161, rose}, + {162, rose}, {163, rose}, {164, rose}]). -- cgit v1.2.3