Make PDP-Type and APN from GSUP AuthInfoReq available through all layers
Change-Id: I3f29b00f57f433f8623b9f0a5048c83985e5cced
This commit is contained in:
parent
2ebc823274
commit
ed89689d49
|
@ -20,7 +20,7 @@
|
||||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2]).
|
-export([init/1, handle_call/3, handle_cast/2, handle_info/2]).
|
||||||
-export([code_change/3, terminate/2]).
|
-export([code_change/3, terminate/2]).
|
||||||
|
|
||||||
-export([auth_request/1, auth_compl_request/2, session_termination_request/1]).
|
-export([auth_request/3, auth_compl_request/2, session_termination_request/1]).
|
||||||
-export([auth_response/2, auth_compl_response/2, session_termination_answer/2]).
|
-export([auth_response/2, auth_compl_response/2, session_termination_answer/2]).
|
||||||
|
|
||||||
-define(SERVER, ?MODULE).
|
-define(SERVER, ?MODULE).
|
||||||
|
@ -47,8 +47,8 @@ session_termination_answer(Imsi, Result) ->
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
% Rx from emulated SWm wire:
|
% Rx from emulated SWm wire:
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
auth_request(Imsi) ->
|
auth_request(Imsi, PdpTypeNr, Apn) ->
|
||||||
gen_server:cast(?SERVER, {epdg_auth_req, Imsi}).
|
gen_server:cast(?SERVER, {epdg_auth_req, Imsi, PdpTypeNr, Apn}).
|
||||||
|
|
||||||
auth_compl_request(Imsi, Apn) ->
|
auth_compl_request(Imsi, Apn) ->
|
||||||
gen_server:cast(?SERVER, {epdg_auth_compl_req, Imsi, Apn}).
|
gen_server:cast(?SERVER, {epdg_auth_compl_req, Imsi, Apn}).
|
||||||
|
@ -56,9 +56,9 @@ auth_compl_request(Imsi, Apn) ->
|
||||||
session_termination_request(Imsi) ->
|
session_termination_request(Imsi) ->
|
||||||
gen_server:cast(?SERVER, {str, Imsi}).
|
gen_server:cast(?SERVER, {str, Imsi}).
|
||||||
|
|
||||||
handle_cast({epdg_auth_req, Imsi}, State0) ->
|
handle_cast({epdg_auth_req, Imsi, PdpTypeNr, Apn}, State0) ->
|
||||||
{Sess, State1} = find_or_new_swm_session(Imsi, State0),
|
{Sess, State1} = find_or_new_swm_session(Imsi, State0),
|
||||||
aaa_ue_fsm:ev_swm_auth_req(Sess#swm_session.pid),
|
aaa_ue_fsm:ev_swm_auth_req(Sess#swm_session.pid, {PdpTypeNr, Apn}),
|
||||||
{noreply, State1};
|
{noreply, State1};
|
||||||
|
|
||||||
handle_cast({epdg_auth_compl_req, Imsi, Apn}, State) ->
|
handle_cast({epdg_auth_compl_req, Imsi, Apn}, State) ->
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
%% gen_server Function Exports
|
%% gen_server Function Exports
|
||||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2]).
|
-export([init/1, handle_call/3, handle_cast/2, handle_info/2]).
|
||||||
-export([code_change/3]).
|
-export([code_change/3]).
|
||||||
-export([multimedia_auth_request/6]).
|
-export([multimedia_auth_request/7]).
|
||||||
-export([server_assignment_request/3]).
|
-export([server_assignment_request/3]).
|
||||||
-export([test/0, test/1]).
|
-export([test/0, test/1]).
|
||||||
|
|
||||||
|
@ -136,11 +136,11 @@ test() ->
|
||||||
test("001011234567890").
|
test("001011234567890").
|
||||||
|
|
||||||
test(IMSI) ->
|
test(IMSI) ->
|
||||||
multimedia_auth_request(IMSI, 3, "EAP-AKA", 1, [], []).
|
multimedia_auth_request(IMSI, 3, "EAP-AKA", 1, [], [], 33).
|
||||||
|
|
||||||
multimedia_auth_request(IMSI, NumAuthItems, AuthScheme, RAT, CKey, IntegrityKey) ->
|
multimedia_auth_request(IMSI, NumAuthItems, AuthScheme, RAT, CKey, IntegrityKey, PdpTypeNr) ->
|
||||||
gen_server:call(?SERVER,
|
gen_server:call(?SERVER,
|
||||||
{mar, {IMSI, NumAuthItems, AuthScheme, RAT, CKey, IntegrityKey}}).
|
{mar, {IMSI, NumAuthItems, AuthScheme, RAT, CKey, IntegrityKey, PdpTypeNr}}).
|
||||||
% APN is optional and should be []
|
% APN is optional and should be []
|
||||||
server_assignment_request(IMSI, Type, APN) ->
|
server_assignment_request(IMSI, Type, APN) ->
|
||||||
gen_server:call(?SERVER,
|
gen_server:call(?SERVER,
|
||||||
|
@ -181,8 +181,30 @@ parse_saa(#'SAA'{'Experimental-Result' = [#{'Vendor-Code' := ?VENDOR_ID_3GPP, 'E
|
||||||
parse_saa(Saa) ->
|
parse_saa(Saa) ->
|
||||||
{unknown_err, []}.
|
{unknown_err, []}.
|
||||||
|
|
||||||
handle_call({mar, {IMSI, NumAuthItems, AuthScheme, RAT, CKey, IntegrityKey}}, {Pid, _Tag} = _From, State) ->
|
handle_call({mar, {IMSI, NumAuthItems, AuthScheme, RAT, CKey, IntegrityKey, PdpTypeNr}}, {Pid, _Tag} = _From, State) ->
|
||||||
SessionId = diameter:session_id(application:get_env(?ENV_APP_NAME, origin_host, ?ENV_DEFAULT_ORIG_HOST)),
|
SessionId = diameter:session_id(application:get_env(?ENV_APP_NAME, origin_host, ?ENV_DEFAULT_ORIG_HOST)),
|
||||||
|
% RFC 4005 6.11.1 Framed-IP-Address AVP:
|
||||||
|
% "0xFFFFFFFE indicates that the NAS should select an address for the user
|
||||||
|
% (e.g., assigned from a pool of addresses kept by the NAS)."
|
||||||
|
Ipv4Dyn = <<16#FFFFFFFE:32>>,
|
||||||
|
% 3GPP TS 29.229 6.3.54, RFC4005 6.11.6 2.3, RFC3162 2.3 allow empty prefix.
|
||||||
|
% Set only the Reserved=0 byte and Prefix-Length=0
|
||||||
|
IPv6Dyn = <<16#00:8,16#00:8>>,
|
||||||
|
case PdpTypeNr of
|
||||||
|
16#21 ->
|
||||||
|
IPv4Opt = Ipv4Dyn,
|
||||||
|
IPv6Opt = [];
|
||||||
|
16#57 ->
|
||||||
|
IPv4Opt = [],
|
||||||
|
IPv6Opt = IPv6Dyn;
|
||||||
|
16#8d ->
|
||||||
|
IPv4Opt = Ipv4Dyn,
|
||||||
|
IPv6Opt = IPv6Dyn;
|
||||||
|
_ ->
|
||||||
|
IPv4Opt = [],
|
||||||
|
IPv6Opt = []
|
||||||
|
end,
|
||||||
|
lager:debug("Swx MAR: IPv4Opt=~p IPv6Opt=~p~n", [IPv4Opt, IPv6Opt]),
|
||||||
MAR = #'MAR'{'Vendor-Specific-Application-Id' = #'Vendor-Specific-Application-Id'{
|
MAR = #'MAR'{'Vendor-Specific-Application-Id' = #'Vendor-Specific-Application-Id'{
|
||||||
'Vendor-Id' = ?VENDOR_ID_3GPP,
|
'Vendor-Id' = ?VENDOR_ID_3GPP,
|
||||||
'Auth-Application-Id' = [?DIAMETER_APP_ID_SWX]},
|
'Auth-Application-Id' = [?DIAMETER_APP_ID_SWX]},
|
||||||
|
@ -192,10 +214,14 @@ handle_call({mar, {IMSI, NumAuthItems, AuthScheme, RAT, CKey, IntegrityKey}}, {P
|
||||||
'SIP-Auth-Data-Item' = #'SIP-Auth-Data-Item'{
|
'SIP-Auth-Data-Item' = #'SIP-Auth-Data-Item'{
|
||||||
'SIP-Authentication-Scheme' = [AuthScheme],
|
'SIP-Authentication-Scheme' = [AuthScheme],
|
||||||
'Confidentiality-Key' = CKey,
|
'Confidentiality-Key' = CKey,
|
||||||
'Integrity-Key' = IntegrityKey},
|
'Integrity-Key' = IntegrityKey,
|
||||||
|
'Framed-IP-Address' = IPv4Opt,
|
||||||
|
'Framed-IPv6-Prefix' = IPv6Opt
|
||||||
|
},
|
||||||
'SIP-Number-Auth-Items' = NumAuthItems,
|
'SIP-Number-Auth-Items' = NumAuthItems,
|
||||||
'RAT-Type' = RAT
|
'RAT-Type' = RAT
|
||||||
},
|
},
|
||||||
|
lager:debug("Swx Tx MAR: ~p~n", [MAR]),
|
||||||
Ret = diameter:call(?SVC_NAME, ?APP_ALIAS, MAR, [{extra, [Pid]}, detach]),
|
Ret = diameter:call(?SVC_NAME, ?APP_ALIAS, MAR, [{extra, [Pid]}, detach]),
|
||||||
case Ret of
|
case Ret of
|
||||||
ok ->
|
ok ->
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
-export([start_link/1]).
|
-export([start_link/1]).
|
||||||
-export([init/1,callback_mode/0,terminate/3]).
|
-export([init/1,callback_mode/0,terminate/3]).
|
||||||
-export([get_server_name_by_imsi/1, get_pid_by_imsi/1]).
|
-export([get_server_name_by_imsi/1, get_pid_by_imsi/1]).
|
||||||
-export([ev_swm_auth_req/1, ev_swm_auth_compl/2, ev_rx_swm_str/1, ev_rx_swx_maa/2, ev_rx_swx_saa/2,
|
-export([ev_swm_auth_req/2, ev_swm_auth_compl/2, ev_rx_swm_str/1, ev_rx_swx_maa/2, ev_rx_swx_saa/2,
|
||||||
ev_rx_s6b_aar/2, ev_rx_s6b_str/1]).
|
ev_rx_s6b_aar/2, ev_rx_s6b_str/1]).
|
||||||
-export([state_new/3, state_wait_swx_maa/3, state_wait_swx_saa/3, state_authenticated/3, state_authenticated_wait_swx_saa/3]).
|
-export([state_new/3, state_wait_swx_maa/3, state_wait_swx_saa/3, state_authenticated/3, state_authenticated_wait_swx_saa/3]).
|
||||||
|
|
||||||
|
@ -66,10 +66,10 @@ start_link(Imsi) ->
|
||||||
lager:info("ue_fsm start_link(~p)~n", [ServerName]),
|
lager:info("ue_fsm start_link(~p)~n", [ServerName]),
|
||||||
gen_statem:start_link({local, ServerName}, ?MODULE, Imsi, [{debug, [trace]}]).
|
gen_statem:start_link({local, ServerName}, ?MODULE, Imsi, [{debug, [trace]}]).
|
||||||
|
|
||||||
ev_swm_auth_req(Pid) ->
|
ev_swm_auth_req(Pid, {PdpTypeNr, Apn}) ->
|
||||||
lager:info("ue_fsm ev_swm_auth_req~n", []),
|
lager:info("ue_fsm ev_swm_auth_req~n", []),
|
||||||
try
|
try
|
||||||
gen_statem:call(Pid, swm_auth_req)
|
gen_statem:call(Pid, {swm_auth_req, PdpTypeNr, Apn})
|
||||||
catch
|
catch
|
||||||
exit:Err ->
|
exit:Err ->
|
||||||
{error, Err}
|
{error, Err}
|
||||||
|
@ -152,12 +152,12 @@ terminate(Reason, State, Data) ->
|
||||||
state_new(enter, _OldState, Data) ->
|
state_new(enter, _OldState, Data) ->
|
||||||
{keep_state, Data};
|
{keep_state, Data};
|
||||||
|
|
||||||
state_new({call, From}, swm_auth_req, Data) ->
|
state_new({call, From}, {swm_auth_req, PdpTypeNr, Apn}, Data) ->
|
||||||
lager:info("ue_fsm state_new event=swm_auth_req, ~p~n", [Data]),
|
lager:info("ue_fsm state_new event=swm_auth_req {~p, ~p}, ~p~n", [PdpTypeNr, Apn, Data]),
|
||||||
% request the diameter code for a tuple
|
% request the diameter code for a tuple
|
||||||
CKey = [],
|
CKey = [],
|
||||||
IntegrityKey = [],
|
IntegrityKey = [],
|
||||||
case aaa_diameter_swx:multimedia_auth_request(Data#ue_fsm_data.imsi, 1, "EAP-AKA", 1, CKey, IntegrityKey) of
|
case aaa_diameter_swx:multimedia_auth_request(Data#ue_fsm_data.imsi, 1, "EAP-AKA", 1, CKey, IntegrityKey, PdpTypeNr) of
|
||||||
ok -> {next_state, state_wait_swx_maa, Data, [{reply,From,ok}]};
|
ok -> {next_state, state_wait_swx_maa, Data, [{reply,From,ok}]};
|
||||||
{error, Err} -> {keep_state, Data, [{reply,From,{error, Err}}]}
|
{error, Err} -> {keep_state, Data, [{reply,From,{error, Err}}]}
|
||||||
end;
|
end;
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2]).
|
-export([init/1, handle_call/3, handle_cast/2, handle_info/2]).
|
||||||
-export([code_change/3, terminate/2]).
|
-export([code_change/3, terminate/2]).
|
||||||
|
|
||||||
-export([auth_request/1, auth_compl_request/2, session_termination_request/1]).
|
-export([auth_request/3, auth_compl_request/2, session_termination_request/1]).
|
||||||
-export([auth_response/2, auth_compl_response/2, session_termination_answer/2]).
|
-export([auth_response/2, auth_compl_response/2, session_termination_answer/2]).
|
||||||
|
|
||||||
-define(SERVER, ?MODULE).
|
-define(SERVER, ?MODULE).
|
||||||
|
@ -33,10 +33,13 @@ init([]) ->
|
||||||
{ok, #swm_state{}}.
|
{ok, #swm_state{}}.
|
||||||
|
|
||||||
|
|
||||||
auth_request(Imsi) ->
|
auth_request(Imsi, PdpTypeNr, Apn) ->
|
||||||
% In Diameter we use Imsi as strings, as done by diameter module.
|
% In Diameter we use Imsi as strings, as done by diameter module.
|
||||||
ImsiStr = binary_to_list(Imsi),
|
ImsiStr = binary_to_list(Imsi),
|
||||||
Result = gen_server:call(?SERVER, {epdg_auth_req, ImsiStr}),
|
% epdg_auth_req: Swm Diameter message Diameter-EAP-Request 3GPP TS 29.273 7.2.2.1.1
|
||||||
|
% PdpTypeNr: SWm Diameter AVP "UE-Local-IP-Address"
|
||||||
|
% Apn: SWm Diameter AVP "Service-Selection"
|
||||||
|
Result = gen_server:call(?SERVER, {epdg_auth_req, ImsiStr, PdpTypeNr, Apn}),
|
||||||
case Result of
|
case Result of
|
||||||
{ok, _Mar} ->
|
{ok, _Mar} ->
|
||||||
epdg_ue_fsm:received_swm_auth_response(self(), Result),
|
epdg_ue_fsm:received_swm_auth_response(self(), Result),
|
||||||
|
@ -68,10 +71,10 @@ session_termination_request(Imsi) ->
|
||||||
_ -> Result
|
_ -> Result
|
||||||
end.
|
end.
|
||||||
|
|
||||||
handle_call({epdg_auth_req, Imsi}, {Pid, _Tag} = _From, State0) ->
|
handle_call({epdg_auth_req, Imsi, PdpTypeNr, Apn}, {Pid, _Tag} = _From, State0) ->
|
||||||
% we yet don't implement the Diameter SWm interface on the wire, we process the call internally:
|
% 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),
|
{_Sess, State1} = find_or_new_swm_session(Imsi, Pid, State0),
|
||||||
ok = aaa_diameter_swm:auth_request(Imsi),
|
ok = aaa_diameter_swm:auth_request(Imsi, PdpTypeNr, Apn),
|
||||||
{reply, ok, State1};
|
{reply, ok, State1};
|
||||||
|
|
||||||
handle_call({epdg_auth_compl_req, Imsi, Apn}, _From, State) ->
|
handle_call({epdg_auth_compl_req, Imsi, Apn}, _From, State) ->
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
-export([start_link/1, stop/1]).
|
-export([start_link/1, stop/1]).
|
||||||
-export([init/1,callback_mode/0,terminate/3]).
|
-export([init/1,callback_mode/0,terminate/3]).
|
||||||
-export([get_server_name_by_imsi/1, get_pid_by_imsi/1]).
|
-export([get_server_name_by_imsi/1, get_pid_by_imsi/1]).
|
||||||
-export([auth_request/1, lu_request/1, tunnel_request/1, purge_ms_request/1]).
|
-export([auth_request/2, lu_request/1, tunnel_request/1, purge_ms_request/1]).
|
||||||
-export([received_swm_auth_response/2, received_swm_auth_compl_response/2, received_swm_session_termination_answer/2]).
|
-export([received_swm_auth_response/2, received_swm_auth_compl_response/2, received_swm_session_termination_answer/2]).
|
||||||
-export([received_gtpc_create_session_response/2, received_gtpc_delete_session_response/2, received_gtpc_delete_bearer_request/1]).
|
-export([received_gtpc_create_session_response/2, received_gtpc_delete_session_response/2, received_gtpc_delete_bearer_request/1]).
|
||||||
-export([state_new/3, state_wait_auth_resp/3, state_authenticating/3, state_authenticated/3,
|
-export([state_new/3, state_wait_auth_resp/3, state_authenticating/3, state_authenticated/3,
|
||||||
|
@ -69,10 +69,10 @@ start_link(Imsi) ->
|
||||||
stop(SrvRef) ->
|
stop(SrvRef) ->
|
||||||
gen_statem:stop(SrvRef).
|
gen_statem:stop(SrvRef).
|
||||||
|
|
||||||
auth_request(Pid) ->
|
auth_request(Pid, {PdpTypeNr, Apn}) ->
|
||||||
lager:info("ue_fsm auth_request~n", []),
|
lager:info("ue_fsm auth_request~n", []),
|
||||||
try
|
try
|
||||||
gen_statem:call(Pid, auth_request)
|
gen_statem:call(Pid, {auth_request, PdpTypeNr, Apn})
|
||||||
catch
|
catch
|
||||||
exit:Err ->
|
exit:Err ->
|
||||||
{error, Err}
|
{error, Err}
|
||||||
|
@ -183,9 +183,9 @@ terminate(Reason, State, Data) ->
|
||||||
state_new(enter, _OldState, Data) ->
|
state_new(enter, _OldState, Data) ->
|
||||||
{keep_state, Data};
|
{keep_state, Data};
|
||||||
|
|
||||||
state_new({call, From}, auth_request, Data) ->
|
state_new({call, From}, {auth_request, PdpTypeNr, Apn}, Data) ->
|
||||||
lager:info("ue_fsm state_new event=auth_request, ~p~n", [Data]),
|
lager:info("ue_fsm state_new event=auth_request {~p, ~p}, ~p~n", [PdpTypeNr, Apn, Data]),
|
||||||
case epdg_diameter_swm:auth_request(Data#ue_fsm_data.imsi) of
|
case epdg_diameter_swm:auth_request(Data#ue_fsm_data.imsi, PdpTypeNr, Apn) of
|
||||||
ok -> {next_state, state_wait_auth_resp, Data, [{reply,From,ok}]};
|
ok -> {next_state, state_wait_auth_resp, Data, [{reply,From,ok}]};
|
||||||
{error, Err} -> {stop_and_reply, Err, Data, [{reply,From,{error,Err}}]}
|
{error, Err} -> {stop_and_reply, Err, Data, [{reply,From,{error,Err}}]}
|
||||||
end;
|
end;
|
||||||
|
|
|
@ -231,9 +231,16 @@ handle_info({ipa_tcp_accept, Socket}, S) ->
|
||||||
{noreply, S#gsups_state{socket=Socket}};
|
{noreply, S#gsups_state{socket=Socket}};
|
||||||
|
|
||||||
% send auth info / requesting authentication tuples
|
% 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) ->
|
||||||
|
#{pdp_info_list := [PdpInfo]} = GsupMsgRx,
|
||||||
|
#{pdp_context_id := _PDPCtxId,
|
||||||
|
pdp_address := #{address := #{},
|
||||||
|
pdp_type_nr := PdpTypeNr,
|
||||||
|
pdp_type_org := 241},
|
||||||
|
access_point_name := Apn
|
||||||
|
} = PdpInfo,
|
||||||
{UE, State1} = find_or_new_gsups_ue(Imsi, State0),
|
{UE, State1} = find_or_new_gsups_ue(Imsi, State0),
|
||||||
case epdg_ue_fsm:auth_request(UE#gsups_ue.pid) of
|
case epdg_ue_fsm:auth_request(UE#gsups_ue.pid, {PdpTypeNr, Apn}) of
|
||||||
ok -> State2 = State1;
|
ok -> State2 = State1;
|
||||||
{error, Err} ->
|
{error, Err} ->
|
||||||
lager:error("Auth Req for Imsi ~p failed: ~p~n", [Imsi, Err]),
|
lager:error("Auth Req for Imsi ~p failed: ~p~n", [Imsi, Err]),
|
||||||
|
|
Loading…
Reference in New Issue