pespin has submitted this change. ( https://gerrit.osmocom.org/c/erlang/osmo-epdg/+/35660?usp=email )
Change subject: Make CreateSession Req+Resp procedure async ......................................................................
Make CreateSession Req+Resp procedure async
Change-Id: Ib42ed08afa4a06149d2d72ac64487eec808e260f --- M src/epdg_gtpc_s2b.erl M src/ue_fsm.erl 2 files changed, 44 insertions(+), 32 deletions(-)
Approvals: laforge: Looks good to me, but someone else must approve Jenkins Builder: Verified pespin: Looks good to me, approved
diff --git a/src/epdg_gtpc_s2b.erl b/src/epdg_gtpc_s2b.erl index fe07a42..fc41351 100644 --- a/src/epdg_gtpc_s2b.erl +++ b/src/epdg_gtpc_s2b.erl @@ -86,6 +86,7 @@
-record(gtp_session, { imsi :: binary(), + pid :: pid(), apn :: binary(), ue_ip :: inet:ip_address(), local_control_tei = 0 :: non_neg_integer(), @@ -136,32 +137,15 @@ end.
create_session_req(Imsi) -> - gen_server:call(?SERVER, - {gtpc_create_session_req, {Imsi}}). + gen_server:call(?SERVER, {gtpc_create_session_req, {Imsi}}).
-handle_call({gtpc_create_session_req, {Imsi}}, _From, State0) -> - {Sess0, State1} = find_or_new_gtp_session(Imsi, State0), +handle_call({gtpc_create_session_req, {Imsi}}, {Pid, _Tag} = _From, State0) -> + {Sess0, State1} = find_or_new_gtp_session(Imsi, Pid, State0), Req = gen_create_session_request(Sess0, State1), %TODO: increment State.seq_no. tx_gtp(Req, State1), lager:debug("Waiting for CreateSessionResponse~n", []), - receive - {udp, _Socket, IP, InPortNo, RxMsg} -> - try - Resp = gtp_packet:decode(RxMsg), - lager:info("s2b: Rx from IP ~p port ~p ~p~n", [IP, InPortNo, Resp]), - Sess1 = update_gtp_session_from_create_session_response(Resp, Sess0), - lager:info("s2b: Updated Session after create_session_response: ~p~n", [Sess1]), - State2 = update_gtp_session(Sess0, Sess1, State1), - {reply, {ok, Resp}, State2} - catch Any -> - lager:error("Error sending message to receiver, ERROR: ~p~n", [Any]), - {reply, {error, decode_failure}, State1} - end - after 5000 -> - lager:error("Timeout waiting for CreateSessionResponse for ~p~n", [Req]), - {reply, timeout, State1} - end. + {reply, ok, State1}.
%% @callback gen_server handle_cast(stop, State) -> @@ -199,13 +183,14 @@ %% Internal Function Definitions %% ------------------------------------------------------------------
-new_gtp_session(Imsi, State) -> +new_gtp_session(Imsi, Pid, State) -> % TODO: find non-used local TEI inside State Bearer = #gtp_bearer{ ebi = 5, local_data_tei = State#gtp_state.next_local_data_tei }, Sess = #gtp_session{imsi = Imsi, + pid = Pid, apn = ?APN, local_control_tei = State#gtp_state.next_local_control_tei, bearer = Bearer @@ -224,13 +209,13 @@ undefined, State#gtp_state.sessions).
-find_or_new_gtp_session(Imsi, State) -> +find_or_new_gtp_session(Imsi, Pid, State) -> Sess = find_gtp_session_by_imsi(Imsi, State), case Sess of #gtp_session{imsi = Imsi} -> {Sess, State}; undefined -> - new_gtp_session(Imsi, State) + new_gtp_session(Imsi, Pid, State) end.
update_gtp_session(OldSess, NewSess, State) -> @@ -277,6 +262,20 @@ connect(Address) -> connect(?SVC_NAME, Address).
+rx_gtp(Resp = #gtp{version = v2, type = create_session_response}, State0) -> + Sess0 = find_gtp_session_by_local_teic(Resp#gtp.tei, State0), + case Sess0 of + undefined -> + lager:error("Rx unknown TEI ~p: ~p~n", [Resp#gtp.tei, Resp]), + {noreply, State0}; + Sess0 -> + Sess1 = update_gtp_session_from_create_session_response(Resp, Sess0), + lager:info("s2b: Updated Session after create_session_response: ~p~n", [Sess1]), + State1 = update_gtp_session(Sess0, Sess1, State0), + ue_fsm:received_gtpc_create_session_response(Sess0#gtp_session.pid, {ok, Resp}), + {noreply, State1} + end; + rx_gtp(Req = #gtp{version = v2, type = delete_bearer_request}, State) -> Sess = find_gtp_session_by_local_teic(Req#gtp.tei, State), case Sess of @@ -289,6 +288,7 @@ State1 = delete_gtp_session(Sess, State), {noreply, State1} end; + rx_gtp(Req, State) -> lager:error("S2b: UNIMPLEMENTED Rx: ~p~n", [Req]), {noreply, State}. diff --git a/src/ue_fsm.erl b/src/ue_fsm.erl index 0fe6992..f6b2b7e 100644 --- a/src/ue_fsm.erl +++ b/src/ue_fsm.erl @@ -36,7 +36,7 @@
-export([start_link/1]). -export([init/1,callback_mode/0,terminate/3]). --export([auth_request/1, lu_request/1, tunnel_request/1]). +-export([auth_request/1, lu_request/1, tunnel_request/1, received_gtpc_create_session_response/2]). -export([state_new/3,state_authenticated/3]).
-record(ue_fsm_data, { @@ -60,6 +60,10 @@ lager:info("ue_fsm tunnel_request~n", []), gen_statem:cast(Pid, tunnel_request).
+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}). + init(Imsi) -> lager:info("ue_fsm init(~p)~n", [Imsi]), Data = #ue_fsm_data{imsi = Imsi}, @@ -96,14 +100,13 @@
state_authenticated(cast, tunnel_request, Data) -> lager:info("ue_fsm state_authenticated event=tunnel_request, ~p~n", [Data]), - Result = epdg_gtpc_s2b:create_session_req(Data#ue_fsm_data.imsi), + epdg_gtpc_s2b:create_session_req(Data#ue_fsm_data.imsi), + {keep_state, Data}; + +state_authenticated(cast, {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), - case Result of - {ok, _} -> - {keep_state, Data}; - {error, Err} -> - {stop, Err, Data} - end; + {keep_state, Data};
state_authenticated(cast, _Whatever, Data) -> lager:info("ue_fsm state_authenticated event=auth_request, ~p~n", [Data]),