add glue layer between SCCP and TCAP
This commit is contained in:
parent
b07fd4ad93
commit
b25d878a48
|
@ -0,0 +1,127 @@
|
||||||
|
% wrapper code between signerl/TCAP and osmo_ss7/SCCP
|
||||||
|
|
||||||
|
-module(osmo_sccp_tcap).
|
||||||
|
|
||||||
|
-copyright('Copyright (C) 2011 by Harald Welte <laforge@gnumonks.org>').
|
||||||
|
-author('Harald Welte <laforge@gnumonks.org>').
|
||||||
|
|
||||||
|
-behaviour(tcap_tco_server).
|
||||||
|
|
||||||
|
-include_lib("osmo_ss7/include/osmo_util.hrl").
|
||||||
|
-include_lib("osmo_ss7/include/sccp.hrl").
|
||||||
|
-include_lib("TCAP/include/sccp.hrl").
|
||||||
|
|
||||||
|
%% callbacks needed for gen_server behaviour
|
||||||
|
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||||
|
terminate/2, code_change/3]).
|
||||||
|
|
||||||
|
%% callbacks needed for tcap_tco_server
|
||||||
|
-export([send_primitive/2, start_user/3]).
|
||||||
|
|
||||||
|
%% our published API functions
|
||||||
|
-export([start_link/1, stop/1]).
|
||||||
|
|
||||||
|
start_link(SSN) ->
|
||||||
|
Ourname = list_to_atom("sccp_ssn" ++ integer_to_list(SSN)),
|
||||||
|
gen_server:start_link({local, Ourname}, ?MODULE, [SSN],[]).
|
||||||
|
|
||||||
|
init([SupRef, SSN]) ->
|
||||||
|
ok = sccp_user:bind_ssn(SSN, undefined),
|
||||||
|
State = 1,
|
||||||
|
{ok, State}.
|
||||||
|
|
||||||
|
handle_call(stop, _From, State) ->
|
||||||
|
{stop, shutdown, State}.
|
||||||
|
|
||||||
|
handle_cast(Request, State) ->
|
||||||
|
error_logger:error_report(["unknown handle_cast",
|
||||||
|
{request, Request}, {state, State}]),
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
|
osmo_prim2signerl(#primitive{subsystem='N', gen_name='UNITDATA',
|
||||||
|
spec_name=Spec, parameters=Msg}) ->
|
||||||
|
Params = Msg#sccp_msg.parameters,
|
||||||
|
CalledAddr = proplists:get_value(called_party_addr, Params),
|
||||||
|
CallingAddr = proplists:get_value(calling_party_addr, Params),
|
||||||
|
UserData = proplists:get_value(user_data, Params),
|
||||||
|
{PC, Opt} = proplists:get_value(protocol_class, Params),
|
||||||
|
Rec = #'N-UNITDATA'{calledAddress = CalledAddr,
|
||||||
|
callingAddress = CallingAddr,
|
||||||
|
sequenceControl = undefined,
|
||||||
|
returnOption = undefined,
|
||||||
|
importance = undefined,
|
||||||
|
userData = UserData},
|
||||||
|
{'N','UNITDATA', Spec, Rec}.
|
||||||
|
|
||||||
|
% incoming message from
|
||||||
|
handle_info({sccp, P= #primitive{subsystem='N',
|
||||||
|
gen_name='UNITDATA',
|
||||||
|
spec_name=indication}}, State) ->
|
||||||
|
% this is really ugly, we need to make TCO understand #primitives
|
||||||
|
gen_server:cast(self(), osmo_prim2signerl(P)),
|
||||||
|
{noreply, State};
|
||||||
|
handle_info(Info, State) ->
|
||||||
|
error_logger:error_report(["unknown handle_info",
|
||||||
|
{info, Info}, {state, State}]),
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
|
terminate(Reason, State) ->
|
||||||
|
io:format("terminating with Reason ~w", [Reason]),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
%% @spec (NSAP) -> ok
|
||||||
|
%% NSAP = pid()
|
||||||
|
%%
|
||||||
|
%% @doc Stop an sccp server.
|
||||||
|
%% <p>Closes an SCCP service access point (SAP).</p>
|
||||||
|
%% <p><tt>NSAP</tt> is a pid returned from a previous call to
|
||||||
|
%% <tt>start_link/2,3,7</tt>.</p>
|
||||||
|
%%
|
||||||
|
stop(NSAP) ->
|
||||||
|
gen_server:call(NSAP, stop).
|
||||||
|
|
||||||
|
% UNITDATA.req
|
||||||
|
|
||||||
|
% message coming down from TCO to SCCP, to be transmitted
|
||||||
|
send_primitive({'N', 'UNITDATA', request, #'N-UNITDATA'{calledAddress = Called,
|
||||||
|
callingAddress = Calling,
|
||||||
|
sequenceControl = Seq,
|
||||||
|
returnOption = RetOpt,
|
||||||
|
importance = Imp,
|
||||||
|
userData = UserData}=Par}, State) ->
|
||||||
|
io:format("N-UNITDATA.req (~w,~w)~n", [Par, State]),
|
||||||
|
ClassOut = protocol_class(tcap_to_osmo, {Seq, RetOpt}),
|
||||||
|
UserDataOut = iolist_to_binary(UserData),
|
||||||
|
% Build an osmo_ss7 primitive
|
||||||
|
Prim = osmo_util:make_prim('N', 'UNITDATA', request,
|
||||||
|
[{called_party_addr, Called},
|
||||||
|
{calling_party_addr, Calling},
|
||||||
|
{protocol_class, ClassOut},
|
||||||
|
{user_data, UserDataOut}]),
|
||||||
|
% send primitive to SCCP code
|
||||||
|
gen_fsm:send_event(sccp_scrc, Prim).
|
||||||
|
|
||||||
|
|
||||||
|
% TCAP has received the start of a new dialogue, return pid() of new user
|
||||||
|
start_user({DhaPid, CcoPid}, DialogueID, State) ->
|
||||||
|
tcap_test_user:start_link({DhaPid,CcoPid}, DialogueID).
|
||||||
|
|
||||||
|
|
||||||
|
% convert signerl format to osmo format
|
||||||
|
protocol_class(tcap_to_osmo, {SeqIn, ReturnIn}) ->
|
||||||
|
case SeqIn of
|
||||||
|
true ->
|
||||||
|
Class = 1;
|
||||||
|
_ ->
|
||||||
|
Class = 0
|
||||||
|
end,
|
||||||
|
case ReturnIn of
|
||||||
|
true ->
|
||||||
|
{Class, 8};
|
||||||
|
_ ->
|
||||||
|
{Class, 0}
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
code_change(_OldVsn, State, _Extra) ->
|
||||||
|
{ok, State}.
|
Loading…
Reference in New Issue