blob: 2996b949957286fbcfd854e5db83e7ba93c6033f [file] [log] [blame]
Harald Welte91b79652012-01-17 10:12:34 +01001% SUA behaviour call-back for sctp_core
2
3% (C) 2011-2012 by Harald Welte <laforge@gnumonks.org>
4%
5% All Rights Reserved
6%
7% This program is free software; you can redistribute it and/or modify
8% it under the terms of the GNU Affero General Public License as
9% published by the Free Software Foundation; either version 3 of the
10% License, or (at your option) any later version.
11%
12% This program is distributed in the hope that it will be useful,
13% but WITHOUT ANY WARRANTY; without even the implied warranty of
14% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15% GNU General Public License for more details.
16%
17% You should have received a copy of the GNU Affero General Public License
18% along with this program. If not, see <http://www.gnu.org/licenses/>.
Harald Weltef8bf0322012-04-16 13:10:47 +020019%
20% Additional Permission under GNU AGPL version 3 section 7:
21%
22% If you modify this Program, or any covered work, by linking or
23% combining it with runtime libraries of Erlang/OTP as released by
24% Ericsson on http://www.erlang.org (or a modified version of these
25% libraries), containing parts covered by the terms of the Erlang Public
26% License (http://www.erlang.org/EPLICENSE), the licensors of this
27% Program grant you additional permission to convey the resulting work
28% without the need to license the runtime libraries of Erlang/OTP under
29% the GNU Affero General Public License. Corresponding Source for a
30% non-source form of such a combination shall include the source code
31% for the parts of the runtime libraries of Erlang/OTP used as well as
32% that of the covered work.
Harald Welte91b79652012-01-17 10:12:34 +010033
34-module(sctp_sua).
35-author('Harald Welte <laforge@gnumonks.org>').
36-behaviour(sctp_core).
37
38-include_lib("kernel/include/inet_sctp.hrl").
39-include("osmo_util.hrl").
Harald Welte92e783d2012-04-01 19:52:01 +020040-include("xua.hrl").
Harald Welte91b79652012-01-17 10:12:34 +010041-include("sua.hrl").
42-include("m3ua.hrl").
43
44-export([init/1, terminate/3, code_change/4, handle_event/3, handle_info/3]).
45
46-export([rx_sctp/4, mtp_xfer/2, state_change/3, prim_up/3]).
47
48-record(sua_state, {
49 asp_pid
50 }).
51
52%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
53% gen_fsm callbacks
54%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
55
Harald Welte0d8af6b2013-07-27 15:02:17 +080056init([Role]) ->
Harald Welte91b79652012-01-17 10:12:34 +010057 % start SUA ASP
58 Fun = fun(Prim, Args) -> asp_prim_to_user(Prim, Args) end,
Harald Weltefdf26532013-07-27 14:14:08 +080059 AsPid = undefined,
Harald Welte0d8af6b2013-07-27 15:02:17 +080060 {ok, Asp} = gen_fsm:start_link(xua_asp_fsm, [AsPid, sua_asp, [], Fun, [self()], self(), Role], [{debug, [trace]}]),
Harald Welte91b79652012-01-17 10:12:34 +010061 {ok, #sua_state{asp_pid=Asp}}.
62
63terminate(Reason, _State, _LoopDat) ->
64 io:format("Terminating ~p (Reason ~p)~n", [?MODULE, Reason]),
65 ok.
66
67code_change(_OldVsn, _State, LoopDat, _Extra) ->
68 {ok, LoopDat}.
69
70handle_event(_Event, State, LoopDat) ->
71 {next_state, State, LoopDat}.
72
73handle_info(_Info, State, LoopDat) ->
74 {next_state, State, LoopDat}.
75
76%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
77% sctp_core callbacks
78%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
79
80prim_up(#primitive{subsystem='M', gen_name = 'SCTP_ESTABLISH', spec_name = confirm}, State, LoopDat) ->
81 Asp = LoopDat#sua_state.asp_pid,
82 gen_fsm:send_event(Asp, osmo_util:make_prim('M','ASP_UP',request)),
83 {ignore, LoopDat};
84prim_up(#primitive{subsystem='M', gen_name = 'ASP_UP', spec_name = confirm}, State, LoopDat) ->
85 Asp = LoopDat#sua_state.asp_pid,
86 gen_fsm:send_event(Asp, osmo_util:make_prim('M','ASP_ACTIVE',request)),
87 {ignore, LoopDat};
88prim_up(Prim, State, LoopDat) ->
89 % default: forward all primitives to the user
90 {ok, Prim, LoopDat}.
91
92
93% sctp_core indicates that ew have received some data...
94rx_sctp(#sctp_sndrcvinfo{ppid = ?SUA_PPID}, Data, State, LoopDat) ->
95 Asp = LoopDat#sua_state.asp_pid,
Harald Welte92e783d2012-04-01 19:52:01 +020096 Sua = xua_codec:parse_msg(Data),
Harald Welte91b79652012-01-17 10:12:34 +010097 case Sua of
Harald Welte92e783d2012-04-01 19:52:01 +020098 #xua_msg{msg_class = ?M3UA_MSGC_MGMT,
Harald Welte91b79652012-01-17 10:12:34 +010099 msg_type = ?M3UA_MSGT_MGMT_NTFY} ->
100 Prim = osmo_util:make_prim('M','NOTIFY',indication,Sua),
101 {ok, Prim, LoopDat};
Harald Welte92e783d2012-04-01 19:52:01 +0200102 #xua_msg{msg_class = ?M3UA_MSGC_MGMT,
Harald Welte91b79652012-01-17 10:12:34 +0100103 msg_type = ?M3UA_MSGT_MGMT_ERR} ->
104 Prim = osmo_util:make_prim('M','ERROR',indication,Sua),
105 {ok, Prim, LoopDat};
Harald Welte92e783d2012-04-01 19:52:01 +0200106 #xua_msg{msg_class = ?M3UA_MSGC_SSNM} ->
Harald Weltebd63ade2012-04-01 18:41:53 +0200107 % FIXME
Harald Welte91b79652012-01-17 10:12:34 +0100108 {ignore, LoopDat};
Harald Welte92e783d2012-04-01 19:52:01 +0200109 #xua_msg{msg_class = ?M3UA_MSGC_ASPSM} ->
Harald Welte91b79652012-01-17 10:12:34 +0100110 gen_fsm:send_event(Asp, Sua),
111 {ignore, LoopDat};
Harald Welte92e783d2012-04-01 19:52:01 +0200112 #xua_msg{msg_class = ?M3UA_MSGC_ASPTM} ->
Harald Welte91b79652012-01-17 10:12:34 +0100113 gen_fsm:send_event(Asp, Sua),
114 {ignore, LoopDat};
Harald Welte92e783d2012-04-01 19:52:01 +0200115 #xua_msg{msg_class = ?SUA_MSGC_CL} ->
Harald Weltebd63ade2012-04-01 18:41:53 +0200116 Prim = sua_to_prim(Sua, LoopDat),
117 {ok, Prim, LoopDat};
Harald Welte92e783d2012-04-01 19:52:01 +0200118 %#xua_msg{msg_class = ?SUA_MSGC_C0} ->
Harald Welte91b79652012-01-17 10:12:34 +0100119 _ ->
120 % do something with link related msgs
121 io:format("SUA Unknown message ~p in state ~p~n", [Sua, State]),
122 {ignore, State, LoopDat}
123 end.
124
125% MTP-TRANSFER.req has arrived at sctp_core, encapsulate+tx it
Harald Welte92e783d2012-04-01 19:52:01 +0200126mtp_xfer(Sua, LoopDat) when is_record(Sua, xua_msg) ->
127 SuaBin = xua_codec:encode_msg(Sua),
Harald Welte91b79652012-01-17 10:12:34 +0100128 tx_sctp(1, SuaBin),
129 LoopDat.
130
131state_change(_, established, LoopDat) ->
132 % emulate a 'start' from LSC
133 %gen_fsm:send_event(LoopDat#sua_state.lsc_pid, start),
134 LoopDat;
135state_change(established, _, LoopDat) ->
136 %gen_fsm:send_event(LoopDat#sua_state.lsc_pid, link_failure),
137 LoopDat;
138state_change(_, _, LoopDat) ->
139 LoopDat.
140
141
142%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
143% helper functions
144%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
145
146tx_sctp(Stream, Payload) when is_integer(Stream), is_binary(Payload) ->
147 Param = {Stream, ?SUA_PPID, Payload},
148 % sent to 'ourselves' (behaviour master module)
149 gen_fsm:send_event(self(), osmo_util:make_prim('SCTP','TRANSFER',request,Param)).
150
151% callback fun for ASP FMS
152asp_prim_to_user(Prim, [SctpPid]) ->
153 gen_fsm:send_event(SctpPid, Prim).
Harald Weltebd63ade2012-04-01 18:41:53 +0200154
155
Harald Welte92e783d2012-04-01 19:52:01 +0200156sua_to_prim(Sua, LoopDat) when is_record(Sua, xua_msg) ->
Harald Weltebd63ade2012-04-01 18:41:53 +0200157 Sccp = sua_sccp_conv:sua_to_sccp(Sua),
158 osmo_util:make_prim('N','UNITADATA',indication, Sccp).