pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/erlang/osmo-epdg/+/35675?usp=email )
Change subject: Use call() instead of cast() in ue_fsm ......................................................................
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(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-epdg refs/changes/75/35675/1
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