Compare commits
6 Commits
74fff9f574
...
859807eb7f
Author | SHA1 | Date |
---|---|---|
Pau Espin | 859807eb7f | |
Pau Espin | 0d09d1e568 | |
Pau Espin | 56fd123844 | |
Pau Espin | c5ba31465d | |
Pau Espin | 57e2eb47a9 | |
Pau Espin | bc53ecd5ad |
|
@ -1,5 +1,5 @@
|
|||
#!/bin/sh -ex
|
||||
|
||||
rebar3 compile
|
||||
rebar3 escriptize
|
||||
rebar3 eunit
|
||||
make clean || true
|
||||
make
|
||||
make check
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
%
|
||||
-hrl_name('conv.hrl').
|
||||
|
||||
-define(VENDOR_ID_3GPP, 10415).
|
||||
|
||||
%% Can Hold information about Result-Code or Experimental-Result:
|
||||
-record(epdg_dia_rc, {
|
||||
vendor_id :: non_neg_integer(), %% or undefined if Result-Code
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
{osmo_gsup, {git, "https://gerrit.osmocom.org/erlang/osmo_gsup", {branch, "osmocom/epdg"}}}
|
||||
]}.
|
||||
|
||||
{minimum_otp_vsn, "20.3"}.
|
||||
{minimum_otp_vsn, "25.2.3"}.
|
||||
{plugins, [
|
||||
{rebar3_diameter_compiler,
|
||||
{git, "https://github.com/carlosedp/rebar3_diameter_compiler.git", {tag, "0.8.0"}}}
|
||||
|
|
|
@ -47,12 +47,9 @@
|
|||
-export([start_link/0]).
|
||||
-export([start/0, stop/0, terminate/2]).
|
||||
%% gen_server Function Exports
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2]).
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, peer_down/3]).
|
||||
-export([code_change/3]).
|
||||
-export([multimedia_auth_request/6]).
|
||||
-export([server_assignment_request/3]).
|
||||
-export([tx_aa_answer/2, tx_st_answer/2]).
|
||||
-export([test/0, test/1]).
|
||||
|
||||
%% Diameter Application Definitions
|
||||
-define(SERVER, ?MODULE).
|
||||
|
@ -96,11 +93,6 @@
|
|||
{module, ?CALLBACK_MOD},
|
||||
{answer_errors, callback}]}]).
|
||||
|
||||
-record(state, {
|
||||
handlers,
|
||||
peers = #{}
|
||||
}).
|
||||
|
||||
%% @doc starts gen_server implementation process
|
||||
-spec start() -> ok | {error, term()}.
|
||||
start() ->
|
||||
|
@ -115,9 +107,7 @@ stop() ->
|
|||
start_link() ->
|
||||
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
|
||||
|
||||
peer_down(API, SvcName, {PeerRef, _} = Peer) ->
|
||||
% fixme: why do we still have ets here?
|
||||
(catch ets:delete(?MODULE, {API, PeerRef})),
|
||||
peer_down(_API, SvcName, {_PeerRef, _} = Peer) ->
|
||||
gen_server:cast(?SERVER, {peer_down, SvcName, Peer}),
|
||||
ok.
|
||||
|
||||
|
@ -133,20 +123,6 @@ init(State) ->
|
|||
{ok, _} = listen({address, Proto, Ip, Port}, {timer, ConnectTimer, WatchdogTimer, WatchdogConfig}),
|
||||
{ok, State}.
|
||||
|
||||
test() ->
|
||||
test("001011234567890").
|
||||
|
||||
test(IMSI) ->
|
||||
multimedia_auth_request(IMSI, 3, "EAP-AKA", 1, [], []).
|
||||
|
||||
multimedia_auth_request(IMSI, NumAuthItems, AuthScheme, RAT, CKey, IntegrityKey) ->
|
||||
gen_server:call(?SERVER,
|
||||
{mar, {IMSI, NumAuthItems, AuthScheme, RAT, CKey, IntegrityKey}}).
|
||||
% APN is optional and should be []
|
||||
server_assignment_request(IMSI, Type, APN) ->
|
||||
gen_server:call(?SERVER,
|
||||
{sar, {IMSI, Type, APN}}).
|
||||
|
||||
tx_aa_answer(Pid, DiaRC) ->
|
||||
% handle_request(AAR) was spawned into its own process, and it's blocked waiting for AAA:
|
||||
Pid ! {aaa, DiaRC}.
|
||||
|
@ -155,12 +131,8 @@ tx_st_answer(Pid, DiaRC) ->
|
|||
% handle_request(STR) was spawned into its own process, and it's blocked waiting for STA:
|
||||
Pid ! {sta, DiaRC}.
|
||||
|
||||
result_code_success(2001) -> ok;
|
||||
result_code_success(2002) -> ok;
|
||||
result_code_success(_) -> invalid_result_code.
|
||||
|
||||
handle_call({aar, {IMSI, Type, APN}}, _From, State) ->
|
||||
SessionId = diameter:session_id(application:get_env(?ENV_APP_NAME, origin_host, ?ENV_DEFAULT_ORIG_HOST)).
|
||||
handle_call(Info, _From, State) ->
|
||||
error_logger:error_report(["unknown handle_call", {module, ?MODULE}, {info, Info}, {state, State}]).
|
||||
|
||||
%% @callback gen_server
|
||||
handle_cast(stop, State) ->
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
%% diameter callbacks
|
||||
-export([peer_up/3, peer_down/3, pick_peer/4, pick_peer/5, prepare_request/3, prepare_request/4,
|
||||
prepare_retransmit/3, prepare_retransmit/4,
|
||||
handle_answer/4, handle_answer/5, handle_error/4, handle_error/5, handle_request/3]).
|
||||
handle_request/3,
|
||||
handle_answer/4, handle_answer/5, handle_error/4, handle_error/5]).
|
||||
|
||||
%% peer_up/3
|
||||
peer_up(_SvcName, Peer, State) ->
|
||||
|
@ -67,6 +68,41 @@ prepare_retransmit(Packet, SvcName, Peer) ->
|
|||
prepare_retransmit(Packet, SvcName, Peer, ExtraPars) ->
|
||||
prepare_request(Packet, SvcName, Peer, ExtraPars).
|
||||
|
||||
%% handle_request/3
|
||||
|
||||
%% 3GPP TS 29.273 8.2.2.4 Network Initiated De-Registration by HSS Procedure
|
||||
handle_request(#diameter_packet{msg = Req, errors = []}, _SvcName, {_, Caps}) when is_record(Req, 'RTR') ->
|
||||
lager:info("SWx Rx RTR from ~p: ~p~n", [Caps, Req]),
|
||||
#diameter_caps{origin_host = {OH,_}, origin_realm = {OR,_}} = Caps,
|
||||
#'RTR'{'Session-Id' = SessionId,
|
||||
'Vendor-Specific-Application-Id' = VendorAppId,
|
||||
'Auth-Session-State' = AuthSessState,
|
||||
'User-Name' = Imsi,
|
||||
'Deregistration-Reason' = _DeregReason} = Req,
|
||||
case aaa_ue_fsm:get_pid_by_imsi(Imsi) of
|
||||
Pid when is_pid(Pid) ->
|
||||
aaa_ue_fsm:stop(Pid),
|
||||
Res = 2001, %% Success
|
||||
ERes = [];
|
||||
undefined ->
|
||||
Res = [],
|
||||
%% TS 29.229 6.2.2.1 DIAMETER_ERROR_USER_UNKNOWN
|
||||
ERes = #'Experimental-Result'{'Vendor-Id' = ?VENDOR_ID_3GPP, 'Experimental-Result-Code' = 5001}
|
||||
end,
|
||||
Resp = #'RTA'{'Session-Id' = SessionId,
|
||||
'Vendor-Specific-Application-Id' = VendorAppId,
|
||||
'Result-Code' = Res,
|
||||
'Experimental-Result' = ERes,
|
||||
'Auth-Session-State' = AuthSessState,
|
||||
'Origin-Host' = OH,
|
||||
'Origin-Realm' = OR},
|
||||
lager:info("SWx Tx to ~p: ~p~n", [Caps, Resp]),
|
||||
{reply, Resp};
|
||||
|
||||
handle_request(Msg, _SvcName, Peer) ->
|
||||
lager:error("SWx Rx unexpected msg from ~p: ~p~n", [Peer, Msg]),
|
||||
erlang:error({unexpected, ?MODULE, ?LINE}).
|
||||
|
||||
%% handle_answer/4
|
||||
handle_answer(#diameter_packet{msg = Msg, errors = Errors}, _Request, _SvcName, Peer, ReqPid) when is_record(Msg, 'MAA') ->
|
||||
lager:info("SWx Rx MAA ~p: ~p/ Errors ~p ~n", [Peer, Msg, Errors]),
|
||||
|
@ -82,6 +118,7 @@ handle_answer(#diameter_packet{msg = Msg, errors = Errors}, _Request, _SvcName,
|
|||
aaa_ue_fsm:ev_rx_swx_maa(ReqPid, {error, DiaRC})
|
||||
end,
|
||||
{ok, Msg};
|
||||
|
||||
handle_answer(#diameter_packet{msg = Msg, errors = Errors}, Request, _SvcName, Peer, ReqPid) when is_record(Msg, 'SAA') ->
|
||||
lager:info("SWx Rx SAA ~p: ~p/ Errors ~p ~n", [Peer, Msg, Errors]),
|
||||
% Recover fields from originating request:
|
||||
|
@ -103,9 +140,11 @@ handle_answer(#diameter_packet{msg = Msg, errors = Errors}, Request, _SvcName, P
|
|||
aaa_ue_fsm:ev_rx_swx_saa(ReqPid, {error, SAType, DiaRC})
|
||||
end,
|
||||
{ok, Msg}.
|
||||
|
||||
handle_answer(#diameter_packet{msg = Msg, errors = []}, _Request, _SvcName, Peer) ->
|
||||
lager:info("SWx Rx ~p: ~p~n", [Peer, Msg]),
|
||||
{ok, Msg};
|
||||
|
||||
handle_answer(#diameter_packet{msg = Msg, errors = Errors}, _Request, _SvcName, Peer) ->
|
||||
lager:info("SWx Rx ~p: ~p / Errors ~p ~n", [Peer, Msg, Errors]),
|
||||
{error, Errors}.
|
||||
|
@ -122,10 +161,6 @@ handle_error(Reason, _Request, _SvcName, _Peer, ExtraPars) ->
|
|||
lager:error("SWx error: ~p, ExtraPars: ~p~n", [Reason, ExtraPars]),
|
||||
{error, Reason}.
|
||||
|
||||
%% handle_request/3
|
||||
handle_request(_Packet, _SvcName, _Peer) ->
|
||||
erlang:error({unexpected, ?MODULE, ?LINE}).
|
||||
|
||||
%% ------------------------------------------------------------------
|
||||
%% Internal Function Definitions
|
||||
%% ------------------------------------------------------------------
|
||||
|
|
|
@ -179,7 +179,7 @@ received_gtpc_delete_bearer_request(Pid) ->
|
|||
ev_handle({call, From}, {auth_request, PdpTypeNr, Apn, EAP}, Data) ->
|
||||
case epdg_diameter_swm:auth_request(Data#ue_fsm_data.imsi, PdpTypeNr, Apn, EAP) of
|
||||
ok -> {next_state, state_wait_auth_resp, Data, [{reply,From,ok}]};
|
||||
{error, Err} -> {stop_and_reply, Err, Data, [{reply,From,{error,Err}}]}
|
||||
{error, Err} -> {stop_and_reply, Err, [{reply,From,{error,Err}}], Data}
|
||||
end.
|
||||
|
||||
%% ------------------------------------------------------------------
|
||||
|
@ -211,7 +211,7 @@ state_new({call, _From} = EvType, {auth_request, PdpTypeNr, Apn, EAP} = EvConten
|
|||
|
||||
state_new({call, From}, purge_ms_request, Data) ->
|
||||
lager:info("ue_fsm state_new event=purge_ms_request, ~p~n", [Data]),
|
||||
{stop_and_reply, purge_ms_request, Data, [{reply,From,ok}]}.
|
||||
{stop_and_reply, purge_ms_request, [{reply,From,ok}], Data}.
|
||||
|
||||
state_wait_auth_resp(enter, _OldState, Data) ->
|
||||
{keep_state, Data};
|
||||
|
@ -242,7 +242,7 @@ state_authenticating({call, From}, lu_request, Data) ->
|
|||
% Rx "GSUP CEAI LU Req" is our way of saying Rx "Swm Diameter-EAP REQ (DER) with EAP AVP containing successuful auth":
|
||||
case epdg_diameter_swm:auth_compl_request(Data#ue_fsm_data.imsi, Data#ue_fsm_data.apn) of
|
||||
ok -> {keep_state, Data, [{reply,From,ok}]};
|
||||
{error, Err} -> {stop_and_reply, Err, Data, [{reply,From,{error,Err}}]}
|
||||
{error, Err} -> {stop_and_reply, Err, [{reply,From,{error,Err}}], Data}
|
||||
end;
|
||||
|
||||
% Rx Swm Diameter-EAP Answer (DEA) containing APN-Configuration, triggered by
|
||||
|
|
|
@ -260,7 +260,7 @@ purge_ms_response(Imsi, Result) ->
|
|||
|
||||
% Our GSUP CEAI implementation for "IKEv2 Information Delete Request"
|
||||
cancel_location_request(Imsi) ->
|
||||
lager:info("cancel_location_request(~p): ~p~n", [Imsi]),
|
||||
lager:info("cancel_location_request(~p)~n", [Imsi]),
|
||||
gen_server:cast(?SERVER, {cancel_location_request, Imsi}).
|
||||
|
||||
%% ------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue