summaryrefslogtreecommitdiff
path: root/src/tapi.erl
blob: 517b7be0272183d757e585185fe2fad5e67a64b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
-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([login/0, logout/0]).
-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(_Request, _From, State) ->
	{reply, ok, State}.

handle_cast({ok, Reply}, Socket) ->
	gen_tcp:send(Socket, Reply),
	{noreply, Socket}.

handle_info({tcp, _, Data}, Socket) ->
	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]),
			acse:dispatch(Acse)
	end,
	{noreply, Socket};

handle_info({tcp_closed, _}, Socket) ->
	{stop, closed, Socket}.

terminate(_Reason, State) ->
	gen_tcp:close(State).

code_change(_OldVsn, State, _Extra) ->
	{ok, State}.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

ext() ->
	gen_server:cast(?SERVER, rose:invoke(?ESCAPE, escape:lines(station))).

co() ->
	gen_server:cast(?SERVER, rose:invoke(?ESCAPE, escape:lines(networkInterface))).

send(Reply) ->
	gen_server:cast(?SERVER, Reply).

snapshot(Device) ->
	gen_server:cast(?SERVER, rose:invoke(?SNAPSHOT, snapshot:encode({dialingNumber, Device}))).

button(Device) ->
	gen_server:cast(?SERVER, rose:invoke(?BUTTON, button:encode({deviceNumber, Device}))).

monitor(Device) ->
	gen_server:cast(?SERVER, rose:invoke(?MONITOR, monitor:encode({dialingNumber, Device}))).

dial(From, To) ->
	gen_server:cast(?SERVER, rose:invoke(?MAKECALL, dial:encode({dialingNumber, From}, {dialingNumber, To}))).

login() ->
	gen_server:cast(?SERVER, acse:associate()).

logout() ->
	gen_server:cast(?SERVER, acse:release()).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

kind(<<Head:8,_/binary>>) ->
	proplists:get_value(Head, [{96, acse}, {97, acse}, {98, acse},
				   {99, acse}, {100, acse}, {161, rose},
				   {162, rose}, {163, rose}, {164, rose}]).

%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).