pespin submitted this change.

View Change


Approvals: laforge: Looks good to me, but someone else must approve pespin: Looks good to me, approved Jenkins Builder: Verified
Use call() instead of cast() in ue_fsm

This allows accounting for problems in the FSM from the calling code,
and act accordingly, eg. rejecting a message.

Change-Id: I235d3c8fb3a863d288b5433c39e0da65f747936b
---
M src/gsup_server.erl
M src/ue_fsm.erl
2 files changed, 90 insertions(+), 27 deletions(-)

diff --git a/src/gsup_server.erl b/src/gsup_server.erl
index 521d4c3..30e8864 100644
--- a/src/gsup_server.erl
+++ b/src/gsup_server.erl
@@ -202,9 +202,18 @@
{noreply, S#gsups_state{socket=Socket}};

% send auth info / requesting authentication tuples
-handle_info({ipa, _Socket, ?IPAC_PROTO_EXT_GSUP, _GsupMsgRx = #{message_type := send_auth_info_req, imsi := Imsi}}, State0) ->
+handle_info({ipa, Socket, ?IPAC_PROTO_EXT_GSUP, _GsupMsgRx = #{message_type := send_auth_info_req, imsi := Imsi}}, State0) ->
{UE, State1} = find_or_new_gsups_ue(Imsi, State0),
- ue_fsm:auth_request(UE#gsups_ue.pid),
+ case ue_fsm:auth_request(UE#gsups_ue.pid) of
+ ok -> ok;
+ {error, _} ->
+ Resp = #{message_type => send_auth_info_err,
+ imsi => Imsi,
+ message_class => 5,
+ cause => ?GSUP_CAUSE_NET_FAIL
+ },
+ tx_gsup(Socket, Resp)
+ end,
{noreply, State1};

% location update request / when a UE wants to connect to a specific APN. This will trigger a AAA->HLR Request Server Assignment Request
@@ -212,15 +221,24 @@
handle_info({ipa, Socket, ?IPAC_PROTO_EXT_GSUP, _GsupMsgRx = #{message_type := location_upd_req, imsi := Imsi}}, State) ->
UE = find_gsups_ue_by_imsi(Imsi, State),
case UE of
- #gsups_ue{imsi = Imsi} ->
- ue_fsm:lu_request(UE#gsups_ue.pid);
- undefined ->
+ #gsups_ue{imsi = Imsi} ->
+ case ue_fsm:lu_request(UE#gsups_ue.pid) of
+ ok -> ok;
+ {error, _} ->
Resp = #{message_type => location_upd_err,
imsi => Imsi,
message_class => 5,
- cause => ?GSUP_CAUSE_IMSI_UNKNOWN
+ cause => ?GSUP_CAUSE_NET_FAIL
},
tx_gsup(Socket, Resp)
+ end;
+ undefined ->
+ Resp = #{message_type => location_upd_err,
+ imsi => Imsi,
+ message_class => 5,
+ cause => ?GSUP_CAUSE_IMSI_UNKNOWN
+ },
+ tx_gsup(Socket, Resp)
end,
{noreply, State};

@@ -230,15 +248,24 @@
lager:info("GSUP: Rx ~p~n", [GsupMsgRx]),
UE = find_gsups_ue_by_imsi(Imsi, State),
case UE of
- #gsups_ue{imsi = Imsi} ->
- ue_fsm:tunnel_request(UE#gsups_ue.pid);
- undefined ->
+ #gsups_ue{imsi = Imsi} ->
+ case ue_fsm:tunnel_request(UE#gsups_ue.pid) of
+ ok -> ok;
+ {error, _} ->
Resp = #{message_type => epdg_tunnel_error,
- imsi => Imsi,
- message_class => 5,
- cause => ?GSUP_CAUSE_IMSI_UNKNOWN
+ imsi => Imsi,
+ message_class => 5,
+ cause => ?GSUP_CAUSE_NET_FAIL
},
tx_gsup(Socket, Resp)
+ end;
+ undefined ->
+ Resp = #{message_type => epdg_tunnel_error,
+ imsi => Imsi,
+ message_class => 5,
+ cause => ?GSUP_CAUSE_IMSI_UNKNOWN
+ },
+ tx_gsup(Socket, Resp)
end,
{noreply, State};

diff --git a/src/ue_fsm.erl b/src/ue_fsm.erl
index f6b2b7e..c0b8872 100644
--- a/src/ue_fsm.erl
+++ b/src/ue_fsm.erl
@@ -50,19 +50,39 @@

auth_request(Pid) ->
lager:info("ue_fsm auth_request~n", []),
- gen_statem:cast(Pid, auth_request).
+ try
+ gen_statem:call(Pid, auth_request)
+ catch
+ exit:Err ->
+ {error, Err}
+ end.

lu_request(Pid) ->
lager:info("ue_fsm lu_request~n", []),
- gen_statem:cast(Pid, lu_request).
+ try
+ gen_statem:call(Pid, lu_request)
+ catch
+ exit:Err ->
+ {error, Err}
+ end.

tunnel_request(Pid) ->
lager:info("ue_fsm tunnel_request~n", []),
- gen_statem:cast(Pid, tunnel_request).
+ try
+ gen_statem:call(Pid, tunnel_request)
+ 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]),
- gen_statem:cast(Pid, {received_gtpc_create_session_response, Msg}).
+ try
+ gen_statem:call(Pid, {received_gtpc_create_session_response, Msg})
+ catch
+ exit:Err ->
+ {error, Err}
+ end.

init(Imsi) ->
lager:info("ue_fsm init(~p)~n", [Imsi]),
@@ -76,38 +96,42 @@
lager:info("terminating ~p with reason ~p state=~p, ~p~n", [?MODULE, Reason, State, Data]),
ok.

-state_new(cast, auth_request, Data) ->
+state_new({call, From}, auth_request, Data) ->
lager:info("ue_fsm state_new event=auth_request, ~p~n", [Data]),
Auth = auth_handler:auth_request(Data#ue_fsm_data.imsi),
gsup_server:auth_response(Data#ue_fsm_data.imsi, Auth),
case Auth of
{ok, _} ->
- {next_state, state_authenticated, Data};
+ {next_state, state_authenticated, Data, [{reply,From,ok}]};
{error, Err} ->
- {stop, Err, Data}
+ {stop_and_reply, Err, Data, [{reply,From,{error,Err}}]}
end.

-state_authenticated(cast, lu_request, Data) ->
+state_authenticated({call, From}, lu_request, Data) ->
lager:info("ue_fsm state_authenticated event=lu_request, ~p~n", [Data]),
Result = epdg_diameter_swx:server_assignment_request(Data#ue_fsm_data.imsi, 1, "internet"),
gsup_server:lu_response(Data#ue_fsm_data.imsi, Result),
case Result of
{ok, _} ->
- {keep_state, Data};
+ {keep_state, Data, [{reply,From,ok}]};
{error, Err} ->
- {stop, Err, Data}
+ {stop, Err, Data, [{reply,From,{error,Err}}]}
end;

-state_authenticated(cast, tunnel_request, 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),
- {keep_state, Data};
+ {keep_state, Data, [{reply,From,ok}]};

-state_authenticated(cast, {received_gtpc_create_session_response, Result}, Data) ->
+state_authenticated({call, From}, {received_gtpc_create_session_response, Result}, Data) ->
lager:info("ue_fsm state_authenticated event=received_gtpc_create_session_response, ~p~n", [Data]),
gsup_server:tunnel_response(Data#ue_fsm_data.imsi, Result),
- {keep_state, Data};
+ {keep_state, Data, [{reply,From,ok}]};
+
+state_authenticated({call, From}, _Whatever, Data) ->
+ lager:error("ue_fsm state_authenticated: Unexpected call event, ~p~n", [Data]),
+ {keep_state, Data, [{reply,From,ok}]};

state_authenticated(cast, _Whatever, Data) ->
- lager:info("ue_fsm state_authenticated event=auth_request, ~p~n", [Data]),
+ lager:error("ue_fsm state_authenticated: Unexpected cast event, ~p~n", [Data]),
{keep_state, Data}.
\ No newline at end of file

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

Gerrit-Project: erlang/osmo-epdg
Gerrit-Branch: master
Gerrit-Change-Id: I235d3c8fb3a863d288b5433c39e0da65f747936b
Gerrit-Change-Number: 35675
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge@osmocom.org>
Gerrit-Reviewer: pespin <pespin@sysmocom.de>
Gerrit-MessageType: merged