pespin has submitted this change. ( https://gerrit.osmocom.org/c/erlang/osmo-epdg/+/35737?usp=email )
Change subject: UE-initiated detach: Do STR+STA ePDG<->AAA-Server ......................................................................
UE-initiated detach: Do STR+STA ePDG<->AAA-Server
Change-Id: I6f7554e24b26bfe191b28b56904bc8432690625d --- M src/aaa_diameter_swm.erl M src/epdg_diameter_swm.erl M src/epdg_ue_fsm.erl 3 files changed, 110 insertions(+), 10 deletions(-)
Approvals: Jenkins Builder: Verified pespin: Looks good to me, approved laforge: Looks good to me, but someone else must approve
diff --git a/src/aaa_diameter_swm.erl b/src/aaa_diameter_swm.erl index f99ae91..a3e5132 100644 --- a/src/aaa_diameter_swm.erl +++ b/src/aaa_diameter_swm.erl @@ -14,7 +14,7 @@ -export([init/1, handle_call/3, handle_cast/2, handle_info/2]). -export([code_change/3, terminate/2]).
--export([auth_request/1, auth_compl_request/2]). +-export([auth_request/1, auth_compl_request/2, session_termination_request/1]).
-define(SERVER, ?MODULE).
@@ -32,6 +32,9 @@ auth_compl_request(Imsi, Apn) -> gen_server:cast(?SERVER, {epdg_auth_compl_req, Imsi, Apn}).
+session_termination_request(Imsi) -> + gen_server:cast(?SERVER, {str, Imsi}). + handle_cast({epdg_auth_req, Imsi}, State) -> % request the diameter code for a tuple CKey = [], @@ -54,6 +57,10 @@ end, {noreply, State};
+handle_cast({str, Imsi}, State) -> + ok = epdg_diameter_swm:session_termination_answer(Imsi, 2001), + {noreply, State}; + handle_cast(Info, S) -> error_logger:error_report(["unknown handle_cast", {module, ?MODULE}, {info, Info}, {state, S}]), {noreply, S}. diff --git a/src/epdg_diameter_swm.erl b/src/epdg_diameter_swm.erl index 7c2043d..bfb8f2d 100644 --- a/src/epdg_diameter_swm.erl +++ b/src/epdg_diameter_swm.erl @@ -19,8 +19,8 @@ -export([init/1, handle_call/3, handle_cast/2, handle_info/2]). -export([code_change/3, terminate/2]).
--export([auth_request/1, auth_compl_request/2]). --export([auth_response/2, auth_compl_response/2]). +-export([auth_request/1, auth_compl_request/2, session_termination_request/1]). +-export([auth_response/2, auth_compl_response/2, session_termination_answer/2]).
-define(SERVER, ?MODULE).
@@ -52,6 +52,15 @@ _ -> Result end.
+% 3GPP TS 29.273 7.1.2.3 +session_termination_request(Imsi) -> + Result = gen_server:call(?SERVER, {str, Imsi}), + case Result of + {ok, _Mar} -> + epdg_ue_fsm:received_swm_session_terminate_answer(self(), Result), + ok; + _ -> Result + end.
handle_call({epdg_auth_req, Imsi}, {Pid, _Tag} = _From, State0) -> % we yet don't implement the Diameter SWm interface on the wire, we process the call internally: @@ -68,6 +77,17 @@ undefined -> Reply = {error,unknown_imsi} end, + {reply, Reply, State}; + +handle_call({str, Imsi}, _From, State) -> + % we yet don't implement the Diameter SWm interface on the wire, we process the call internally: + Sess = find_swm_session_by_imsi(Imsi, State), + case Sess of + #swm_session{imsi = Imsi} -> + Reply = aaa_diameter_swm:session_termination_request(Imsi); + undefined -> + Reply = {error,unknown_imsi} + end, {reply, Reply, State}.
handle_cast({epdg_auth_resp, Imsi, Result}, State) -> @@ -90,6 +110,16 @@ end, {noreply, State};
+handle_cast({sta, Imsi, Result}, State) -> + Sess = find_swm_session_by_imsi(Imsi, State), + case Sess of + #swm_session{imsi = Imsi} -> + epdg_ue_fsm:received_swm_session_termination_answer(Sess#swm_session.pid, Result); + undefined -> + error_logger:error_report(["unknown swm_session", {module, ?MODULE}, {imsi, Imsi}, {state, State}]) + end, + {noreply, State}; + handle_cast(Info, S) -> error_logger:error_report(["unknown handle_cast", {module, ?MODULE}, {info, Info}, {state, S}]), {noreply, S}. @@ -116,6 +146,10 @@ auth_compl_response(Imsi, Result) -> ok = gen_server:cast(?SERVER, {epdg_auth_compl_resp, Imsi, Result}).
+% Rx SWm Diameter STA: +session_termination_answer(Imsi, Result) -> + ok = gen_server:cast(?SERVER, {sta, Imsi, Result}). + %% ------------------------------------------------------------------ %% Internal Function Definitions %% ------------------------------------------------------------------ diff --git a/src/epdg_ue_fsm.erl b/src/epdg_ue_fsm.erl index 1d934c5..3e9d1be 100644 --- a/src/epdg_ue_fsm.erl +++ b/src/epdg_ue_fsm.erl @@ -40,13 +40,15 @@ -export([start_link/1]). -export([init/1,callback_mode/0,terminate/3]). -export([auth_request/1, lu_request/1, tunnel_request/1, purge_ms_request/1]). --export([received_swm_auth_response/2, received_swm_auth_compl_response/2]). +-export([received_swm_auth_response/2, received_swm_auth_compl_response/2, received_swm_session_termination_answer/2]). -export([received_gtpc_create_session_response/2, received_gtpc_delete_session_response/2]). --export([state_new/3, state_wait_auth_resp/3, state_authenticating/3, state_authenticated/3, state_wait_delete_session_resp/3]). +-export([state_new/3, state_wait_auth_resp/3, state_authenticating/3, state_authenticated/3, + state_wait_delete_session_resp/3, state_wait_swm_session_termination_answer/3]).
-record(ue_fsm_data, { imsi, - apn = "internet" :: string() + apn = "internet" :: string(), + tear_down_gsup_cause = 0 :: integer() }).
start_link(Imsi) -> @@ -108,6 +110,15 @@ {error, Err} end.
+received_swm_session_termination_answer(Pid, Result) -> + lager:info("ue_fsm received_swm_session_termination_answer ~p~n", [Result]), + try + gen_statem:call(Pid, {received_swm_sta, Result}) + catch + exit:Err -> + {error, Err} + end. + received_gtpc_create_session_response(Pid, Msg) -> lager:info("ue_fsm received_gtpc_create_session_response ~p~n", [Msg]), try @@ -140,12 +151,15 @@ {ok, state_new, Data}.
callback_mode() -> - state_functions. + [state_functions, state_enter].
terminate(Reason, State, Data) -> lager:info("terminating ~p with reason ~p state=~p, ~p~n", [?MODULE, Reason, State, Data]), ok.
+state_new(enter, _OldState, Data) -> + {keep_state, Data}; + state_new({call, From}, auth_request, Data) -> lager:info("ue_fsm state_new event=auth_request, ~p~n", [Data]), case epdg_diameter_swm:auth_request(Data#ue_fsm_data.imsi) of @@ -157,6 +171,9 @@ lager:info("ue_fsm state_new event=purge_ms_request, ~p~n", [Data]), {stop_and_reply, purge_ms_request, Data, [{reply,From,ok}]}.
+state_wait_auth_resp(enter, _OldState, Data) -> + {keep_state, Data}; + state_wait_auth_resp({call, From}, {received_swm_auth_response, Auth}, Data) -> lager:info("ue_fsm state_wait_auth_resp event=received_swm_auth_response, ~p~n", [Data]), gsup_server:auth_response(Data#ue_fsm_data.imsi, Auth), @@ -169,6 +186,9 @@ {next_state, state_new, Data, [{reply,From,{error,unknown}}]} end.
+state_authenticating(enter, _OldState, Data) -> + {keep_state, Data}; + state_authenticating({call, From}, lu_request, Data) -> lager:info("ue_fsm state_authenticating event=lu_request, ~p~n", [Data]), % Rx "GSUP CEAI LU Req" is our way of saying Rx "Swm Diameter-EAP REQ (DER) with EAP AVP containing successuful auth": @@ -191,6 +211,9 @@ gsup_server:lu_response(Data#ue_fsm_data.imsi, Ret), {next_state, state_authenticated, Data, [{reply,From,Ret}]}.
+state_authenticated(enter, _OldState, Data) -> + {keep_state, Data}; + state_authenticated({call, From}, tunnel_request, Data) -> lager:info("ue_fsm state_authenticated event=tunnel_request, ~p~n", [Data]), epdg_gtpc_s2b:create_session_req(Data#ue_fsm_data.imsi), @@ -216,6 +239,9 @@ lager:error("ue_fsm state_authenticated: Unexpected cast event, ~p~n", [Data]), {keep_state, Data}.
+state_wait_delete_session_resp(enter, _OldState, Data) -> + {keep_state, Data}; + state_wait_delete_session_resp({call, From}, {received_gtpc_delete_session_response, _Resp = #gtp{version = v2, type = delete_session_response, ie = IEs}}, Data) -> lager:info("ue_fsm state_wait_delete_session_resp event=received_gtpc_delete_session_response, ~p~n", [Data]), #{{v2_cause,0} := CauseIE} = IEs, @@ -223,11 +249,35 @@ GsupCause = conv:cause_gtp2gsup(GtpCause), lager:debug("Cause: GTP_atom=~p -> GTP_int=~p -> GSUP_int=~p~n", [CauseIE#v2_cause.v2_cause, GtpCause, GsupCause]), case GsupCause of - 0 -> gsup_server:purge_ms_response(Data#ue_fsm_data.imsi, ok); - _ -> gsup_server:purge_ms_response(Data#ue_fsm_data.imsi, {error, GsupCause}) + 0 -> Data1 = Data; + _ -> Data1 = Data#ue_fsm_data{tear_down_gsup_cause = GsupCause} + end, + {next_state, state_wait_swm_session_termination_answer, Data1, [{reply,From,ok}]}; + +state_wait_delete_session_resp({call, From}, Event, Data) -> + lager:error("ue_fsm state_wait_delete_session_resp: Unexpected call event ~p, ~p~n", [Event, Data]), + {keep_state, Data, [{reply,From,{error,unexpected_event}}]}. + +state_wait_swm_session_termination_answer(enter, _OldState, Data) -> + % TODO: Send STR towards AAA-Server + % % 3GPP TS 29.273 7.1.2.3 + lager:info("ue_fsm state_wait_swm_session_termination_answer event=enter, ~p~n", [Data]), + case epdg_diameter_swm:session_termination_request(Data#ue_fsm_data.imsi) of + ok -> {keep_state, Data}; + {error, _Err} -> + gsup_server:purge_ms_response(Data#ue_fsm_data.imsi, {error, ?GSUP_CAUSE_NET_FAIL}), + {keep_state, Data} + end; + +state_wait_swm_session_termination_answer({call, From}, {received_swm_sta, DiaResultCode}, Data) -> + lager:info("ue_fsm state_wait_swm_session_termination_answer event=received_swm_sta, ~p~n", [Data]), + case {DiaResultCode, Data#ue_fsm_data.tear_down_gsup_cause} of + {2001, 0} -> gsup_server:purge_ms_response(Data#ue_fsm_data.imsi, ok); + {2001, _} -> gsup_server:purge_ms_response(Data#ue_fsm_data.imsi, {error, Data#ue_fsm_data.tear_down_gsup_cause}); + _ -> gsup_server:purge_ms_response(Data#ue_fsm_data.imsi, {error, ?GSUP_CAUSE_NET_FAIL}) end, {keep_state, Data, [{reply,From,ok}]};
-state_wait_delete_session_resp({call, From}, Event, Data) -> +state_wait_swm_session_termination_answer({call, From}, Event, Data) -> lager:error("ue_fsm state_wait_delete_session_resp: Unexpected call event ~p, ~p~n", [Event, Data]), {keep_state, Data, [{reply,From,{error,unexpected_event}}]}.