Skip to content

Commit

Permalink
use structured location types everywhere
Browse files Browse the repository at this point in the history
  • Loading branch information
RoadRunnr committed Jul 9, 2021
1 parent 3ff1280 commit 380ce8a
Show file tree
Hide file tree
Showing 18 changed files with 247 additions and 230 deletions.
42 changes: 8 additions & 34 deletions apps/ergw/test/smc_ggsn_test_lib.erl
Original file line number Diff line number Diff line change
Expand Up @@ -259,13 +259,8 @@ make_request(create_pdp_context_request, SubType,
#selection_mode{mode = 0},
#tunnel_endpoint_identifier_control_plane{tei = LocalCntlTEI},
#tunnel_endpoint_identifier_data_i{tei = LocalDataTEI},
#user_location_information{type = 1,
mcc = <<"001">>,
mnc = <<"001">>,
lac = 11,
ci = 0,
sac = 20263,
rac = 0}],
#user_location_information{location = smc_test_lib:sai(1, 1, 11, 20263)}
],
IEs = make_pdp_type(SubType, IEs0),

Req = #gtp{version = v1, type = create_pdp_context_request, tei = 0,
Expand All @@ -282,13 +277,10 @@ make_request(update_pdp_context_request, SubType,
ULI =
case SubType of
ra_update ->
#user_location_information
{type = 1, mcc = <<"001">>, mnc = <<"001">>,
lac = 11, ci = 0, sac = SeqNo band 16#ffff, rac = 0};
#user_location_information{location =
smc_test_lib:sai(1, 1, 11, SeqNo band 16#ffff)};
_ ->
#user_location_information
{type = 1, mcc = <<"001">>, mnc = <<"001">>,
lac = 11, ci = 0, sac = 20263, rac = 0}
#user_location_information{location = smc_test_lib:sai(1, 1, 11, 20263)}
end,

IEs = [#recovery{restart_counter = RCnt},
Expand All @@ -314,13 +306,7 @@ make_request(ms_info_change_notification_request, without_tei,
#rat_type{rat_type = RAT},
#imei{imei = <<"1234567890123456">>},
#international_mobile_subscriber_identity{imsi = ?IMSI},
#user_location_information{type = 1,
mcc = <<"001">>,
mnc = <<"001">>,
lac = 11,
ci = 0,
sac = 20263,
rac = 0}
#user_location_information{location = smc_test_lib:sai(1, 1, 11, 20263)}
],

#gtp{version = v1, type = ms_info_change_notification_request, tei = 0,
Expand All @@ -333,13 +319,7 @@ make_request(ms_info_change_notification_request, invalid_imsi,
#rat_type{rat_type = RAT},
#international_mobile_subscriber_identity{
imsi = <<"991111111111111">>},
#user_location_information{type = 1,
mcc = <<"001">>,
mnc = <<"001">>,
lac = 11,
ci = 0,
sac = 20263,
rac = 0}
#user_location_information{location = smc_test_lib:sai(1, 1, 11, 20263)}
],

#gtp{version = v1, type = ms_info_change_notification_request, tei = 0,
Expand All @@ -351,13 +331,7 @@ make_request(ms_info_change_notification_request, _SubType,
rat_type = RAT}) ->
IEs = [#recovery{restart_counter = RCnt},
#rat_type{rat_type = RAT},
#user_location_information{type = 1,
mcc = <<"001">>,
mnc = <<"001">>,
lac = 11,
ci = 0,
sac = 20263,
rac = 0}
#user_location_information{location = smc_test_lib:sai(1, 1, 11, 20263)}
],

#gtp{version = v1, type = ms_info_change_notification_request,
Expand Down
63 changes: 63 additions & 0 deletions apps/ergw/test/smc_test_lib.erl
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@
-export([match_map/4, maps_key_length/2]).
-export([init_ets/1]).
-export([set_online_charging/1, set_apn_key/2, load_aaa_answer_config/1, set_path_timers/1]).
-export([plmn/2, cgi/2, cgi/4, sai/2, sai/4, rai/3, rai/4,
tai/2, tai/3, ecgi/2, ecgi/3, lai/2, lai/3,
macro_enb/2, macro_enb/3, ext_macro_enb/2, ext_macro_enb/3]).

-include("smc_test_lib.hrl").
-include_lib("stdlib/include/ms_transform.hrl").
Expand Down Expand Up @@ -765,3 +768,63 @@ set_path_timers(SetTimers) ->
{ok, Timers} = ergw_core_config:get([path_management], undefined),
NewTimers = maps_recusive_merge(Timers, SetTimers),
ok = ergw_core_config:put(path_management, NewTimers).

%%%===================================================================
%%% common helpers for location data types
%%%===================================================================

