pespin submitted this change.
Make SWm MAR+MAA asynchronous
Change-Id: Ie7762843e463f404cd4f0c5fcf03a9566dcf173b
---
M src/aaa_diameter_swm.erl
M src/epdg_diameter_swm.erl
M src/epdg_ue_fsm.erl
3 files changed, 108 insertions(+), 22 deletions(-)
diff --git a/src/aaa_diameter_swm.erl b/src/aaa_diameter_swm.erl
index 6aef1b2..c8ae250 100644
--- a/src/aaa_diameter_swm.erl
+++ b/src/aaa_diameter_swm.erl
@@ -29,26 +29,31 @@
auth_request(Imsi) ->
- gen_server:call(?SERVER, {epdg_auth_req, Imsi}).
+ gen_server:cast(?SERVER, {epdg_auth_req, Imsi}).
-handle_call({epdg_auth_req, Imsi}, From, State) ->
+handle_cast({epdg_auth_req, Imsi}, State) ->
% request the diameter code for a tuple
CKey = [],
IntegrityKey = [],
Result = aaa_diameter_swx:multimedia_auth_request(Imsi, 1, "EAP-AKA", 1, CKey, IntegrityKey),
case Result of
- {ok, Mar} -> {reply, {ok, Mar}, State};
- {error, Err} -> {reply, {error, Err}, State};
- {_, _} -> {reply, {error, unknown}, State}
- end.
+ {ok, _MAA} -> epdg_diameter_swm:auth_response(Imsi, Result);
+ {error, Err} -> epdg_diameter_swm:auth_response(Imsi, Result);
+ _ -> epdg_diameter_swm:auth_response(Imsi, {error, unknown})
+ end,
+ {noreply, State};
handle_cast(Info, S) ->
error_logger:error_report(["unknown handle_cast", {module, ?MODULE}, {info, Info}, {state, S}]),
{noreply, S}.
+
handle_info(Info, S) ->
error_logger:error_report(["unknown handle_info", {module, ?MODULE}, {info, Info}, {state, S}]),
{noreply, S}.
+handle_call(Request, From, S) ->
+ error_logger:error_report(["unknown handle_call", {module, ?MODULE}, {request, Request}, {from, From}, {state, S}]),
+ {noreply, S}.
stop() ->
gen_server:call(?MODULE, stop).
diff --git a/src/epdg_diameter_swm.erl b/src/epdg_diameter_swm.erl
index 9c3145b..dbb764f 100644
--- a/src/epdg_diameter_swm.erl
+++ b/src/epdg_diameter_swm.erl
@@ -7,13 +7,20 @@
-include_lib("diameter_3gpp_ts29_273_swx.hrl").
-record(swm_state, {
+ sessions = sets:new()
}).
+-record(swm_session, {
+ imsi :: binary(),
+ pid :: pid()
+ }).
+
-export([start_link/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2]).
-export([code_change/3, terminate/2]).
-export[(auth_request/1)].
+-export[(auth_response/2)].
-define(SERVER, ?MODULE).
@@ -27,17 +34,31 @@
auth_request(Imsi) ->
- gen_server:call(?SERVER, {epdg_auth_req, Imsi}).
-
-handle_call({epdg_auth_req, Imsi}, _From, State) ->
- % we yet don't implement the Diameter SWm interface on the wire, we process the call internally:
- Result = aaa_diameter_swm:auth_request(Imsi),
+ Result = gen_server:call(?SERVER, {epdg_auth_req, Imsi}),
case Result of
- {ok, Mar} -> {reply, {ok, Mar}, State};
- {error, Err} -> {reply, {error, Err}, State};
- {_, _} -> {reply, {error, unknown}, State}
+ {ok, _Mar} ->
+ epdg_ue_fsm:received_swm_auth_response(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:
+ {_Sess, State1} = find_or_new_swm_session(Imsi, Pid, State0),
+ ok = aaa_diameter_swm:auth_request(Imsi),
+ {reply, ok, State1}.
+
+handle_cast({epdg_auth_resp, Imsi, Result}, State) ->
+ Sess = find_swm_session_by_imsi(Imsi, State),
+ case Sess of
+ #swm_session{imsi = Imsi} ->
+ epdg_ue_fsm:received_swm_auth_response(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}.
@@ -54,3 +75,36 @@
terminate(Reason, _S) ->
lager:info("terminating ~p with reason ~p~n", [?MODULE, Reason]).
+
+%% Emulation from the wire (DIAMETER SWm), called from internal AAA Server:
+auth_response(Imsi, Result) ->
+ ok = gen_server:cast(?SERVER, {epdg_auth_resp, Imsi, Result}).
+
+%% ------------------------------------------------------------------
+%% Internal Function Definitions
+%% ------------------------------------------------------------------
+
+new_swm_session(Imsi, Pid, State) ->
+ Sess = #swm_session{imsi = Imsi,
+ pid = Pid
+ },
+ NewSt = State#swm_state{sessions = sets:add_element(Sess, State#swm_state.sessions)},
+ {Sess, NewSt}.
+
+% returns Sess if found, undefined it not
+find_swm_session_by_imsi(Imsi, State) ->
+ sets:fold(
+ fun(SessIt = #swm_session{imsi = Imsi}, _AccIn) -> SessIt;
+ (_, AccIn) -> AccIn
+ end,
+ undefined,
+ State#swm_state.sessions).
+
+find_or_new_swm_session(Imsi, Pid, State) ->
+ Sess = find_swm_session_by_imsi(Imsi, State),
+ case Sess of
+ #swm_session{imsi = Imsi} ->
+ {Sess, State};
+ undefined ->
+ new_swm_session(Imsi, Pid, State)
+ end.
\ No newline at end of file
diff --git a/src/epdg_ue_fsm.erl b/src/epdg_ue_fsm.erl
index 787689d..9d20a73 100644
--- a/src/epdg_ue_fsm.erl
+++ b/src/epdg_ue_fsm.erl
@@ -40,8 +40,9 @@
-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]).
-export([received_gtpc_create_session_response/2, received_gtpc_delete_session_response/2]).
--export([state_new/3,state_authenticated/3, state_wait_delete_session_resp/3]).
+-export([state_new/3, state_wait_auth_resp/3, state_authenticated/3, state_wait_delete_session_resp/3]).
-record(ue_fsm_data, {
imsi
@@ -88,6 +89,15 @@
{error, Err}
end.
+received_swm_auth_response(Pid, Result) ->
+ lager:info("ue_fsm received_swm_auth_response ~p~n", [Result]),
+ try
+ gen_statem:call(Pid, {received_swm_auth_response, 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
@@ -128,19 +138,27 @@
state_new({call, From}, auth_request, Data) ->
lager:info("ue_fsm state_new event=auth_request, ~p~n", [Data]),
- Auth = epdg_diameter_swm: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, [{reply,From,ok}]};
- {error, Err} ->
- {stop_and_reply, Err, Data, [{reply,From,{error,Err}}]}
+ case epdg_diameter_swm:auth_request(Data#ue_fsm_data.imsi) of
+ ok -> {next_state, state_wait_auth_resp, Data, [{reply,From,ok}]};
+ {error, Err} -> {stop_and_reply, Err, Data, [{reply,From,{error,Err}}]}
end;
state_new({call, From}, purge_ms_request, Data) ->
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({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),
+ case Auth of
+ {ok, _} ->
+ {next_state, state_authenticated, Data, [{reply,From,ok}]};
+ {error, Err} ->
+ {next_state, state_new, Data, [{reply,From,{error,Err}}]};
+ _ ->
+ {next_state, state_new, Data, [{reply,From,{error,unknown}}]}
+ end.
+
state_authenticated({call, From}, lu_request, Data) ->
lager:info("ue_fsm state_authenticated event=lu_request, ~p~n", [Data]),
Result = aaa_diameter_swx:server_assignment_request(Data#ue_fsm_data.imsi, 1, "internet"),
To view, visit change 35691. To unsubscribe, or for help writing mail filters, visit settings.