summaryrefslogtreecommitdiff
path: root/src/tda.erl
blob: 079836540f59bdba6006278cd6d9cccac1285ac4 (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
-module(tda).

-export([start/0, client/1, stop/0]).
-export([ext/0, co/0, snapshot/1]).

-define(TIMEOUT, 300000).
-define(CONNECT_TIMEOUT, 3000).
-define(HOST, "192.168.240.20").
-define(PORT, 33333).

start() ->
	register(tdaPid, spawn(?MODULE, client, [{dial, ?HOST, ?PORT}])).

stop() ->
	counter:stop(),
	tdaPid ! acse:release().

ext() ->
	tdaPid ! rose:invoke({local, 51}, csta:lines(ext)).

co() ->
	tdaPid ! rose:invoke({local, 51}, csta:lines(co)).

snapshot(Device) ->
	tdaPid ! rose:invoke({local, 74}, csta:snapshot(Device)).

client({dial, Host, Port}) ->
	io:format("Dial ~p:~p~n", [Host, Port]),
	Conn = gen_tcp:connect(Host, Port,
			       [binary, {active, once}, {packet, 2}],
			       ?CONNECT_TIMEOUT),
	counter:start(),
	client(Conn);

client({ok, Sock}) ->
	io:format("Connected~n", []),
	tdaPid ! 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]),
			gen_tcp:send(Sock, Reply);
		{tcp, Sock, Data} ->
			%io:format("Got ~p~n", [Data]),
			case decode(Data) of
				{ok, Reply} -> tdaPid ! {ok, Reply};
				ok -> ok;
				error -> exit(error)
			end;
		{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 dispatch(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.

dispatch(<<Head:8,_/binary>>) ->
	case Head of
		 96 -> acse;	% aarq
		 97 -> acse;	% aare
		 98 -> acse;	% rlrq
		 99 -> acse;	% rlre
		100 -> acse;	% abrt
		161 -> rose;	% invoke
		162 -> rose;	% returnResult
		163 -> rose;	% returnError
		164 -> rose	% reject
	end.