plmn(CC, NC) ->
MCC = iolist_to_binary(io_lib:format("~3..0b", [CC])),
S = itu_e212:mcn_size(MCC),
MNC = iolist_to_binary(io_lib:format("~*..0b", [S, NC])),
{MCC, MNC}.

cgi(CC, NC, LAC, CI) ->
#cgi{plmn_id = plmn(CC, NC), lac = LAC, ci = CI}.

cgi(CC, NC) ->
cgi(CC, NC, rand:uniform(16#ffff), rand:uniform(16#ffff)).

sai(CC, NC, LAC, SAC) ->
#sai{plmn_id = plmn(CC, NC), lac = LAC, sac = SAC}.

sai(CC, NC) ->
sai(CC, NC, rand:uniform(16#ffff), rand:uniform(16#ffff)).

rai(CC, NC, LAC, RAC) ->
#rai{plmn_id = plmn(CC, NC), lac = LAC, rac = RAC}.

rai(v1, CC, NC) ->
rai(CC, NC, rand:uniform(16#ffff), (rand:uniform(16#ff) bsl 8) bor 16#ff);
rai(v2, CC, NC) ->
rai(CC, NC, rand:uniform(16#ffff), rand:uniform(16#ffff)).

tai(CC, NC, TAC) ->
#tai{plmn_id = plmn(CC, NC), tac = TAC}.

tai(CC, NC) ->
tai(CC, NC, rand:uniform(16#ffff)).

ecgi(CC, NC, ECI) ->
#ecgi{plmn_id = plmn(CC, NC), eci = ECI}.

ecgi(CC, NC) ->
ecgi(CC, NC, rand:uniform(16#fffffff)).

lai(CC, NC, LAC) ->
#lai{plmn_id = plmn(CC, NC), lac = LAC}.

lai(CC, NC) ->
lai(CC, NC, rand:uniform(16#ffff)).

macro_enb(CC, NC, MeNB) ->
#macro_enb{plmn_id = plmn(CC, NC), id = MeNB}.

macro_enb(CC, NC) ->
macro_enb(CC, NC, rand:uniform(16#fffff)).

ext_macro_enb(CC, NC, EMeNB) ->
#ext_macro_enb{plmn_id = plmn(CC, NC), id = EMeNB}.

ext_macro_enb(CC, NC) ->
ext_macro_enb(CC, NC, rand:uniform(16#1fffff)).
8 changes: 5 additions & 3 deletions apps/ergw_core/src/ergw_gsn_lib.erl
Original file line number Diff line number Diff line change
Expand Up @@ -286,19 +286,21 @@ optional_if_unset(K, V, M) ->

init_cev_from_session(Now, SessionOpts) ->
Keys = ['Charging-Rule-Base-Name', 'QoS-Information',
'3GPP-User-Location-Info', '3GPP-RAT-Type',
'User-Location-Info', '3GPP-RAT-Type',
'3GPP-Charging-Id',
'3GPP-SGSN-Address', '3GPP-SGSN-IPv6-Address'],
Init = #{'Change-Time' =>
[calendar:system_time_to_universal_time(Now + erlang:time_offset(), native)]},
Container =
maps:fold(fun(K, V, M) when K == '3GPP-User-Location-Info';
K == '3GPP-RAT-Type';
maps:fold(fun(K, V, M) when K == '3GPP-RAT-Type';
K == '3GPP-Charging-Id' ->
M#{K => [ergw_aaa_diameter:'3gpp_from_session'(K, V)]};
(K, V, M) when K == '3GPP-SGSN-Address';
K == '3GPP-SGSN-IPv6-Address' ->
M#{'SGSN-Address' => [V]};
('User-Location-Info' = K, V, M) ->
M#{'3GPP-User-Location-Info' =>
[ergw_aaa_diameter:'3gpp_from_session'(K, V)]};
(K, V, M) -> M#{K => [V]}
end,
Init, maps:with(Keys, SessionOpts)),
Expand Down
2 changes: 1 addition & 1 deletion apps/ergw_core/src/ergw_proxy_lib.erl
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ proxy_info(Session,
#bearer{remote = #fq_teid{ip = GsnU}},
#context{apn = APN, imsi = IMSI, imei = IMEI, msisdn = MSISDN}) ->
Keys = [{'3GPP-RAT-Type', 'ratType'},
{'3GPP-User-Location-Info', 'userLocationInfo'},
{'User-Location-Info', 'userLocationInfo'},
{'RAI', rai}],
PI = lists:foldl(
fun({Key, MapTo}, P) when is_map_key(Key, Session) ->
Expand Down
36 changes: 13 additions & 23 deletions apps/ergw_core/src/ggsn_gn.erl
Original file line number Diff line number Diff line change
Expand Up @@ -385,11 +385,6 @@ map_username(IEs, [H | Rest], Acc) ->
Part = map_attr(H, IEs),
map_username(IEs, Rest, [Part | Acc]).

hexstr(Value, _Width) when is_binary(Value) ->
erlang:iolist_to_binary([io_lib:format("~2.16.0B", [X]) || <<X>> <= Value]);
hexstr(Value, Width) when is_integer(Value) ->
erlang:iolist_to_binary(io_lib:format("~*.16.0B", [Width, Value])).

%% init_session/4
init_session(IEs, #tunnel{local = #fq_teid{ip = LocalIP}},
#context{charging_identifier = ChargingId},
Expand Down Expand Up @@ -508,28 +503,23 @@ copy_to_session(_, #selection_mode{mode = Mode}, _AAAopts, Session) ->
Session#{'3GPP-Selection-Mode' => Mode};
copy_to_session(_, #charging_characteristics{value = Value}, _AAAopts, Session) ->
Session#{'3GPP-Charging-Characteristics' => Value};
copy_to_session(_, #routeing_area_identity{mcc = MCC, mnc = MNC,
lac = LAC, rac = RAC}, _AAAopts, Session) ->
RAI = <<MCC/binary, MNC/binary, (hexstr(LAC, 4))/binary, (hexstr(RAC, 2))/binary>>,
Session#{'RAI' => RAI,
'3GPP-SGSN-MCC-MNC' => <<MCC/binary, MNC/binary>>};
copy_to_session(_, #routeing_area_identity{identity = #rai{plmn_id = PLMN} = RAI},
_AAAopts, Session) ->
maps:update_with('User-Location-Info', _#{'RAI' => RAI}, #{'RAI' => RAI},
Session#{'3GPP-SGSN-MCC-MNC' => PLMN});
copy_to_session(_, #imei{imei = IMEI}, _AAAopts, Session) ->
Session#{'3GPP-IMEISV' => IMEI};
copy_to_session(_, #rat_type{rat_type = Type}, _AAAopts, Session) ->
Session#{'3GPP-RAT-Type' => Type};
copy_to_session(_, #user_location_information{type = Type, mcc = MCC, mnc = MNC, lac = LAC,
ci = CI, sac = SAC} = IE, _AAAopts, Session0) ->
Session = if Type == 0 ->
CGI = <<MCC/binary, MNC/binary, LAC:16, CI:16>>,
maps:without(['SAI'], Session0#{'CGI' => CGI});
Type == 1 ->
SAI = <<MCC/binary, MNC/binary, LAC:16, SAC:16>>,
maps:without(['CGI'], Session0#{'SAI' => SAI});
true ->
Session0
end,
Value = gtp_packet:encode_v1_uli(IE),
Session#{'3GPP-User-Location-Info' => Value};
copy_to_session(_, #user_location_information{location = Location}, _AAAopts, Session) ->
ULI0 = maps:with(['RAI'], maps:get('User-Location-Info', Session, #{})),
ULI = case Location of
#cgi{} -> ULI0#{'CGI' => Location};
#sai{} -> ULI0#{'SAI' => Location};
#rai{} -> ULI0#{'RAI' => Location};
_ -> ULI0
end,
Session#{'User-Location-Info' => ULI};
copy_to_session(_, #ms_time_zone{timezone = TZ, dst = DST}, _AAAopts, Session) ->
Session#{'3GPP-MS-TimeZone' => {TZ, DST}};
copy_to_session(_, _, _AAAopts, Session) ->
Expand Down
14 changes: 12 additions & 2 deletions apps/ergw_core/src/gtp_context.erl
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,17 @@ trigger_delete_context(Context) ->
gen_statem:cast(Context, {delete_context, administrative}).

%% TODO: add online charing events
collect_charging_events(OldS, NewS) ->
collect_charging_events(OldS0, NewS0) ->
Fields = ['3GPP-MS-TimeZone',
'QoS-Information',
'3GPP-RAT-Type',
'3GPP-SGSN-Address',
'3GPP-SGSN-IPv6-Address',
'3GPP-SGSN-MCC-MNC',
'User-Location-Info'],
OldS = maps:merge(maps:with(Fields, OldS0), maps:get('User-Location-Info', OldS0)),
NewS = maps:merge(maps:with(Fields, NewS0), maps:get('User-Location-Info', NewS0)),

EvChecks =
[
{'CGI', 'cgi-sai-change'},
Expand All @@ -141,7 +151,7 @@ collect_charging_events(OldS, NewS) ->
{'3GPP-SGSN-MCC-MNC', 'sgsn-sgw-plmn-id-change'},
{'TAI', 'tai-change'},
%%{ qos, 'tariff-switch-change'},
{'3GPP-User-Location-Info', 'user-location-info-change'}
{'User-Location-Info', 'user-location-info-change'}
],

Events =
Expand Down
4 changes: 4 additions & 0 deletions apps/ergw_core/src/itu_e212.erl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@

-export([split_imsi/1]).

-ifdef(TEST).
-export([mcn_size/1]).
-endif.

%%====================================================================
%% API
%%====================================================================
Expand Down
54 changes: 15 additions & 39 deletions apps/ergw_core/src/pgw_s5s8.erl
Original file line number Diff line number Diff line change
Expand Up @@ -674,49 +674,25 @@ copy_to_session(_, #v2_selection_mode{mode = Mode}, _AAAopts, Session) ->
copy_to_session(_, #v2_charging_characteristics{value = Value}, _AAAopts, Session) ->
Session#{'3GPP-Charging-Characteristics' => Value};

copy_to_session(_, #v2_serving_network{mcc = MCC, mnc = MNC}, _AAAopts, Session) ->
Session#{'3GPP-SGSN-MCC-MNC' => <<MCC/binary, MNC/binary>>};
copy_to_session(_, #v2_serving_network{plmn_id = PLMN}, _AAAopts, Session) ->
Session#{'3GPP-SGSN-MCC-MNC' => PLMN};
copy_to_session(_, #v2_mobile_equipment_identity{mei = IMEI}, _AAAopts, Session) ->
Session#{'3GPP-IMEISV' => IMEI};
copy_to_session(_, #v2_rat_type{rat_type = Type}, _AAAopts, Session) ->
Session#{'3GPP-RAT-Type' => Type};

%% 0 CGI
%% 1 SAI
%% 2 RAI
%% 3-127 Spare for future use
%% 128 TAI
%% 129 ECGI
%% 130 TAI and ECGI
%% 131-255 Spare for future use

copy_to_session(_, #v2_user_location_information{tai = TAI, ecgi = ECGI}, _AAAopts, Session)
when is_binary(TAI), is_binary(ECGI) ->
Value = <<130, TAI/binary, ECGI/binary>>,
Session#{'TAI' => TAI, 'ECGI' => ECGI, '3GPP-User-Location-Info' => Value};
copy_to_session(_, #v2_user_location_information{ecgi = ECGI}, _AAAopts, Session)
when is_binary(ECGI) ->
Value = <<129, ECGI/binary>>,
Session#{'ECGI' => ECGI, '3GPP-User-Location-Info' => Value};
copy_to_session(_, #v2_user_location_information{tai = TAI}, _AAAopts, Session)
when is_binary(TAI) ->
Value = <<128, TAI/binary>>,
Session#{'TAI' => TAI, '3GPP-User-Location-Info' => Value};
copy_to_session(_, #v2_user_location_information{rai = RAI}, _AAAopts, Session)
when is_binary(RAI) ->
Value = <<2, RAI/binary>>,
Session#{'RAI' => RAI, '3GPP-User-Location-Info' => Value};
copy_to_session(_, #v2_user_location_information{sai = SAI}, _AAAopts, Session0)
when is_binary(SAI) ->
Session = maps:without(['CGI'], Session0#{'SAI' => SAI}),
Value = <<1, SAI/binary>>,
Session#{'3GPP-User-Location-Info' => Value};
copy_to_session(_, #v2_user_location_information{cgi = CGI}, _AAAopts, Session0)
when is_binary(CGI) ->
Session = maps:without(['SAI'], Session0#{'CGI' => CGI}),
Value = <<0, CGI/binary>>,
Session#{'3GPP-User-Location-Info' => Value};

copy_to_session(_, #v2_user_location_information{} = Info, _AAAopts, Session) ->
ULI = lists:foldl(
fun(X, S) when is_record(X, cgi) -> S#{'CGI' => X};
(X, S) when is_record(X, sai) -> S#{'SAI' => X};
(X, S) when is_record(X, rai) -> S#{'RAI' => X};
(X, S) when is_record(X, tai) -> S#{'TAI' => X};
(X, S) when is_record(X, ecgi) -> S#{'ECGI' => X};
(X, S) when is_record(X, lai) -> S#{'LAI' => X};
(X, S) when is_record(X, macro_enb) -> S#{'macro-eNB' => X};
(X, S) when is_record(X, ext_macro_enb) -> S#{'ext-macro-eNB' => X};
(_, S) -> S
end, #{}, tl(tuple_to_list(Info))),
Session#{'User-Location-Info' => ULI};
copy_to_session(_, #v2_ue_time_zone{timezone = TZ, dst = DST}, _AAAopts, Session) ->
Session#{'3GPP-MS-TimeZone' => {TZ, DST}};
copy_to_session(_, _, _AAAopts, Session) ->
Expand Down
Loading

0 comments on commit 380ce8a

Please sign in to comment.