Harald Welte | 91b7965 | 2012-01-17 10:12:34 +0100 | [diff] [blame] | 1 | % 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 Welte | f8bf032 | 2012-04-16 13:10:47 +0200 | [diff] [blame] | 19 | % |
| 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 Welte | 91b7965 | 2012-01-17 10:12:34 +0100 | [diff] [blame] | 33 | |
| 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 Welte | 92e783d | 2012-04-01 19:52:01 +0200 | [diff] [blame] | 40 | -include("xua.hrl"). |
Harald Welte | 91b7965 | 2012-01-17 10:12:34 +0100 | [diff] [blame] | 41 | -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 Welte | 0d8af6b | 2013-07-27 15:02:17 +0800 | [diff] [blame] | 56 | init([Role]) -> |
Harald Welte | 91b7965 | 2012-01-17 10:12:34 +0100 | [diff] [blame] | 57 | % start SUA ASP |
| 58 | Fun = fun(Prim, Args) -> asp_prim_to_user(Prim, Args) end, |
Harald Welte | fdf2653 | 2013-07-27 14:14:08 +0800 | [diff] [blame] | 59 | AsPid = undefined, |
Harald Welte | 0d8af6b | 2013-07-27 15:02:17 +0800 | [diff] [blame] | 60 | {ok, Asp} = gen_fsm:start_link(xua_asp_fsm, [AsPid, sua_asp, [], Fun, [self()], self(), Role], [{debug, [trace]}]), |
Harald Welte | 91b7965 | 2012-01-17 10:12:34 +0100 | [diff] [blame] | 61 | {ok, #sua_state{asp_pid=Asp}}. |
| 62 | |
| 63 | terminate(Reason, _State, _LoopDat) -> |
| 64 | io:format("Terminating ~p (Reason ~p)~n", [?MODULE, Reason]), |
| 65 | ok. |
| 66 | |
| 67 | code_change(_OldVsn, _State, LoopDat, _Extra) -> |
| 68 | {ok, LoopDat}. |
| 69 | |
| 70 | handle_event(_Event, State, LoopDat) -> |
| 71 | {next_state, State, LoopDat}. |
| 72 | |
| 73 | handle_info(_Info, State, LoopDat) -> |
| 74 | {next_state, State, LoopDat}. |
| 75 | |
| 76 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 77 | % sctp_core callbacks |
| 78 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 79 | |
| 80 | prim_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}; |
| 84 | prim_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}; |
| 88 | prim_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... |
| 94 | rx_sctp(#sctp_sndrcvinfo{ppid = ?SUA_PPID}, Data, State, LoopDat) -> |
| 95 | Asp = LoopDat#sua_state.asp_pid, |
Harald Welte | 92e783d | 2012-04-01 19:52:01 +0200 | [diff] [blame] | 96 | Sua = xua_codec:parse_msg(Data), |
Harald Welte | 91b7965 | 2012-01-17 10:12:34 +0100 | [diff] [blame] | 97 | case Sua of |
Harald Welte | 92e783d | 2012-04-01 19:52:01 +0200 | [diff] [blame] | 98 | #xua_msg{msg_class = ?M3UA_MSGC_MGMT, |
Harald Welte | 91b7965 | 2012-01-17 10:12:34 +0100 | [diff] [blame] | 99 | msg_type = ?M3UA_MSGT_MGMT_NTFY} -> |
| 100 | Prim = osmo_util:make_prim('M','NOTIFY',indication,Sua), |
| 101 | {ok, Prim, LoopDat}; |
Harald Welte | 92e783d | 2012-04-01 19:52:01 +0200 | [diff] [blame] | 102 | #xua_msg{msg_class = ?M3UA_MSGC_MGMT, |
Harald Welte | 91b7965 | 2012-01-17 10:12:34 +0100 | [diff] [blame] | 103 | msg_type = ?M3UA_MSGT_MGMT_ERR} -> |
| 104 | Prim = osmo_util:make_prim('M','ERROR',indication,Sua), |
| 105 | {ok, Prim, LoopDat}; |
Harald Welte | 92e783d | 2012-04-01 19:52:01 +0200 | [diff] [blame] | 106 | #xua_msg{msg_class = ?M3UA_MSGC_SSNM} -> |
Harald Welte | bd63ade | 2012-04-01 18:41:53 +0200 | [diff] [blame] | 107 | % FIXME |
Harald Welte | 91b7965 | 2012-01-17 10:12:34 +0100 | [diff] [blame] | 108 | {ignore, LoopDat}; |
Harald Welte | 92e783d | 2012-04-01 19:52:01 +0200 | [diff] [blame] | 109 | #xua_msg{msg_class = ?M3UA_MSGC_ASPSM} -> |
Harald Welte | 91b7965 | 2012-01-17 10:12:34 +0100 | [diff] [blame] | 110 | gen_fsm:send_event(Asp, Sua), |
| 111 | {ignore, LoopDat}; |
Harald Welte | 92e783d | 2012-04-01 19:52:01 +0200 | [diff] [blame] | 112 | #xua_msg{msg_class = ?M3UA_MSGC_ASPTM} -> |
Harald Welte | 91b7965 | 2012-01-17 10:12:34 +0100 | [diff] [blame] | 113 | gen_fsm:send_event(Asp, Sua), |
| 114 | {ignore, LoopDat}; |
Harald Welte | 92e783d | 2012-04-01 19:52:01 +0200 | [diff] [blame] | 115 | #xua_msg{msg_class = ?SUA_MSGC_CL} -> |
Harald Welte | bd63ade | 2012-04-01 18:41:53 +0200 | [diff] [blame] | 116 | Prim = sua_to_prim(Sua, LoopDat), |
| 117 | {ok, Prim, LoopDat}; |
Harald Welte | 92e783d | 2012-04-01 19:52:01 +0200 | [diff] [blame] | 118 | %#xua_msg{msg_class = ?SUA_MSGC_C0} -> |
Harald Welte | 91b7965 | 2012-01-17 10:12:34 +0100 | [diff] [blame] | 119 | _ -> |
| 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 Welte | 92e783d | 2012-04-01 19:52:01 +0200 | [diff] [blame] | 126 | mtp_xfer(Sua, LoopDat) when is_record(Sua, xua_msg) -> |
| 127 | SuaBin = xua_codec:encode_msg(Sua), |
Harald Welte | 91b7965 | 2012-01-17 10:12:34 +0100 | [diff] [blame] | 128 | tx_sctp(1, SuaBin), |
| 129 | LoopDat. |
| 130 | |
| 131 | state_change(_, established, LoopDat) -> |
| 132 | % emulate a 'start' from LSC |
| 133 | %gen_fsm:send_event(LoopDat#sua_state.lsc_pid, start), |
| 134 | LoopDat; |
| 135 | state_change(established, _, LoopDat) -> |
| 136 | %gen_fsm:send_event(LoopDat#sua_state.lsc_pid, link_failure), |
| 137 | LoopDat; |
| 138 | state_change(_, _, LoopDat) -> |
| 139 | LoopDat. |
| 140 | |
| 141 | |
| 142 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 143 | % helper functions |
| 144 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 145 | |
| 146 | tx_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 |
| 152 | asp_prim_to_user(Prim, [SctpPid]) -> |
| 153 | gen_fsm:send_event(SctpPid, Prim). |
Harald Welte | bd63ade | 2012-04-01 18:41:53 +0200 | [diff] [blame] | 154 | |
| 155 | |
Harald Welte | 92e783d | 2012-04-01 19:52:01 +0200 | [diff] [blame] | 156 | sua_to_prim(Sua, LoopDat) when is_record(Sua, xua_msg) -> |
Harald Welte | bd63ade | 2012-04-01 18:41:53 +0200 | [diff] [blame] | 157 | Sccp = sua_sccp_conv:sua_to_sccp(Sua), |
| 158 | osmo_util:make_prim('N','UNITADATA',indication, Sccp). |