pespin has uploaded this change for review.
Forward failure SWx MAA -> GSUP AuthInfo Error
Change-Id: I48066058e601a4ca4d46e239f7a7060bbc20a32b
---
M include/conv.hrl
M src/aaa_diameter_swx_cb.erl
M src/aaa_ue_fsm.erl
M src/conv.erl
M src/epdg_ue_fsm.erl
M src/gsup_server.erl
6 files changed, 100 insertions(+), 32 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-epdg refs/changes/80/36180/1
diff --git a/include/conv.hrl b/include/conv.hrl
index 80b7e5b..786bdff 100644
--- a/include/conv.hrl
+++ b/include/conv.hrl
@@ -31,6 +31,12 @@
%
-hrl_name('conv.hrl').
+%% Can Hold information about Result-Code or Experimental-Result:
+-record(epdg_dia_rc, {
+ vendor_id :: non_neg_integer(), %% or undefined if Result-Code
+ result_code :: non_neg_integer()
+}).
+
-record(epdg_eua, {
type_nr :: non_neg_integer(),
ipv4 :: binary(),
diff --git a/src/aaa_diameter_swx_cb.erl b/src/aaa_diameter_swx_cb.erl
index 0457259..8a6dd08 100644
--- a/src/aaa_diameter_swx_cb.erl
+++ b/src/aaa_diameter_swx_cb.erl
@@ -70,18 +70,27 @@
%% handle_answer/4
handle_answer(#diameter_packet{msg = Msg, errors = Errors}, _Request, _SvcName, Peer, ReqPid) when is_record(Msg, 'MAA') ->
lager:info("SWx Rx MAA ~p: ~p/ Errors ~p ~n", [Peer, Msg, Errors]),
- #'MAA'{'SIP-Auth-Data-Item' = SipAuthTuples} = Msg,
- AuthTuples = lists:map(fun dia_sip2epdg_auth_tuple/1, SipAuthTuples),
- % TODO: handle error case....
- aaa_ue_fsm:ev_rx_swx_maa(ReqPid, {ok, AuthTuples}),
+ #'MAA'{'Result-Code' = ResultCodeOpt,
+ 'Experimental-Result' = ExperimentalResultOpt} = Msg,
+ DiaRC = parse_epdg_dia_rc(ResultCodeOpt, ExperimentalResultOpt),
+ case dia_rc_success(DiaRC) of
+ ok ->
+ #'MAA'{'SIP-Auth-Data-Item' = SipAuthTuples} = Msg,
+ AuthTuples = lists:map(fun dia_sip2epdg_auth_tuple/1, SipAuthTuples),
+ aaa_ue_fsm:ev_rx_swx_maa(ReqPid, {ok, AuthTuples});
+ _ ->
+ aaa_ue_fsm:ev_rx_swx_maa(ReqPid, {error, DiaRC})
+ end,
{ok, Msg};
handle_answer(#diameter_packet{msg = Msg, errors = Errors}, Request, _SvcName, Peer, ReqPid) when is_record(Msg, 'SAA') ->
lager:info("SWx Rx SAA ~p: ~p/ Errors ~p ~n", [Peer, Msg, Errors]),
% Recover fields from originating request:
#'SAR'{'Server-Assignment-Type' = SAType} = Request,
% Retrieve fields from answer:
- #'SAA'{'Result-Code' = [ResultCode]} = Msg,
- case result_code_success(ResultCode) of
+ #'SAA'{'Result-Code' = ResultCodeOpt,
+ 'Experimental-Result' = ExperimentalResultOpt} = Msg,
+ DiaRC = parse_epdg_dia_rc(ResultCodeOpt, ExperimentalResultOpt),
+ case dia_rc_success(DiaRC) of
ok ->
#'SAA'{'Non-3GPP-User-Data' = N3UA} = Msg,
PGWAddresses = parse_pgw_addr_from_N3UA(N3UA),
@@ -91,7 +100,7 @@
end,
aaa_ue_fsm:ev_rx_swx_saa(ReqPid, {ok, SAType, ResInfo});
_ ->
- aaa_ue_fsm:ev_rx_swx_saa(ReqPid, {error, SAType, ResultCode})
+ aaa_ue_fsm:ev_rx_swx_saa(ReqPid, {error, SAType, DiaRC})
end,
{ok, Msg}.
handle_answer(#diameter_packet{msg = Msg, errors = []}, _Request, _SvcName, Peer) ->
@@ -121,9 +130,19 @@
%% Internal Function Definitions
%% ------------------------------------------------------------------
-result_code_success(2001) -> ok;
-result_code_success(2002) -> ok;
-result_code_success(_) -> invalid_result_code.
+dia_rc_success(#epdg_dia_rc{result_code = 2001}) -> ok;
+dia_rc_success(#epdg_dia_rc{result_code = 2002}) -> ok;
+dia_rc_success(_) -> invalid_result_code.
+
+parse_epdg_dia_rc([], []) ->
+ #epdg_dia_rc{vendor_id = undefined, result_code = 2001 };
+parse_epdg_dia_rc([ResultCode], []) ->
+ #epdg_dia_rc{vendor_id = undefined, result_code = ResultCode };
+parse_epdg_dia_rc([], [ExpResultCode]) ->
+ #'Experimental-Result'{'Vendor-Id' = VendorId, 'Experimental-Result-Code' = ERC} = ExpResultCode,
+ #epdg_dia_rc{vendor_id = VendorId, result_code = ERC };
+parse_epdg_dia_rc([ResultCode], [_ExpResultCode]) ->
+ parse_epdg_dia_rc([ResultCode], []).
dia_sip2epdg_auth_tuple(#'SIP-Auth-Data-Item'{'SIP-Authenticate' = [Authenticate],
'SIP-Authorization' = [Authorization],
diff --git a/src/aaa_ue_fsm.erl b/src/aaa_ue_fsm.erl
index 9e41756..55eea36 100644
--- a/src/aaa_ue_fsm.erl
+++ b/src/aaa_ue_fsm.erl
@@ -175,7 +175,6 @@
state_wait_swx_maa({call, From}, {rx_swx_maa, Result}, Data) ->
lager:info("ue_fsm state_wait_swx_maa event=rx_swx_maa, ~p~n", [Data]),
aaa_diameter_swm:auth_response(Data#ue_fsm_data.imsi, Result),
- % TODO: don't transit if SAS returned error code.
{next_state, state_new, Data, [{reply,From,ok}]}.
state_wait_swx_saa(enter, _OldState, Data) ->
diff --git a/src/conv.erl b/src/conv.erl
index cdba445..1a15a3c 100644
--- a/src/conv.erl
+++ b/src/conv.erl
@@ -40,6 +40,7 @@
-export([ip_to_bin/1, bin_to_ip/1]).
-export([cause_gtp2gsup/1]).
+-export([dia_rc_to_gsup_cause/1]).
-export([gtp2_paa_to_epdg_eua/1, epdg_eua_to_gsup_pdp_address/1]).
-export([nai_to_imsi/1]).
@@ -76,6 +77,32 @@
cause_gtp2gsup(_) -> ?GSUP_CAUSE_PROTO_ERR_UNSPEC.
+-define(DIA_VENDOR_3GPP, 10415).
+% transient (only in Experimental-Result-Code)
+-define(DIAMETER_AUTHENTICATION_DATA_UNAVAILABLE, 4181).
+-define(DIAMETER_ERROR_CAMEL_SUBSCRIPTION_PRESENT, 4182).
+% permanent (only in Experimental-Result-Code)
+-define(DIAMETER_ERROR_USER_UNKNOWN, 5001).
+-define(DIAMETER_AUTHORIZATION_REJECTED, 5003).
+-define(DIAMETER_ERROR_ROAMING_NOT_ALLOWED, 5004).
+-define(DIAMETER_MISSING_AVP, 5005).
+-define(DIAMETER_UNABLE_TO_COMPLY, 5012).
+-define(DIAMETER_ERROR_UNKNOWN_EPS_SUBSCRIPTION, 5420).
+-define(DIAMETER_ERROR_RAT_NOT_ALLOWED, 5421).
+-define(DIAMETER_ERROR_EQUIPMENT_UNKNOWN, 5422).
+-define(DIAMETER_ERROR_UNKOWN_SERVING_NODE, 5423).
+
+-spec dia_rc_to_gsup_cause(#epdg_dia_rc{}) -> non_neg_integer().
+dia_rc_to_gsup_cause(#epdg_dia_rc{result_code = 2001}) -> 0;
+dia_rc_to_gsup_cause(#epdg_dia_rc{result_code = 2002}) -> 0;
+dia_rc_to_gsup_cause(#epdg_dia_rc{result_code = ?DIAMETER_ERROR_USER_UNKNOWN}) -> ?GSUP_CAUSE_IMSI_UNKNOWN;
+dia_rc_to_gsup_cause(#epdg_dia_rc{result_code = ?DIAMETER_AUTHORIZATION_REJECTED}) -> ?GSUP_CAUSE_LA_NOTALLOWED;
+dia_rc_to_gsup_cause(#epdg_dia_rc{result_code = ?DIAMETER_ERROR_ROAMING_NOT_ALLOWED}) -> ?GSUP_CAUSE_ROAMING_NOTALLOWED;
+dia_rc_to_gsup_cause(#epdg_dia_rc{result_code = ?DIAMETER_ERROR_UNKNOWN_EPS_SUBSCRIPTION}) -> ?GSUP_CAUSE_NO_SUIT_CELL_IN_LA;
+dia_rc_to_gsup_cause(#epdg_dia_rc{result_code = ?DIAMETER_UNABLE_TO_COMPLY}) -> ?GSUP_CAUSE_NET_FAIL;
+dia_rc_to_gsup_cause(#epdg_dia_rc{result_code = ?DIAMETER_MISSING_AVP}) -> ?GSUP_CAUSE_PROTO_ERR_UNSPEC;
+dia_rc_to_gsup_cause(_) -> ?GSUP_CAUSE_NET_FAIL.
+
gtp2_paa_to_epdg_eua(#v2_pdn_address_allocation{type = ipv4, address = Addr}) ->
#epdg_eua{type_nr = ?GTP_PDP_ADDR_TYPE_NR_IPv4,
ipv4 = Addr};
diff --git a/src/epdg_ue_fsm.erl b/src/epdg_ue_fsm.erl
index 703e242..1414190 100644
--- a/src/epdg_ue_fsm.erl
+++ b/src/epdg_ue_fsm.erl
@@ -218,12 +218,14 @@
state_wait_auth_resp({call, From}, {received_swm_auth_response, Result}, Data) ->
lager:info("ue_fsm state_wait_auth_resp event=received_swm_auth_response Result=~p, ~p~n", [Result, Data]),
- gsup_server:auth_response(Data#ue_fsm_data.imsi, Result),
case Result of
- {ok, _} ->
+ {ok, _AuthTuples} ->
+ gsup_server:auth_response(Data#ue_fsm_data.imsi, Result),
{next_state, state_authenticating, Data, [{reply,From,ok}]};
- {error, Err} ->
- {next_state, state_new, Data, [{reply,From,{error,Err}}]};
+ {error, DiaRC} ->
+ GsupCause = conv:dia_rc_to_gsup_cause(DiaRC),
+ gsup_server:auth_response(Data#ue_fsm_data.imsi, {error, GsupCause}),
+ {next_state, state_new, Data, [{reply,From,ok}]};
_ ->
{next_state, state_new, Data, [{reply,From,{error,unknown}}]}
end.
@@ -257,13 +259,12 @@
PGWAddrCandidateList ->
Data1 = Data#ue_fsm_data{pgw_rem_addr_list = PGWAddrCandidateList}
end,
- Ret = ok,
- gsup_server:lu_response(Data1#ue_fsm_data.imsi, Ret),
- {next_state, state_authenticated, Data1, [{reply,From,Ret}]};
- {error, Err} ->
- Ret = {error, Err},
- gsup_server:lu_response(Data#ue_fsm_data.imsi, Ret),
- {next_state, state_new, Data, [{reply,From,Ret}]}
+ gsup_server:lu_response(Data1#ue_fsm_data.imsi, ok),
+ {next_state, state_authenticated, Data1, [{reply,From,ok}]};
+ {error, DiaRC} ->
+ GsupCause = conv:dia_rc_to_gsup_cause(DiaRC),
+ gsup_server:lu_response(Data#ue_fsm_data.imsi, {error, GsupCause}),
+ {next_state, state_new, Data, [{reply,From,ok}]}
end.
state_authenticated(enter, _OldState, Data) ->
diff --git a/src/gsup_server.erl b/src/gsup_server.erl
index d71836b..10495e1 100644
--- a/src/gsup_server.erl
+++ b/src/gsup_server.erl
@@ -122,7 +122,12 @@
imsi => Imsi,
auth_tuples => lists:map(fun epdg_auth_tuple2gsup/1, AuthTuples)
};
- {error, _} -> Resp = #{message_type => send_auth_info_err, imsi => Imsi, message_class => 5, cause => ?GSUP_CAUSE_NET_FAIL}
+ {error, Gsupcause} ->
+ Resp = #{message_type => send_auth_info_err,
+ imsi => Imsi,
+ message_class => 5,
+ cause => Gsupcause
+ }
end,
tx_gsup(Socket, Resp),
{noreply, State};
@@ -131,15 +136,17 @@
lager:info("lu_response for ~p: ~p~n", [Imsi, Result]),
Socket = State#gsups_state.socket,
case Result of
- ok -> Resp = #{message_type => location_upd_res,
- imsi => Imsi,
- message_class => 5
- };
- {error, _} -> Resp = #{message_type => location_upd_err,
- imsi => Imsi,
- message_class => 5,
- cause => ?GSUP_CAUSE_NET_FAIL
- }
+ ok ->
+ Resp = #{message_type => location_upd_res,
+ imsi => Imsi,
+ message_class => 5
+ };
+ {error, Gsupcause} ->
+ Resp = #{message_type => location_upd_err,
+ imsi => Imsi,
+ message_class => 5,
+ cause => Gsupcause
+ }
end,
tx_gsup(Socket, Resp),
{noreply, State};
To view, visit change 36180. To unsubscribe, or for help writing mail filters, visit settings.