summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2015-10-29 14:00:41 +0100
committerDimitri Sokolyuk <demon@dim13.org>2015-10-29 14:00:41 +0100
commitfc86381ccac10fa30aefe76996a716ae1d677f5b (patch)
treec7a0c6c2ab9ab0c254bdb01088c2aad3119ff277 /src
parentb9697094228db7832e75a8699a2678338f7c7c22 (diff)
Prepare for rebar
Diffstat (limited to 'src')
-rw-r--r--src/acse.erl35
-rw-r--r--src/counter.erl41
-rw-r--r--src/csta.erl35
-rw-r--r--src/kme.erl10
-rw-r--r--src/rose.erl64
-rw-r--r--src/tda.erl89
6 files changed, 274 insertions, 0 deletions
diff --git a/src/acse.erl b/src/acse.erl
new file mode 100644
index 0000000..e8f0d70
--- /dev/null
+++ b/src/acse.erl
@@ -0,0 +1,35 @@
+-module(acse).
+
+-include("ACSE-1.hrl").
+-include("CSTA-application-context-information-csta3.hrl").
+
+-export([associate/0, release/0]).
+-export([decode/1, dispatch/1]).
+
+ui() ->
+ {ok, UI} = 'CSTA-application-context-information-csta3':encode(
+ 'ACSEUserInformationForCSTA', {newDefinition,
+ #'NewACSEUserInformationForCSTA'{cSTAVersion = [versionFive]}}),
+ {'single-ASN1-type', UI}.
+
+associate() ->
+ 'ACSE-1':encode('ACSE-apdu', {aarq, #'AARQ-apdu'{
+ 'protocol-version' = [version1],
+ 'application-context-name' = {1, 3, 12, 0, 218},
+ 'user-information' = [#'EXTERNAL'{
+ 'direct-reference' = {1, 3, 12, 0, 285, 200},
+ encoding = ui()}]}}).
+
+release() -> 'ACSE-1':encode('ACSE-apdu', {rlrq, #'RLRQ-apdu'{}}).
+
+decode(Msg) -> 'ACSE-1':decode('ACSE-apdu', Msg).
+
+dispatch({aare, #'AARE-apdu'{result = Result}}) ->
+ case Result of
+ accepted -> ok;
+ _ -> error
+ end;
+
+dispatch({rlre, _}) -> ok;
+
+dispatch({abrt, _}) -> error.
diff --git a/src/counter.erl b/src/counter.erl
new file mode 100644
index 0000000..98605f6
--- /dev/null
+++ b/src/counter.erl
@@ -0,0 +1,41 @@
+-module(counter).
+
+-export([start/0, counter/0, next/0, set/1, stop/0]).
+
+-define(MAXCOUNT, 32767).
+
+start() ->
+ register(counterPid, spawn_link(?MODULE, counter, [0])).
+
+counter() ->
+ process_flag(trap_exit, true),
+ count(0).
+
+count(N) when N > ?MAXCOUNT ->
+ count(0);
+
+count(N) ->
+ receive
+ {next, FromPID} ->
+ FromPID ! {next, N},
+ count(N+1);
+ {set, New} ->
+ count(New);
+ {'EXIT', Pid, Reason} ->
+ io:format("~p: ~p~n", [Pid, Reason]),
+ exit(normal);
+ {stop} ->
+ exit(normal)
+ end.
+
+set({present, N}) ->
+ counterPid ! {set, N}.
+
+next() ->
+ counterPid ! {next, self()},
+ receive
+ {next, N} -> {present, N}
+ end.
+
+stop() ->
+ counterPid ! {stop}.
diff --git a/src/csta.erl b/src/csta.erl
new file mode 100644
index 0000000..60aaaee
--- /dev/null
+++ b/src/csta.erl
@@ -0,0 +1,35 @@
+-module(csta).
+
+-export([lines/1, decode/1, snapshot/1]).
+-export([decodeStatus/1, statusOk/0]).
+
+-include("CSTA-escape-service.hrl").
+-include("CSTA-snapshot-device.hrl").
+-include("CSTA-device-identifiers.hrl").
+
+decode(Data) ->
+ 'CSTA-escape-service':decode('EscapeArgument', Data).
+
+lines(co) ->
+ lines(networkInterface);
+
+lines(ext) ->
+ lines(station);
+
+lines(Device) ->
+ 'CSTA-escape-service':encode('EscapeArgument', #'EscapeArgument'{
+ privateData = {private,
+ {kmeSystemData, {getSystemData, {request, {deviceList,
+ {category, {standardDevice, Device}}}}}}}}).
+
+decodeStatus(Data) ->
+ 'CSTA-system-status':decode('SystemStatusArg', Data).
+
+statusOk() ->
+ 'CSTA-system-status':encode('SystemStatusRes', {noData, []}).
+
+snapshot(Device) ->
+ 'CSTA-snapshot-device':encode('SnapshotDeviceArgument',
+ #'SnapshotDeviceArgument'{
+ snapshotObject = #'DeviceID'{
+ deviceIdentifier = {deviceNumber, Device}}}).
diff --git a/src/kme.erl b/src/kme.erl
new file mode 100644
index 0000000..64c8fde
--- /dev/null
+++ b/src/kme.erl
@@ -0,0 +1,10 @@
+-module(kme).
+
+-export([co_lines/0]).
+
+-include("KME-specific-types.hrl").
+
+co_lines() ->
+ 'KME-specific-types':encode('KMESpecificPrivateData',
+ {kmeSystemData, {getSystemData, {request, {deviceList,
+ {category, {standardDevice, networkInterface}}}}}}).
diff --git a/src/rose.erl b/src/rose.erl
new file mode 100644
index 0000000..c720dd8
--- /dev/null
+++ b/src/rose.erl
@@ -0,0 +1,64 @@
+-module(rose).
+
+-export([decode/1, invoke/2, dispatch/1]).
+
+-include("Remote-Operations-Generic-ROS-PDUs.hrl").
+
+decode(Data) ->
+ 'Remote-Operations-Generic-ROS-PDUs':decode('ROS', Data).
+
+return(Id, Op, {ok, Data}) ->
+ 'Remote-Operations-Generic-ROS-PDUs':encode('ROS', {returnResult,
+ #'ReturnResult'{invokeId = Id,
+ result = #'ReturnResult_result'{opcode = Op, result = Data}}}).
+
+invoke(Op, {ok, Data}) ->
+ Id = counter:next(),
+ 'Remote-Operations-Generic-ROS-PDUs':encode('ROS', {invoke,
+ #'Invoke'{invokeId = Id, opcode = Op, argument = Data}}).
+
+dispatch({invoke, #'Invoke'{invokeId = Id, opcode = Op, argument = Data}}) ->
+ counter:set(Id),
+ case Op of
+ {local, 21} ->
+ ok;
+ {local, 51} ->
+ {ok, Esc} = csta:decode(Data),
+ io:format("Esc ~p~n", [Esc]),
+ ok;
+ {local, 71} ->
+ ok;
+ {local, 74} ->
+ ok;
+ {local, 211} ->
+ {ok, Status} = csta:decodeStatus(Data),
+ io:format("Status: ~p~n", [Status]),
+ return(Id, Op, csta:statusOk());
+ _ ->
+ error
+ end;
+
+dispatch({returnResult, #'ReturnResult'{invokeId = Id, result = Data}}) ->
+ counter:set(Id),
+ dispatch(Data);
+
+dispatch({returnError, #'ReturnError'{invokeId = Id, errcode = Code, parameter = Par}}) ->
+ counter:set(Id),
+ io:format("Err: ~p ~p~n", [Code, Par]),
+ error;
+
+dispatch({reject, #'Reject'{invokeId = Id, problem = Problem}}) ->
+ counter:set(Id),
+ io:format("Problem: ~p~n", [Problem]),
+ error;
+
+dispatch(#'ReturnResult_result'{opcode = Op, result = Data}) ->
+ case Op of
+ {local, 74} ->
+ {ok, Status} = 'CSTA-snapshot-device':decode(
+ 'SnapshotDeviceResult', Data),
+ io:format("Result: ~p~n", [Status]);
+ _ ->
+ io:format("Result: ~p~n", [Data])
+ end,
+ ok.
diff --git a/src/tda.erl b/src/tda.erl
new file mode 100644
index 0000000..0798365
--- /dev/null
+++ b/src/tda.erl
@@ -0,0 +1,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.