fixeria has uploaded this change for review.

View Change

erab_fsm: add erab_release/2 and erab_release_ind/1

The E-RAB RELEASE INDICATION message is used by the eNB to indicate
termination of one or several E-RAB(s). Unlike with the RELEASE
COMMAND, there is no response to that message. Thus, we shall not
wait for it (by entering state erab_wait_release_rsp) but terminate
the E-RAB FSM immediately instead.

Change-Id: Icc9c0f6a1aef327e9585942b3c9d2302feda393a
---
M src/erab_fsm.erl
M test/erab_fsm_test.erl
2 files changed, 51 insertions(+), 9 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-s1gw refs/changes/66/38766/1
diff --git a/src/erab_fsm.erl b/src/erab_fsm.erl
index fb6def3..f185867 100644
--- a/src/erab_fsm.erl
+++ b/src/erab_fsm.erl
@@ -49,8 +49,10 @@
-export([start_link/1,
erab_setup_req/2,
erab_setup_rsp/2,
+ erab_release/2,
erab_release_cmd/1,
erab_release_rsp/1,
+ erab_release_ind/1,
shutdown/1]).

-include_lib("kernel/include/logger.hrl").
@@ -70,13 +72,16 @@
addr() %% GTP-U Transport Layer Address
}.

+-type rel_kind() :: cmd | ind.
+
-record(erab_state, {from :: undefined | gen_statem:from(), %% destination to use when replying
u2c :: undefined | teid_addr(), %% GTP-U params for UPF -> Core
c2u :: undefined | teid_addr(), %% GTP-U params for UPF <- Core
a2u :: undefined | teid_addr(), %% GTP-U params for UPF <- Access
u2a :: undefined | teid_addr(), %% GTP-U params for UPF -> Access
seid_loc :: undefined | pfcp_peer:pfcp_seid(), %% local SEID, chosen by us
- seid_rem :: undefined | pfcp_peer:pfcp_seid() %% remote SEID, chosen by the UPF
+ seid_rem :: undefined | pfcp_peer:pfcp_seid(), %% remote SEID, chosen by the UPF
+ rel_kind :: undefined | rel_kind() %% E-RAB RELEASE kind
}).

-type erab_state() :: #erab_state{}.
@@ -120,6 +125,13 @@
gen_statem:call(Pid, {?FUNCTION_NAME, F_TEID}).


+-spec erab_release(pid(), rel_kind()) -> ok.
+erab_release(Pid, cmd) ->
+ erab_release_cmd(Pid);
+erab_release(Pid, ind) ->
+ erab_release_ind(Pid).
+
+
-spec erab_release_cmd(pid()) -> ok.
erab_release_cmd(Pid) ->
gen_statem:call(Pid, ?FUNCTION_NAME).
@@ -130,6 +142,11 @@
gen_statem:cast(Pid, ?FUNCTION_NAME).


+-spec erab_release_ind(pid()) -> ok.
+erab_release_ind(Pid) ->
+ gen_statem:call(Pid, ?FUNCTION_NAME).
+
+
-spec shutdown(pid()) -> ok.
shutdown(Pid) ->
gen_statem:stop(Pid).
@@ -290,7 +307,16 @@
#erab_state{} = S) ->
?LOG_DEBUG("Rx E-RAB RELEASE Req"),
{next_state, session_delete,
- S#erab_state{from = From}};
+ S#erab_state{from = From,
+ rel_kind = cmd}};
+
+erab_setup({call, From},
+ erab_release_ind,
+ #erab_state{} = S) ->
+ ?LOG_DEBUG("Rx E-RAB RELEASE Ind"),
+ {next_state, session_delete,
+ S#erab_state{from = From,
+ rel_kind = ind}};

%% Catch-all handler for this state
erab_setup(Event, EventData, S) ->
@@ -317,15 +343,22 @@

session_delete(info, #pfcp{} = PDU,
#erab_state{from = From,
- seid_loc = SEID_Rsp} = S) ->
+ seid_loc = SEID_Rsp,
+ rel_kind = RelKind} = S) ->
case PDU of
#pfcp{type = session_deletion_response,
seid = SEID_Rsp, %% matches F-SEID we sent in the ESTABLISH Req
ie = #{pfcp_cause := 'Request accepted'}} ->
?LOG_DEBUG("PFCP session deleted"),
- {next_state, erab_wait_release_rsp,
- S#erab_state{from = undefined},
- [{reply, From, ok}]};
+ Reply = {reply, From, ok},
+ case RelKind of
+ cmd -> %% E-RAB RELEASE CMD => wait for the RSP
+ {next_state, erab_wait_release_rsp,
+ S#erab_state{from = undefined},
+ [Reply]};
+ ind -> %% E-RAB RELEASE IND => terminate immediately
+ {stop_and_reply, normal, [Reply]}
+ end;
_ ->
?LOG_ERROR("Rx unexpected PFCP PDU: ~p", [PDU]),
{stop_and_reply,
diff --git a/test/erab_fsm_test.erl b/test/erab_fsm_test.erl
index e4b036e..0bd6b8b 100644
--- a/test/erab_fsm_test.erl
+++ b/test/erab_fsm_test.erl
@@ -44,8 +44,10 @@


erab_release_test_() ->
- [{"E-RAB release :: success",
- ?TC(fun test_erab_release_success/1)},
+ [{"E-RAB RELEASE CMD :: success",
+ ?TC(fun test_erab_release_cmd_success/1)},
+ {"E-RAB RELEASE IND :: success",
+ ?TC(fun test_erab_release_ind_success/1)},
{"E-RAB release :: PFCP session deletion error",
?TC(fun test_erab_release_pfcp_delete_error/1)}].

@@ -91,7 +93,7 @@
?_assertNot(erlang:is_process_alive(Pid))].


-test_erab_release_success(Pid) ->
+test_erab_release_cmd_success(Pid) ->
[?_assertEqual({ok, ?A2U}, erab_fsm:erab_setup_req(Pid, ?U2C)),
?_assertEqual({ok, ?C2U}, erab_fsm:erab_setup_rsp(Pid, ?U2A)),
?_assertEqual(ok, erab_fsm:erab_release_cmd(Pid)),
@@ -99,6 +101,13 @@
?_assertNot(erlang:is_process_alive(Pid))].


+test_erab_release_ind_success(Pid) ->
+ [?_assertEqual({ok, ?A2U}, erab_fsm:erab_setup_req(Pid, ?U2C)),
+ ?_assertEqual({ok, ?C2U}, erab_fsm:erab_setup_rsp(Pid, ?U2A)),
+ ?_assertEqual(ok, erab_fsm:erab_release_ind(Pid)),
+ ?_assertNot(erlang:is_process_alive(Pid))].
+
+
test_erab_release_pfcp_delete_error(Pid) ->
%% pfcp_peer:session_delete_req/1 responds with a reject
PDU = pfcp_mock:pdu_rsp_reject(session_deletion_response, ?SEID_Loc),

To view, visit change 38766. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: newchange
Gerrit-Project: erlang/osmo-s1gw
Gerrit-Branch: master
Gerrit-Change-Id: Icc9c0f6a1aef327e9585942b3c9d2302feda393a
Gerrit-Change-Number: 38766
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <vyanitskiy@sysmocom.de>