gerrit-log
Threads by month
- ----- 2026 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
December 2025
- 1 participants
- 1175 discussions
[L] Change in ...osmo-s1gw[master]: s1ap_proxy: move S1 SETUP handling to sctp_proxy
by fixeria 05 Dec '25
by fixeria 05 Dec '25
05 Dec '25
fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41622?usp=email )
Change subject: s1ap_proxy: move S1 SETUP handling to sctp_proxy
......................................................................
s1ap_proxy: move S1 SETUP handling to sctp_proxy
This is a prerequisite for the MME pooling support. We need to receive
the S1 SETUP REQUEST PDU, extract the Global-eNB-ID and TAC(s), and use
this information to select an appropriate MME. The PDU must also be
cached so it can be sent (or re-sent) to the selected MME(s).
The s1ap_proxy module no longer needs to parse S1 SETUP PDUs, as this
logic has been moved to the sctp_proxy and implemented using the newly
introduced s1ap_utils API. However, s1ap_proxy still requires the
Global-eNB-ID for logging and per-eNB counters, so sctp_proxy now
provides it through the new s1ap_proxy:set_genb_id/2 API.
Change-Id: I9aa67732b418bcdf3f10b2db89a41dda26ee3d4e
Related: SYS#7052
---
M src/enb_registry.erl
M src/s1ap_proxy.erl
M src/sctp_proxy.erl
M test/s1ap_proxy_test.erl
4 files changed, 151 insertions(+), 113 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-s1gw refs/changes/22/41622/1
diff --git a/src/enb_registry.erl b/src/enb_registry.erl
index 90c3376..80d264b 100644
--- a/src/enb_registry.erl
+++ b/src/enb_registry.erl
@@ -65,7 +65,7 @@
-type enb_event() :: {connecting, sctp_server:conn_info()}
| {connected, sctp_proxy:conn_info()}
- | {s1setup, s1ap_proxy:enb_info()}.
+ | {s1setup, s1ap_utils:genb_id()}.
-type enb_filter() :: {genb_id_str, string()}
| {enb_sctp_aid, gen_sctp:assoc_id()}
@@ -79,9 +79,8 @@
state := enb_state(), %% connection state
reg_time := integer(), %% registration time (monotonic)
uptime := non_neg_integer(), %% seconds since reg_time
- genb_id_str => string(), %% Global-eNB-ID
- enb_id => s1ap_utils:enb_id(), %% eNB-ID
- plmn_id => s1ap_utils:plmn_id(), %% PLMN-ID
+ genb_id => s1ap_utils:genb_id(), %% Global-eNB-ID
+ genb_id_str => string(), %% Global-eNB-ID string
enb_conn_info => sctp_server:conn_info(), %% eNB -> S1GW connection info
mme_conn_info => sctp_proxy:conn_info() %% S1GW -> MME connection info
}.
@@ -307,8 +306,10 @@
EnbInfo#{state => connected,
mme_conn_info => ConnInfo};
-enb_handle_event(EnbInfo, {s1setup, Info}) ->
- maps:merge(EnbInfo#{state => s1setup}, Info);
+enb_handle_event(EnbInfo, {s1setup, GENBId}) ->
+ EnbInfo#{state => s1setup,
+ genb_id => GENBId,
+ genb_id_str => s1ap_utils:genb_id_str(GENBId)};
enb_handle_event(EnbInfo, Event) ->
?LOG_ERROR("Unhandled event: ~p", [Event]),
diff --git a/src/s1ap_proxy.erl b/src/s1ap_proxy.erl
index 43624d2..0903906 100644
--- a/src/s1ap_proxy.erl
+++ b/src/s1ap_proxy.erl
@@ -41,6 +41,7 @@
handle_cast/2,
terminate/2]).
-export([start_link/1,
+ set_genb_id/2,
process_pdu/2,
fetch_erab/2,
fetch_erab_list/1,
@@ -68,8 +69,6 @@
-record(proxy_state, {owner :: pid(),
erabs :: dict:dict(K :: erab_uid(),
V :: pid()),
- enb_id :: undefined | s1ap_utils:enb_id(),
- plmn_id :: undefined | s1ap_utils:plmn_id(),
genb_id_str :: undefined | string(),
mme_ue_id :: undefined | mme_ue_id(),
enb_ue_id :: undefined | enb_ue_id(),
@@ -80,13 +79,7 @@
-type proxy_state() :: #proxy_state{}.
-type proxy_action() :: forward | reply | drop.
--type enb_info() :: #{enb_id => s1ap_utils:enb_id(),
- plmn_id => s1ap_utils:plmn_id(),
- genb_id_str => string()
- }.
-
--export_type([proxy_action/0,
- enb_info/0]).
+-export_type([proxy_action/0]).
%% ------------------------------------------------------------------
@@ -98,6 +91,11 @@
gen_server:start_link(?MODULE, [Owner], []).
+-spec set_genb_id(pid(), string()) -> ok | {error, term()}.
+set_genb_id(Pid, GlobalENBId) ->
+ gen_server:call(Pid, {?FUNCTION_NAME, GlobalENBId}).
+
+
-type process_pdu_result() :: {proxy_action(), binary()}.
-spec process_pdu(pid(), binary()) -> process_pdu_result().
process_pdu(Pid, PDU) ->
@@ -145,6 +143,20 @@
#proxy_state{erabs = ERABs} = S) ->
{reply, dict:to_list(ERABs), S};
+handle_call({set_genb_id, GlobalENBId}, _From,
+ #proxy_state{genb_id_str = undefined} = S) ->
+ ?LOG_DEBUG("Global-eNB-ID is set: ~s", [GlobalENBId]),
+ %% use that as a context for logging
+ osmo_s1gw:set_log_prefix("eNB " ++ GlobalENBId),
+ %% register per-eNB metrics
+ ctr_reg_all(GlobalENBId),
+ {reply, ok, S#proxy_state{genb_id_str = GlobalENBId}};
+
+handle_call({set_genb_id, _GlobalENBId}, _From,
+ #proxy_state{genb_id_str = GlobalENBId} = S) ->
+ ?LOG_ERROR("Global-eNB-ID is already set: ~s", [GlobalENBId]),
+ {reply, {error, ealready}, S};
+
handle_call(Info, From,
#proxy_state{} = S) ->
?LOG_ERROR("unknown ~p() from ~p: ~p", [?FUNCTION_NAME, From, Info]),
@@ -198,15 +210,6 @@
ok.
--spec enb_info(proxy_state()) -> enb_info().
-enb_info(S) ->
- Info = #{enb_id => S#proxy_state.enb_id,
- plmn_id => S#proxy_state.plmn_id,
- genb_id_str => S#proxy_state.genb_id_str},
- %% omit fields with Value =:= undefined
- maps:filter(fun(_K, V) -> V =/= undefined end, Info).
-
-
%% register a single per-eNB counter
-spec ctr_reg(C, GlobalENBId) -> C
when C :: [ctr | _],
@@ -308,25 +311,6 @@
S1 :: proxy_state(),
Result :: {forward | reply, s1ap_utils:s1ap_pdu()} | forward | drop.
-%% 9.1.8.4 S1 SETUP REQUEST
-handle_pdu({initiatingMessage,
- #'InitiatingMessage'{procedureCode = ?'id-S1Setup',
- value = C0}}, S0) ->
- ?LOG_DEBUG("Processing S1 SETUP REQUEST"),
- %% there's nothing to patch in this PDU, so we forward it as-is
- %% TODO: check result of handle_ies(), inc. ?S1GW_CTR_S1AP_PROXY_IN_PKT_PROC_ERROR
- {_, S1} = handle_ies(?'id-Global-ENB-ID',
- C0#'S1SetupRequest'.protocolIEs, S0),
- {forward, S1};
-
-%% 9.1.8.5 S1 SETUP RESPONSE
-handle_pdu({successfulOutcome,
- #'SuccessfulOutcome'{procedureCode = ?'id-S1Setup'}}, S) ->
- ?LOG_DEBUG("Processing S1 SETUP RESPONSE"),
- signal_enb_info(S),
- %% there's nothing to patch in this PDU, so we forward it as-is
- {forward, S};
-
%% 9.1.3.1 E-RAB SETUP REQUEST
handle_pdu({Outcome = initiatingMessage,
@@ -642,32 +626,6 @@
Result :: {handle_ie_result(),
proxy_state()}.
-handle_ie([?'id-Global-ENB-ID'],
- #'Global-ENB-ID'{'pLMNidentity' = PLMNId,
- 'eNB-ID' = ENBId} = C, S0) ->
- %% store PLMNId/ENBId
- S1 = S0#proxy_state{plmn_id = s1ap_utils:parse_plmn_id(PLMNId),
- enb_id = s1ap_utils:parse_enb_id(ENBId)},
- ?LOG_INFO("Global-ENB-ID: PLMN-ID=~p, eNB-ID=~p",
- [S1#proxy_state.plmn_id,
- S1#proxy_state.enb_id]),
- %% use that as a context for logging
- GlobalENBId = s1ap_utils:genb_id_str(#{plmn_id => S1#proxy_state.plmn_id,
- enb_id => S1#proxy_state.enb_id}),
- osmo_s1gw:set_log_prefix("eNB " ++ GlobalENBId),
- %% register per-eNB metrics
- ctr_reg_all(GlobalENBId),
- %% increment per-eNB ?S1GW_CTR_S1AP_PROXY_IN_PKT_ALL, if needed
- %% this is needed to count S1 Setup Req correctly
- S2 = case S0#proxy_state.genb_id_str of
- GlobalENBId -> S1;
- _ ->
- Ctr = s1gw_metrics:enb_metric(?S1GW_CTR_S1AP_PROXY_IN_PKT_ALL, GlobalENBId),
- s1gw_metrics:ctr_inc(Ctr),
- S1#proxy_state{genb_id_str = GlobalENBId}
- end,
- {{ok, C}, S2};
-
%% E-RAB SETUP REQUEST related IEs
handle_ie([?'id-E-RABToBeSetupListBearerSUReq'], C, S) ->
%% This IE contains a list of BearerSUReq, so patch inner IEs
@@ -1196,11 +1154,4 @@
ok.
-%% Signal eNB info to the parent process
--spec signal_enb_info(proxy_state()) -> ok.
-signal_enb_info(#proxy_state{owner = Pid} = S) ->
- Pid ! {?MODULE, {enb_info, enb_info(S)}},
- ok.
-
-
%% vim:set ts=4 sw=4 et:
diff --git a/src/sctp_proxy.erl b/src/sctp_proxy.erl
index 60f0c11..305d7d7 100644
--- a/src/sctp_proxy.erl
+++ b/src/sctp_proxy.erl
@@ -1,4 +1,4 @@
-%% Copyright (C) 2024 by sysmocom - s.f.m.c. GmbH <info(a)sysmocom.de>
+%% Copyright (C) 2024-2025 by sysmocom - s.f.m.c. GmbH <info(a)sysmocom.de>
%% Author: Vadim Yanitskiy <vyanitskiy(a)sysmocom.de>
%%
%% All Rights Reserved
@@ -38,6 +38,8 @@
-export([init/1,
callback_mode/0,
+ wait_s1setup_req/3,
+ wait_s1setup_rsp/3,
connecting/3,
connected/3,
code_change/4,
@@ -53,6 +55,8 @@
-include("s1gw_metrics.hrl").
+-include("S1AP-Constants.hrl").
+
-type conn_info() :: #{state := atom(),
handler := pid(),
@@ -66,7 +70,7 @@
mme_aid :: undefined | gen_sctp:assoc_id(),
enb_conn_info :: sctp_server:conn_info(),
mme_conn_cfg :: sctp_client:cfg(),
- tx_queue :: [binary()],
+ s1setup_req :: undefined | binary(),
sock :: undefined | gen_sctp:sctp_socket(),
enb_handle :: enb_registry:enb_handle(),
genb_id_str :: undefined | string(),
@@ -111,12 +115,12 @@
init([EnbConnInfo, MmeConnCfg]) ->
{ok, EnbHandle} = enb_registry:enb_register(),
+ enb_registry:enb_event(EnbHandle, {connecting, EnbConnInfo}),
{ok, Pid} = s1ap_proxy:start_link(self()),
- {ok, connecting,
+ {ok, wait_s1setup_req,
#state{enb_aid = maps:get(aid, EnbConnInfo),
enb_conn_info = EnbConnInfo,
mme_conn_cfg = MmeConnCfg,
- tx_queue = [],
enb_handle = EnbHandle,
handler = Pid}}.
@@ -125,13 +129,50 @@
[state_functions, state_enter].
+%% WAIT_S1SETUP_REQ state
+wait_s1setup_req(enter, _OldState, S) ->
+ ?LOG_INFO("State enter: ~p", [?FUNCTION_NAME]),
+ {next_state, ?FUNCTION_NAME, S,
+ [{state_timeout, 5_000, s1setup_req_timeout}]};
+
+%% Handle S1 SETUP REQUEST timeout
+wait_s1setup_req(state_timeout, s1setup_req_timeout, _S) ->
+ ?LOG_ERROR("Timeout waiting for S1 SETUP REQUEST from eNB"),
+ {stop, {shutdown, s1setup_req_timeout}};
+
+%% Handle PDUs coming from the eNB
+wait_s1setup_req(cast, {send_data, Data}, S) ->
+ ?LOG_DEBUG("Rx S1AP PDU from eNB: ~p", [Data]),
+ case s1ap_utils:parse_pdu(Data) of
+ {{?'id-S1Setup', initiatingMessage}, IEs} ->
+ %% fetch the Global-eNB-ID IE, convert it to a string
+ GENBId = proplists:get_value(?'id-Global-ENB-ID', IEs),
+ GlobalENBId = s1ap_utils:genb_id_str(GENBId),
+ %% use it as the logging prefix
+ osmo_s1gw:set_log_prefix("eNB " ++ GlobalENBId),
+ ?LOG_INFO("Rx S1 SETUP REQUEST from eNB"),
+ %% signal the Global-eNB-ID to other modules
+ s1ap_proxy:set_genb_id(S#state.handler, GlobalENBId),
+ enb_registry:enb_event(S#state.enb_handle, {s1setup, GENBId}),
+ gtpu_kpi_enb_register(S#state{genb_id_str = GlobalENBId}),
+ {next_state, connecting,
+ S#state{s1setup_req = Data,
+ genb_id_str = GlobalENBId}};
+ {{Proc, Type}, IEs} ->
+ ?LOG_ERROR("Rx unexpected S1AP PDU from eNB: ~p/~p, ~p", [Proc, Type, IEs]),
+ {stop, {shutdown, s1setup_error}};
+ {error, _Error} ->
+ {stop, {shutdown, s1setup_error}}
+ end;
+
+wait_s1setup_req(Event, EventData, S) ->
+ handle_event(?FUNCTION_NAME, Event, EventData, S).
+
+
%% CONNECTING state
connecting(enter, OldState,
- #state{enb_conn_info = EnbConnInfo,
- mme_conn_cfg = MmeConnCfg,
- enb_handle = Handle} = S) ->
+ #state{mme_conn_cfg = MmeConnCfg} = S) ->
?LOG_INFO("State change: ~p -> ~p", [OldState, ?FUNCTION_NAME]),
- ok = enb_registry:enb_event(Handle, {?FUNCTION_NAME, EnbConnInfo}),
%% Initiate connection establishment with the MME
{ok, Sock} = sctp_client:connect(MmeConnCfg),
%% loop transition to enable state_timeout
@@ -142,12 +183,10 @@
connecting(state_timeout, conn_est_timeout, _S) ->
{stop, {shutdown, conn_est_timeout}};
-%% Handle an eNB -> MME data forwarding request (queue)
-connecting(cast, {send_data, Data},
- #state{tx_queue = Pending} = S) ->
- s1gw_metrics:ctr_inc(?S1GW_CTR_S1AP_PROXY_UPLINK_PACKETS_QUEUED),
- s1gw_metrics:gauge_inc(?S1GW_GAUGE_S1AP_PROXY_UPLINK_PACKETS_QUEUED),
- {keep_state, S#state{tx_queue = [Data | Pending]}};
+%% Handle PDUs coming from the eNB
+connecting(cast, {send_data, Data}, _S) ->
+ ?LOG_ERROR("Rx unexpected S1AP PDU from eNB: ~p", [Data]),
+ keep_state_and_data;
%% Handle an #sctp_assoc_change event (connection state)
connecting(info, {sctp, _Socket, MmeAddr, MmePort,
@@ -157,7 +196,10 @@
comm_up ->
?LOG_NOTICE("MME connection (id=~p, ~p:~p) established",
[Aid, MmeAddr, MmePort]),
- {next_state, connected, S#state{mme_aid = Aid}};
+ %% send the S1 SETUP REQUEST PDU to the MME
+ sctp_send_from_enb(S#state.s1setup_req,
+ S#state{mme_aid = Aid}),
+ {next_state, wait_s1setup_rsp, S#state{mme_aid = Aid}};
_ ->
?LOG_NOTICE("MME connection establishment failed: ~p", [ConnState]),
{stop, {shutdown, conn_est_fail}}
@@ -167,15 +209,75 @@
handle_event(?FUNCTION_NAME, Event, EventData, S).
+%% WAIT_S1SETUP_RSP state
+wait_s1setup_rsp(enter, OldState, S) ->
+ ?LOG_INFO("State change: ~p -> ~p", [OldState, ?FUNCTION_NAME]),
+ {next_state, ?FUNCTION_NAME, S,
+ [{state_timeout, 5_000, s1setup_rsp_timeout}]};
+
+%% Handle S1 SETUP RESPONSE timeout
+wait_s1setup_rsp(state_timeout, s1setup_rsp_timeout, _S) ->
+ ?LOG_ERROR("Timeout waiting for S1 SETUP RESPONSE from MME"),
+ {stop, {shutdown, s1setup_rsp_timeout}};
+
+%% Handle PDUs coming from the eNB
+wait_s1setup_rsp(cast, {send_data, Data}, _S) ->
+ ?LOG_ERROR("Rx unexpected S1AP PDU from eNB: ~p", [Data]),
+ keep_state_and_data;
+
+%% Handle PDUs coming from the MME
+wait_s1setup_rsp(info, {sctp, _Socket, MmeAddr, MmePort,
+ {[#sctp_sndrcvinfo{assoc_id = MmeAid,
+ stream = SID,
+ ssn = SSN,
+ tsn = TSN}], Data}},
+ #state{mme_aid = MmeAid} = S) ->
+ ?LOG_DEBUG("MME connection (id=~p, ~p:~p) -> eNB: ~p",
+ [MmeAid, MmeAddr, MmePort,
+ #{tsn => TSN, sid => SID, ssn => SSN,
+ len => byte_size(Data), data => Data}]),
+ case s1ap_utils:parse_pdu(Data) of
+ {{?'id-S1Setup', successfulOutcome}, _IEs} ->
+ ?LOG_INFO("Rx S1 SETUP RESPONSE from MME"),
+ sctp_send_from_mme(Data, S),
+ {next_state, connected, S};
+ {{?'id-S1Setup', unsuccessfulOutcome}, _IEs} ->
+ ?LOG_NOTICE("Rx S1 SETUP FAILURE from MME"),
+ sctp_send_from_mme(Data, S),
+ {stop, {shutdown, s1setup_error}};
+ {{Proc, Type}, IEs} ->
+ ?LOG_ERROR("Rx unexpected S1AP PDU from MME: ~p/~p, ~p", [Proc, Type, IEs]),
+ {stop, {shutdown, s1setup_error}};
+ {error, _Error} ->
+ {stop, {shutdown, s1setup_error}}
+ end;
+
+%% Handle an #sctp_assoc_change event (MME connection state)
+%% We may loose connection while waiting for the S1 SETUP RESPONSE
+wait_s1setup_rsp(info, {sctp, _Socket, MmeAddr, MmePort,
+ {[], #sctp_assoc_change{state = ConnState,
+ assoc_id = Aid}}}, S) ->
+ case ConnState of
+ comm_up ->
+ ?LOG_NOTICE("MME connection (id=~p, ~p:~p) is already established?!?",
+ [Aid, MmeAddr, MmePort]),
+ {keep_state, S};
+ _ ->
+ ?LOG_NOTICE("MME connection state: ~p", [ConnState]),
+ {stop, {shutdown, conn_fail}}
+ end;
+
+wait_s1setup_rsp(Event, EventData, S) ->
+ handle_event(?FUNCTION_NAME, Event, EventData, S).
+
+
%% CONNECTED state
connected(enter, OldState,
- #state{enb_handle = Handle} = S0) ->
+ #state{enb_handle = Handle} = S) ->
?LOG_INFO("State change: ~p -> ~p", [OldState, ?FUNCTION_NAME]),
- MmeConnInfo = conn_info(?FUNCTION_NAME, S0),
+ MmeConnInfo = conn_info(?FUNCTION_NAME, S),
ok = enb_registry:enb_event(Handle, {?FUNCTION_NAME, MmeConnInfo}),
- %% Send pending eNB -> MME messages (if any)
- S1 = sctp_send_pending(S0),
- {keep_state, S1};
+ {keep_state, S};
%% Handle an eNB -> MME data forwarding request (forward)
connected(cast, {send_data, Data}, S0) ->
@@ -210,14 +312,6 @@
sctp_send_from_mme(Data, S),
{keep_state, S};
-%% eNB info indication from s1ap_proxy
-connected(info, {s1ap_proxy, {enb_info, EnbInfo}},
- #state{enb_handle = EnbHandle} = S0) ->
- enb_registry:enb_event(EnbHandle, {s1setup, EnbInfo}),
- S1 = S0#state{genb_id_str = maps:get(genb_id_str, EnbInfo)},
- gtpu_kpi_enb_register(S1),
- {keep_state, S1};
-
%% eNB's GTP-U address indication from s1ap_proxy
connected(info, {s1ap_proxy, {enb_addr, Addr}}, S) ->
gtpu_kpi_enb_set_addr({s1ap, Addr}),
@@ -315,15 +409,6 @@
end.
-%% Send pending messages to the MME
--spec sctp_send_pending(state()) -> state().
-sctp_send_pending(#state{tx_queue = Pending} = S) ->
- [] = lists:filter(fun(Data) -> sctp_send_from_enb(Data, S) =/= ok end,
- lists:reverse(Pending)),
- s1gw_metrics:gauge_set(?S1GW_GAUGE_S1AP_PROXY_UPLINK_PACKETS_QUEUED, 0),
- S#state{tx_queue = []}.
-
-
-spec conn_info(atom(), state()) -> conn_info().
conn_info(State, #state{mme_conn_cfg = MmeConnCfg} = S) ->
Info = #{state => State,
diff --git a/test/s1ap_proxy_test.erl b/test/s1ap_proxy_test.erl
index e376304..2d748bf 100644
--- a/test/s1ap_proxy_test.erl
+++ b/test/s1ap_proxy_test.erl
@@ -32,6 +32,7 @@
gtpu_kpi:start_link(#{enable => false}),
{ok, EnbHandle} = enb_registry:enb_register(),
{ok, Pid} = s1ap_proxy:start_link(self()),
+ s1ap_proxy:set_genb_id(Pid, ?GlobalENBId),
ok = enb_registry:enb_unregister(EnbHandle),
#{handler => Pid}.
--
To view, visit https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41622?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: erlang/osmo-s1gw
Gerrit-Branch: master
Gerrit-Change-Id: I9aa67732b418bcdf3f10b2db89a41dda26ee3d4e
Gerrit-Change-Number: 41622
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <vyanitskiy(a)sysmocom.de>
1
0
05 Dec '25
fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41624?usp=email )
Change subject: enb_proxy: add inital MME pooling support
......................................................................
enb_proxy: add inital MME pooling support
Change-Id: I83dc4a78c78a7b87e87f5ca9a941a168d6c1dc36
Related: SYS#7052
---
M src/enb_proxy.erl
M src/s1ap_utils.erl
2 files changed, 74 insertions(+), 32 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-s1gw refs/changes/24/41624/1
diff --git a/src/enb_proxy.erl b/src/enb_proxy.erl
index 7a51221..bc36c96 100644
--- a/src/enb_proxy.erl
+++ b/src/enb_proxy.erl
@@ -71,6 +71,8 @@
enb_conn_info :: sctp_server:conn_info(),
mme_conn_cfg :: sctp_client:cfg(),
s1setup_req :: undefined | binary(),
+ mme_name :: undefined | mme_registry:mme_name(),
+ enb_tacs :: undefined | [s1ap_utils:tac()],
sock :: undefined | gen_sctp:sctp_socket(),
enb_handle :: enb_registry:enb_handle(),
genb_id_str :: undefined | string(),
@@ -155,9 +157,13 @@
s1ap_proxy:set_genb_id(S#state.handler, GlobalENBId),
enb_registry:enb_event(S#state.enb_handle, {s1setup, GENBId}),
gtpu_kpi_enb_register(S#state{genb_id_str = GlobalENBId}),
+ %% fetch the TAC (Tracking Area Code) list
+ TACs = proplists:get_value(?'id-SupportedTAs', IEs),
+ ?LOG_DEBUG("Broadcast TACs: ~p", [TACs]),
{next_state, connecting,
S#state{s1setup_req = Data,
- genb_id_str = GlobalENBId}};
+ genb_id_str = GlobalENBId,
+ enb_tacs = TACs}};
{{Proc, Type}, IEs} ->
?LOG_ERROR("Rx unexpected S1AP PDU from eNB: ~p/~p, ~p", [Proc, Type, IEs]),
{stop, {shutdown, s1setup_error}};
@@ -171,17 +177,40 @@
%% CONNECTING state
connecting(enter, OldState,
- #state{mme_conn_cfg = MmeConnCfg} = S) ->
+ #state{mme_name = MmeName,
+ enb_tacs = EnbTACs} = S) ->
?LOG_INFO("State change: ~p -> ~p", [OldState, ?FUNCTION_NAME]),
- %% Initiate connection establishment with the MME
- {ok, Sock} = sctp_client:connect(MmeConnCfg),
- %% loop transition to enable state_timeout
- {next_state, ?FUNCTION_NAME, S#state{sock = Sock},
- [{state_timeout, 2_000, conn_est_timeout}]};
+ %% Select an MME from the pool
+ case mme_registry:mme_select(#{prev_mme => MmeName,
+ enb_tacs => EnbTACs}) of
+ {ok, MmeInfo} ->
+ ?LOG_INFO("MME selection: trying ~p", [maps:get(name, MmeInfo)]),
+ %% Close the old connection, if any
+ close_sock(S),
+ %% Initiate connection establishment with the MME
+ MmeSockOpts = maps:get(sockopts, S#state.mme_conn_cfg),
+ MmeConnCfg = #{laddr => maps:get(laddr, MmeInfo),
+ raddr => maps:get(raddr, MmeInfo),
+ rport => maps:get(rport, MmeInfo),
+ sockopts => MmeSockOpts},
+ {ok, Sock} = sctp_client:connect(MmeConnCfg),
+ {next_state, ?FUNCTION_NAME, %% loop transition to enable state_timeout
+ S#state{sock = Sock,
+ mme_aid = undefined,
+ mme_name = maps:get(name, MmeInfo),
+ mme_conn_cfg = MmeConnCfg},
+ [{state_timeout, 2_000, conn_est_timeout}]};
+ error ->
+ ?LOG_ERROR("Failed to select an MME"),
+ {stop, {shutdown, mme_select_error}}
+ end;
%% Handle connection establishment timeout
-connecting(state_timeout, conn_est_timeout, _S) ->
- {stop, {shutdown, conn_est_timeout}};
+connecting(state_timeout, conn_est_timeout,
+ #state{mme_name = MmeName}) ->
+ ?LOG_ERROR("Timeout establishing connection with MME ~p", [MmeName]),
+ %% re-enter the state to try again (or another MME)
+ repeat_state_and_data;
%% Handle PDUs coming from the eNB
connecting(cast, {send_data, Data}, _S) ->
@@ -202,7 +231,8 @@
{next_state, wait_s1setup_rsp, S#state{mme_aid = Aid}};
_ ->
?LOG_NOTICE("MME connection establishment failed: ~p", [ConnState]),
- {stop, {shutdown, conn_est_fail}}
+ %% re-enter the state to try again (or another MME)
+ repeat_state_and_data
end;
connecting(Event, EventData, S) ->
@@ -216,9 +246,10 @@
[{state_timeout, 5_000, s1setup_rsp_timeout}]};
%% Handle S1 SETUP RESPONSE timeout
-wait_s1setup_rsp(state_timeout, s1setup_rsp_timeout, _S) ->
- ?LOG_ERROR("Timeout waiting for S1 SETUP RESPONSE from MME"),
- {stop, {shutdown, s1setup_rsp_timeout}};
+wait_s1setup_rsp(state_timeout, s1setup_rsp_timeout, S) ->
+ ?LOG_ERROR("Timeout waiting for S1 SETUP RESPONSE from the MME"),
+ %% re-enter state 'connecting' to try again (or another MME)
+ {next_state, connecting, S};
%% Handle PDUs coming from the eNB
wait_s1setup_rsp(cast, {send_data, Data}, _S) ->
@@ -243,13 +274,16 @@
{next_state, connected, S};
{{?'id-S1Setup', unsuccessfulOutcome}, _IEs} ->
?LOG_NOTICE("Rx S1 SETUP FAILURE from MME"),
- sctp_send_from_mme(Data, S),
- {stop, {shutdown, s1setup_error}};
+ %% XXX: sctp_send_from_mme(Data, S),
+ %% re-enter state 'connecting' to try again (or another MME)
+ {next_state, connecting, S};
{{Proc, Type}, IEs} ->
?LOG_ERROR("Rx unexpected S1AP PDU from MME: ~p/~p, ~p", [Proc, Type, IEs]),
- {stop, {shutdown, s1setup_error}};
+ %% re-enter state 'connecting' to try again (or another MME)
+ {next_state, connecting, S};
{error, _Error} ->
- {stop, {shutdown, s1setup_error}}
+ %% re-enter state 'connecting' to try again (or another MME)
+ {next_state, connecting, S}
end;
%% Handle an #sctp_assoc_change event (MME connection state)
@@ -264,7 +298,8 @@
{keep_state, S};
_ ->
?LOG_NOTICE("MME connection state: ~p", [ConnState]),
- {stop, {shutdown, conn_fail}}
+ %% re-enter state 'connecting' to try again (or another MME)
+ {next_state, connecting, S}
end;
wait_s1setup_rsp(Event, EventData, S) ->
@@ -353,22 +388,11 @@
terminate(Reason, State,
#state{handler = Pid,
- enb_handle = Handle,
- sock = Sock,
- mme_aid = MmeAid}) ->
+ enb_handle = Handle} = S) ->
?LOG_NOTICE("Terminating in state ~p, reason ~p", [State, Reason]),
enb_registry:enb_unregister(Handle),
s1ap_proxy:shutdown(Pid),
- case Sock of
- undefined -> ok;
- _ ->
- case MmeAid of
- undefined -> ok;
- _ ->
- sctp_common:shutdown({Sock, MmeAid})
- end,
- gen_sctp:close(Sock)
- end.
+ close_sock(S).
%% ------------------------------------------------------------------
@@ -455,4 +479,20 @@
end.
+-spec close_sock(state()) -> ok | {error, term()}.
+close_sock(#state{sock = undefined}) -> ok;
+
+close_sock(#state{sock = Sock} = S) ->
+ close_conn(S), %% terminate the MME connection, if needed
+ gen_sctp:close(Sock).
+
+
+
+-spec close_conn(state()) -> ok | {error, term()}.
+close_conn(#state{mme_aid = undefined}) -> ok;
+
+close_conn(#state{sock = Sock, mme_aid = MmeAid}) ->
+ sctp_common:shutdown({Sock, MmeAid}).
+
+
%% vim:set ts=4 sw=4 et:
diff --git a/src/s1ap_utils.erl b/src/s1ap_utils.erl
index 6f7e6b6..d813e76 100644
--- a/src/s1ap_utils.erl
+++ b/src/s1ap_utils.erl
@@ -68,13 +68,15 @@
s1ap_pdu_info/0]).
+-type tac() :: 0..16#ffff.
-type enb_id() :: 0..16#fffffff.
-type plmn_id() :: {MCC :: nonempty_string(),
MNC :: nonempty_string()}.
-type genb_id() :: #{enb_id => enb_id(),
plmn_id => plmn_id()}.
--export_type([enb_id/0,
+-export_type([tac/0,
+ enb_id/0,
plmn_id/0,
genb_id/0]).
--
To view, visit https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41624?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: erlang/osmo-s1gw
Gerrit-Branch: master
Gerrit-Change-Id: I83dc4a78c78a7b87e87f5ca9a941a168d6c1dc36
Gerrit-Change-Number: 41624
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <vyanitskiy(a)sysmocom.de>
1
0
[M] Change in ...osmo-s1gw[master]: sctp_proxy: add _from_{enb,mme} variants of sctp_send/2
by fixeria 05 Dec '25
by fixeria 05 Dec '25
05 Dec '25
fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41613?usp=email )
Change subject: sctp_proxy: add _from_{enb,mme} variants of sctp_send/2
......................................................................
sctp_proxy: add _from_{enb,mme} variants of sctp_send/2
The existing sctp_send/2 is sending data from an eNB towards
the MME. Sending data in the opposite direction is done in-place.
For the sake of readability, let's add the counterpart of sctp_send/2
and clarify the direction by adding _from_{enb,mme} to function names.
Change-Id: I388137e27ea5000f22e7a5b58d1ffcfd9caa1475
---
M src/sctp_proxy.erl
1 file changed, 35 insertions(+), 23 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-s1gw refs/changes/13/41613/1
diff --git a/src/sctp_proxy.erl b/src/sctp_proxy.erl
index 3aa67d8..ad58d4b 100644
--- a/src/sctp_proxy.erl
+++ b/src/sctp_proxy.erl
@@ -165,7 +165,7 @@
%% Handle an eNB -> MME data forwarding request (forward)
connected(cast, {send_data, Data}, S0) ->
- sctp_send(Data, S0),
+ sctp_send_from_enb(Data, S0),
{keep_state, S0};
%% Handle an #sctp_assoc_change event (MME connection state)
@@ -184,26 +184,16 @@
%% Handle an #sctp_sndrcvinfo event (MME -> eNB data)
connected(info, {sctp, _Socket, MmeAddr, MmePort,
- {[#sctp_sndrcvinfo{assoc_id = Aid,
+ {[#sctp_sndrcvinfo{assoc_id = MmeAid,
stream = SID,
ssn = SSN,
tsn = TSN}], Data}},
- #{sock := Sock,
- enb_aid := EnbAid,
- mme_aid := Aid,
- handler := Pid} = S) ->
+ #{mme_aid := MmeAid} = S) ->
?LOG_DEBUG("MME connection (id=~p, ~p:~p) -> eNB: ~p",
- [Aid, MmeAddr, MmePort,
+ [MmeAid, MmeAddr, MmePort,
#{tsn => TSN, sid => SID, ssn => SSN,
len => byte_size(Data), data => Data}]),
- case s1ap_proxy:process_pdu(Pid, Data) of
- {forward, FwdData} ->
- sctp_server:send_data(EnbAid, FwdData);
- {reply, ReData} ->
- ok = sctp_common:send_data({Sock, Aid}, ReData);
- {drop, Data} ->
- ok %% no-op
- end,
+ sctp_send_from_mme(Data, S),
{keep_state, S};
connected(Event, EventData, S) ->
@@ -261,15 +251,20 @@
%% private API
%% ------------------------------------------------------------------
-%% Send a single message to the MME
-sctp_send(Data,
- #{sock := Sock,
- enb_aid := EnbAid,
- mme_aid := Aid,
- handler := Pid}) ->
+%% XXX: proper type
+-type state() :: map().
+
+
+%% Send a single message: eNB -> MME
+-spec sctp_send_from_enb(binary(), state()) -> ok | {error, term()}.
+sctp_send_from_enb(Data,
+ #{sock := Sock,
+ enb_aid := EnbAid,
+ mme_aid := MmeAid,
+ handler := Pid}) ->
case s1ap_proxy:process_pdu(Pid, Data) of
{forward, FwdData} ->
- ok = sctp_common:send_data({Sock, Aid}, FwdData);
+ sctp_common:send_data({Sock, MmeAid}, FwdData);
{reply, ReData} ->
sctp_server:send_data(EnbAid, ReData);
{drop, Data} ->
@@ -277,12 +272,29 @@
end.
+%% Send a single message: eNB <- MME
+-spec sctp_send_from_mme(binary(), state()) -> ok | {error, term()}.
+sctp_send_from_mme(Data,
+ #{sock := Sock,
+ enb_aid := EnbAid,
+ mme_aid := MmeAid,
+ handler := Pid}) ->
+ case s1ap_proxy:process_pdu(Pid, Data) of
+ {forward, FwdData} ->
+ sctp_server:send_data(EnbAid, FwdData);
+ {reply, ReData} ->
+ sctp_common:send_data({Sock, MmeAid}, ReData);
+ {drop, Data} ->
+ ok %% no-op
+ end.
+
+
%% Send pending messages to the MME
sctp_send_pending(#{tx_queue := Pending} = S) ->
sctp_send_pending(lists:reverse(Pending), S).
sctp_send_pending([Data | Pending], S) ->
- sctp_send(Data, S),
+ sctp_send_from_enb(Data, S),
s1gw_metrics:gauge_dec(?S1GW_GAUGE_S1AP_PROXY_UPLINK_PACKETS_QUEUED),
sctp_send_pending(Pending, S);
--
To view, visit https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41613?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: erlang/osmo-s1gw
Gerrit-Branch: master
Gerrit-Change-Id: I388137e27ea5000f22e7a5b58d1ffcfd9caa1475
Gerrit-Change-Number: 41613
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <vyanitskiy(a)sysmocom.de>
1
0
05 Dec '25
fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41612?usp=email )
Change subject: osmo_s1gw: add set_log_prefix/1
......................................................................
osmo_s1gw: add set_log_prefix/1
Let's have a common API that can be used by all other modules.
Change-Id: I77ee96f195067ef0137f2cb8af5d455b24ccdd54
---
M src/erab_fsm.erl
M src/osmo_s1gw.erl
M src/s1ap_proxy.erl
3 files changed, 9 insertions(+), 7 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-s1gw refs/changes/12/41612/1
diff --git a/src/erab_fsm.erl b/src/erab_fsm.erl
index 1871919..f281e4b 100644
--- a/src/erab_fsm.erl
+++ b/src/erab_fsm.erl
@@ -610,7 +610,7 @@
%% set process metadata for the logger
set_logging_prefix(UID) ->
Prefix = io_lib:format("E-RAB ~p", [UID]),
- logger:set_process_metadata(#{prefix => Prefix}).
+ osmo_s1gw:set_log_prefix(Prefix).
-spec session_establish_req(erab_state()) -> pfcp_peer:pfcp_session_rsp().
diff --git a/src/osmo_s1gw.erl b/src/osmo_s1gw.erl
index 4444fe0..144301a 100644
--- a/src/osmo_s1gw.erl
+++ b/src/osmo_s1gw.erl
@@ -37,6 +37,7 @@
-export([get_env/2,
set_env/2,
get_priv/1,
+ set_log_prefix/1,
main/1]).
-define(ENV_APP_NAME, osmo_s1gw).
@@ -69,6 +70,12 @@
filename:join(PrivDir, Name).
+%% Set logging prefix for the calling process
+-spec set_log_prefix(string()) -> ok.
+set_log_prefix(Prefix) when is_list(Prefix) ->
+ logger:set_process_metadata(#{prefix => Prefix}).
+
+
main(_Args) ->
application:ensure_all_started(?MODULE),
timer:sleep(infinity).
diff --git a/src/s1ap_proxy.erl b/src/s1ap_proxy.erl
index 502480e..a241611 100644
--- a/src/s1ap_proxy.erl
+++ b/src/s1ap_proxy.erl
@@ -200,11 +200,6 @@
%% private API
%% ------------------------------------------------------------------
--spec set_logging_prefix(string()) -> ok.
-set_logging_prefix(Prefix) when is_list(Prefix) ->
- logger:set_process_metadata(#{prefix => Prefix}).
-
-
-spec erab_uid(erab_id(), proxy_state()) -> erab_uid().
erab_uid(ERABId, #proxy_state{mme_ue_id = MmeUeId}) ->
{MmeUeId, ERABId}.
@@ -733,7 +728,7 @@
S1#proxy_state.enb_id]),
%% use that as a context for logging
GlobalENBId = genb_id_str(S1),
- set_logging_prefix("eNB " ++ GlobalENBId),
+ osmo_s1gw:set_log_prefix("eNB " ++ GlobalENBId),
%% register per-eNB metrics
ctr_reg_all(GlobalENBId),
%% increment per-eNB ?S1GW_CTR_S1AP_PROXY_IN_PKT_ALL, if needed
--
To view, visit https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41612?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: erlang/osmo-s1gw
Gerrit-Branch: master
Gerrit-Change-Id: I77ee96f195067ef0137f2cb8af5d455b24ccdd54
Gerrit-Change-Number: 41612
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <vyanitskiy(a)sysmocom.de>
1
0
[M] Change in ...osmo-s1gw[master]: sctp_proxy: use a record for storing state data
by fixeria 05 Dec '25
by fixeria 05 Dec '25
05 Dec '25
fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41615?usp=email )
Change subject: sctp_proxy: use a record for storing state data
......................................................................
sctp_proxy: use a record for storing state data
Maps are convenient, but they are also more permissive: field names
are unchecked at compile time, making it easier for typos or unexpected
fields to slip through. Records, on the other hand, are stricter and
more declarative. Their structure is explicitly defined, the set of
fields is fixed, and the compiler can validate field names.
Change-Id: Ice9c255c0cf14db0a216bb078198b9b9c76d22a7
---
M src/sctp_proxy.erl
1 file changed, 61 insertions(+), 45 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-s1gw refs/changes/15/41615/1
diff --git a/src/sctp_proxy.erl b/src/sctp_proxy.erl
index 458c53a..5e0d26e 100644
--- a/src/sctp_proxy.erl
+++ b/src/sctp_proxy.erl
@@ -62,6 +62,18 @@
mme_aid => gen_sctp:assoc_id()
}.
+-record(state, {enb_aid :: gen_sctp:assoc_id(),
+ mme_aid :: undefined | gen_sctp:assoc_id(),
+ enb_conn_info :: sctp_server:conn_info(),
+ mme_conn_cfg :: sctp_client:cfg(),
+ tx_queue :: [binary()],
+ sock :: undefined | gen_sctp:sctp_socket(),
+ enb_handle :: enb_registry:enb_handle(),
+ handler :: pid() %% s1ap_proxy process' pid
+ }).
+
+-type state() :: #state{}.
+
-export_type([conn_info/0]).
@@ -100,12 +112,12 @@
{ok, EnbHandle} = enb_registry:enb_register(),
{ok, Pid} = s1ap_proxy:start_link(EnbHandle, EnbConnInfo),
{ok, connecting,
- #{enb_aid => maps:get(aid, EnbConnInfo),
- enb_conn_info => EnbConnInfo,
- mme_conn_cfg => MmeConnCfg,
- tx_queue => [],
- enb_handle => EnbHandle,
- handler => Pid}}.
+ #state{enb_aid = maps:get(aid, EnbConnInfo),
+ enb_conn_info = EnbConnInfo,
+ mme_conn_cfg = MmeConnCfg,
+ tx_queue = [],
+ enb_handle = EnbHandle,
+ handler = Pid}}.
callback_mode() ->
@@ -114,14 +126,14 @@
%% CONNECTING state
connecting(enter, OldState,
- #{enb_conn_info := EnbConnInfo,
- mme_conn_cfg := MmeConnCfg,
- enb_handle := Handle} = S) ->
+ #state{enb_conn_info = EnbConnInfo,
+ mme_conn_cfg = MmeConnCfg,
+ enb_handle = Handle} = S) ->
?LOG_INFO("State change: ~p -> ~p", [OldState, ?FUNCTION_NAME]),
ok = enb_registry:enb_event(Handle, {?FUNCTION_NAME, EnbConnInfo}),
%% Initiate connection establishment with the MME
{ok, Sock} = sctp_client:connect(MmeConnCfg),
- {next_state, connecting, S#{sock => Sock},
+ {next_state, connecting, S#state{sock = Sock},
[{state_timeout, 2_000, conn_est_timeout}]};
%% Handle connection establishment timeout
@@ -130,10 +142,10 @@
%% Handle an eNB -> MME data forwarding request (queue)
connecting(cast, {send_data, Data},
- #{tx_queue := Pending} = S) ->
+ #state{tx_queue = Pending} = S) ->
s1gw_metrics:ctr_inc(?S1GW_CTR_S1AP_PROXY_UPLINK_PACKETS_QUEUED),
s1gw_metrics:gauge_inc(?S1GW_GAUGE_S1AP_PROXY_UPLINK_PACKETS_QUEUED),
- {keep_state, S#{tx_queue => [Data | Pending]}};
+ {keep_state, S#state{tx_queue = [Data | Pending]}};
%% Handle an #sctp_assoc_change event (connection state)
connecting(info, {sctp, _Socket, MmeAddr, MmePort,
@@ -143,7 +155,7 @@
comm_up ->
?LOG_NOTICE("MME connection (id=~p, ~p:~p) established",
[Aid, MmeAddr, MmePort]),
- {next_state, connected, S#{mme_aid => Aid}};
+ {next_state, connected, S#state{mme_aid = Aid}};
_ ->
?LOG_NOTICE("MME connection establishment failed: ~p", [ConnState]),
{stop, {shutdown, conn_est_fail}}
@@ -155,7 +167,7 @@
%% CONNECTED state
connected(enter, OldState,
- #{enb_handle := Handle} = S0) ->
+ #state{enb_handle = Handle} = S0) ->
?LOG_INFO("State change: ~p -> ~p", [OldState, ?FUNCTION_NAME]),
MmeConnInfo = conn_info(?FUNCTION_NAME, S0),
ok = enb_registry:enb_event(Handle, {?FUNCTION_NAME, MmeConnInfo}),
@@ -188,7 +200,7 @@
stream = SID,
ssn = SSN,
tsn = TSN}], Data}},
- #{mme_aid := MmeAid} = S) ->
+ #state{mme_aid = MmeAid} = S) ->
?LOG_DEBUG("MME connection (id=~p, ~p:~p) -> eNB: ~p",
[MmeAid, MmeAddr, MmePort,
#{tsn => TSN, sid => SID, ssn => SSN,
@@ -231,19 +243,22 @@
terminate(Reason, State,
- #{handler := Pid,
- enb_handle := Handle} = S) ->
+ #state{handler = Pid,
+ enb_handle = Handle,
+ sock = Sock,
+ mme_aid = MmeAid}) ->
?LOG_NOTICE("Terminating in state ~p, reason ~p", [State, Reason]),
enb_registry:enb_unregister(Handle),
s1ap_proxy:shutdown(Pid),
- case S of
- #{sock := Sock,
- mme_aid := Aid} ->
- sctp_common:shutdown({Sock, Aid}),
- gen_sctp:close(Sock);
- #{sock := Sock} ->
- gen_sctp:close(Sock);
- _ -> ok
+ case Sock of
+ undefined -> ok;
+ _ ->
+ case MmeAid of
+ undefined -> ok;
+ _ ->
+ sctp_common:shutdown({Sock, MmeAid})
+ end,
+ gen_sctp:close(Sock)
end.
@@ -251,17 +266,13 @@
%% private API
%% ------------------------------------------------------------------
-%% XXX: proper type
--type state() :: map().
-
-
%% Send a single message: eNB -> MME
-spec sctp_send_from_enb(binary(), state()) -> ok | {error, term()}.
sctp_send_from_enb(Data,
- #{sock := Sock,
- enb_aid := EnbAid,
- mme_aid := MmeAid,
- handler := Pid}) ->
+ #state{sock = Sock,
+ enb_aid = EnbAid,
+ mme_aid = MmeAid,
+ handler = Pid}) ->
case s1ap_proxy:process_pdu(Pid, Data) of
{forward, FwdData} ->
sctp_common:send_data({Sock, MmeAid}, FwdData);
@@ -275,10 +286,10 @@
%% Send a single message: eNB <- MME
-spec sctp_send_from_mme(binary(), state()) -> ok | {error, term()}.
sctp_send_from_mme(Data,
- #{sock := Sock,
- enb_aid := EnbAid,
- mme_aid := MmeAid,
- handler := Pid}) ->
+ #state{sock = Sock,
+ enb_aid = EnbAid,
+ mme_aid = MmeAid,
+ handler = Pid}) ->
case s1ap_proxy:process_pdu(Pid, Data) of
{forward, FwdData} ->
sctp_server:send_data(EnbAid, FwdData);
@@ -290,23 +301,28 @@
%% Send pending messages to the MME
-sctp_send_pending(#{tx_queue := Pending} = S) ->
+-spec sctp_send_pending(state()) -> state().
+sctp_send_pending(#state{tx_queue = Pending} = S) ->
sctp_send_pending(lists:reverse(Pending), S).
+-spec sctp_send_pending([binary()], state()) -> state().
sctp_send_pending([Data | Pending], S) ->
sctp_send_from_enb(Data, S),
s1gw_metrics:gauge_dec(?S1GW_GAUGE_S1AP_PROXY_UPLINK_PACKETS_QUEUED),
sctp_send_pending(Pending, S);
sctp_send_pending([], S) ->
- S#{tx_queue := []}.
+ S#state{tx_queue = []}.
-conn_info(State, #{mme_conn_cfg := MmeConnCfg} = S0) ->
- S1 = maps:with([enb_aid, mme_aid, handler], S0),
- S1#{state => State,
- mme_addr => maps:get(raddr, MmeConnCfg),
- mme_port => maps:get(rport, MmeConnCfg)}.
-
+-spec conn_info(atom(), state()) -> conn_info().
+conn_info(State, #state{mme_conn_cfg = MmeConnCfg} = S) ->
+ Info = #{state => State,
+ handler => S#state.handler,
+ mme_addr => maps:get(raddr, MmeConnCfg),
+ mme_port => maps:get(rport, MmeConnCfg),
+ enb_aid => S#state.enb_aid,
+ mme_aid => S#state.mme_aid},
+ maps:filter(fun(_K, V) -> V =/= undefined end, Info).
%% vim:set ts=4 sw=4 et:
--
To view, visit https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41615?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: erlang/osmo-s1gw
Gerrit-Branch: master
Gerrit-Change-Id: Ice9c255c0cf14db0a216bb078198b9b9c76d22a7
Gerrit-Change-Number: 41615
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <vyanitskiy(a)sysmocom.de>
1
0
[S] Change in ...osmo-s1gw[master]: sctp_proxy: use lists:filter/2 in sctp_send_pending/2
by fixeria 05 Dec '25
by fixeria 05 Dec '25
05 Dec '25
fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41616?usp=email )
Change subject: sctp_proxy: use lists:filter/2 in sctp_send_pending/2
......................................................................
sctp_proxy: use lists:filter/2 in sctp_send_pending/2
Use less code to achieve the same result.
Change-Id: Ic666fd77bc6d04341f3c57140dea5d4a5e616e80
---
M src/sctp_proxy.erl
1 file changed, 3 insertions(+), 9 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-s1gw refs/changes/16/41616/1
diff --git a/src/sctp_proxy.erl b/src/sctp_proxy.erl
index 5e0d26e..2866fcd 100644
--- a/src/sctp_proxy.erl
+++ b/src/sctp_proxy.erl
@@ -303,15 +303,9 @@
%% Send pending messages to the MME
-spec sctp_send_pending(state()) -> state().
sctp_send_pending(#state{tx_queue = Pending} = S) ->
- sctp_send_pending(lists:reverse(Pending), S).
-
--spec sctp_send_pending([binary()], state()) -> state().
-sctp_send_pending([Data | Pending], S) ->
- sctp_send_from_enb(Data, S),
- s1gw_metrics:gauge_dec(?S1GW_GAUGE_S1AP_PROXY_UPLINK_PACKETS_QUEUED),
- sctp_send_pending(Pending, S);
-
-sctp_send_pending([], S) ->
+ [] = lists:filter(fun(Data) -> sctp_send_from_enb(Data, S) =/= ok end,
+ lists:reverse(Pending)),
+ s1gw_metrics:gauge_set(?S1GW_GAUGE_S1AP_PROXY_UPLINK_PACKETS_QUEUED, 0),
S#state{tx_queue = []}.
--
To view, visit https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41616?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: erlang/osmo-s1gw
Gerrit-Branch: master
Gerrit-Change-Id: Ic666fd77bc6d04341f3c57140dea5d4a5e616e80
Gerrit-Change-Number: 41616
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <vyanitskiy(a)sysmocom.de>
1
0
[XS] Change in ...osmo-s1gw[master]: sctp_proxy: fix wrong operator in connecting/3
by fixeria 05 Dec '25
by fixeria 05 Dec '25
05 Dec '25
fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41614?usp=email )
Change subject: sctp_proxy: fix wrong operator in connecting/3
......................................................................
sctp_proxy: fix wrong operator in connecting/3
We need to update the map, thus the update operation (`=>`) needs
to be used, not the matching (`:=`). We're lucky that eNBs usually
do not send anything before the MME responds to the S1Setup request;
otherwise the S1GW would crash here due to a mismatch.
Change-Id: I26d8a8da5cce89324a9e1150e4ecdf2084d097c8
---
M src/sctp_proxy.erl
1 file changed, 1 insertion(+), 1 deletion(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-s1gw refs/changes/14/41614/1
diff --git a/src/sctp_proxy.erl b/src/sctp_proxy.erl
index ad58d4b..458c53a 100644
--- a/src/sctp_proxy.erl
+++ b/src/sctp_proxy.erl
@@ -133,7 +133,7 @@
#{tx_queue := Pending} = S) ->
s1gw_metrics:ctr_inc(?S1GW_CTR_S1AP_PROXY_UPLINK_PACKETS_QUEUED),
s1gw_metrics:gauge_inc(?S1GW_GAUGE_S1AP_PROXY_UPLINK_PACKETS_QUEUED),
- {keep_state, S#{tx_queue := [Data | Pending]}};
+ {keep_state, S#{tx_queue => [Data | Pending]}};
%% Handle an #sctp_assoc_change event (connection state)
connecting(info, {sctp, _Socket, MmeAddr, MmePort,
--
To view, visit https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41614?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: erlang/osmo-s1gw
Gerrit-Branch: master
Gerrit-Change-Id: I26d8a8da5cce89324a9e1150e4ecdf2084d097c8
Gerrit-Change-Number: 41614
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <vyanitskiy(a)sysmocom.de>
1
0
[L] Change in ...osmo-s1gw[master]: test: move S1AP PDU samples (blobs) into their own file
by fixeria 05 Dec '25
by fixeria 05 Dec '25
05 Dec '25
fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41611?usp=email )
Change subject: test: move S1AP PDU samples (blobs) into their own file
......................................................................
test: move S1AP PDU samples (blobs) into their own file
This allows using these samples from other (upcoming) tests.
Change-Id: I4b1d3f3a009009ab7620656a3b906e60481e47a1
---
M test/s1ap_proxy_test.erl
A test/s1ap_samples.erl
2 files changed, 423 insertions(+), 396 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-s1gw refs/changes/11/41611/1
diff --git a/test/s1ap_proxy_test.erl b/test/s1ap_proxy_test.erl
index f21a227..8e05b99 100644
--- a/test/s1ap_proxy_test.erl
+++ b/test/s1ap_proxy_test.erl
@@ -100,8 +100,8 @@
%% ------------------------------------------------------------------
test_s1_setup(#{handler := Pid}) ->
- SetupReq = s1_setup_req_pdu(),
- SetupRsp = s1_setup_rsp_pdu(),
+ SetupReq = s1ap_samples:s1_setup_req_pdu(),
+ SetupRsp = s1ap_samples:s1_setup_rsp_pdu(),
%% Expect the PDUs to be proxied unmodified
[?_assertEqual({forward, SetupReq}, s1ap_proxy:process_pdu(Pid, SetupReq)),
?_assertEqual({forward, SetupRsp}, s1ap_proxy:process_pdu(Pid, SetupRsp)),
@@ -117,14 +117,14 @@
test_e_rab_setup(#{handler := Pid}) ->
%% [eNB <- MME] E-RAB SETUP REQUEST
- SetupReqIn = e_rab_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
- SetupReqExp = e_rab_setup_req_pdu(?ADDR_A2U, ?TEID_A2U),
+ SetupReqIn = s1ap_samples:e_rab_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
+ SetupReqExp = s1ap_samples:e_rab_setup_req_pdu(?ADDR_A2U, ?TEID_A2U),
%% [eNB -> MME] E-RAB SETUP RESPONSE
- SetupRspIn = e_rab_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
- SetupRspExp = e_rab_setup_rsp_pdu(?ADDR_C2U, ?TEID_C2U),
+ SetupRspIn = s1ap_samples:e_rab_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
+ SetupRspExp = s1ap_samples:e_rab_setup_rsp_pdu(?ADDR_C2U, ?TEID_C2U),
- [?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, s1_setup_req_pdu())),
- ?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, s1_setup_rsp_pdu())),
+ [?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, s1ap_samples:s1_setup_req_pdu())),
+ ?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, s1ap_samples:s1_setup_rsp_pdu())),
?_assertEqual({forward, SetupReqExp}, s1ap_proxy:process_pdu(Pid, SetupReqIn)),
?_assertEqual({forward, SetupRspExp}, s1ap_proxy:process_pdu(Pid, SetupRspIn)),
%% global counters
@@ -151,8 +151,8 @@
pfcp_mock:mock_req(session_establish_req, PDU),
%% eNB <- [S1GW <- MME] E-RAB SETUP REQUEST
%% eNB -- [S1GW -> MME] E-RAB SETUP RESPONSE (failure)
- SetupReqIn = e_rab_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
- SetupRspExp = e_rab_setup_rsp_fail_pdu(),
+ SetupReqIn = s1ap_samples:e_rab_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
+ SetupRspExp = s1ap_samples:e_rab_setup_rsp_fail_pdu(),
[?_assertEqual({reply, SetupRspExp}, s1ap_proxy:process_pdu(Pid, SetupReqIn)),
?_assertMetric(?S1GW_CTR_S1AP_PROXY_IN_PKT_ALL, 1),
@@ -166,15 +166,15 @@
test_e_rab_setup_rsp_during_release(#{handler := Pid}) ->
%% [eNB <- MME] E-RAB SETUP REQUEST
- SetupReqIn = e_rab_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
- SetupReqExp = e_rab_setup_req_pdu(?ADDR_A2U, ?TEID_A2U),
+ SetupReqIn = s1ap_samples:e_rab_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
+ SetupReqExp = s1ap_samples:e_rab_setup_req_pdu(?ADDR_A2U, ?TEID_A2U),
%% [eNB -> MME] E-RAB SETUP RESPONSE
- SetupRspIn = e_rab_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
- SetupRspExp = e_rab_setup_rsp_pdu(?ADDR_C2U, ?TEID_C2U),
+ SetupRspIn = s1ap_samples:e_rab_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
+ SetupRspExp = s1ap_samples:e_rab_setup_rsp_pdu(?ADDR_C2U, ?TEID_C2U),
%% [eNB <- MME] E-RAB RELEASE COMMAND
- ReleaseCmd = e_rab_release_cmd_pdu(),
+ ReleaseCmd = s1ap_samples:e_rab_release_cmd_pdu(),
%% [eNB -> MME] E-RAB RELEASE RESPONSE
- ReleaseRsp = e_rab_release_rsp_pdu(),
+ ReleaseRsp = s1ap_samples:e_rab_release_rsp_pdu(),
[%% MME orders allocation of an E-RAB
?_assertEqual({forward, SetupReqExp}, s1ap_proxy:process_pdu(Pid, SetupReqIn)),
@@ -199,12 +199,12 @@
test_e_rab_setup_dup(#{handler := Pid}) ->
%% [eNB <- MME] E-RAB SETUP REQUEST
- SetupReqIn = e_rab_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
+ SetupReqIn = s1ap_samples:e_rab_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
%% [eNB -> MME] E-RAB SETUP RESPONSE
- SetupRspIn = e_rab_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
+ SetupRspIn = s1ap_samples:e_rab_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
%% eNB <- [S1GW <- MME] E-RAB SETUP REQUEST (duplicate)
%% eNB -- [S1GW -> MME] E-RAB SETUP RESPONSE (failure)
- SetupRspExp = e_rab_setup_rsp_fail_pdu(),
+ SetupRspExp = s1ap_samples:e_rab_setup_rsp_fail_pdu(),
[?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, SetupReqIn)),
?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, SetupRspIn)),
@@ -216,13 +216,13 @@
test_e_rab_release_cmd(#{handler := Pid}) ->
%% [eNB <- MME] E-RAB SETUP REQUEST
- SetupReq = e_rab_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
+ SetupReq = s1ap_samples:e_rab_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
%% [eNB -> MME] E-RAB SETUP RESPONSE
- SetupRsp = e_rab_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
+ SetupRsp = s1ap_samples:e_rab_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
%% [eNB <- MME] E-RAB RELEASE COMMAND
- ReleaseCmd = e_rab_release_cmd_pdu(),
+ ReleaseCmd = s1ap_samples:e_rab_release_cmd_pdu(),
%% [eNB -> MME] E-RAB RELEASE RESPONSE
- ReleaseRsp = e_rab_release_rsp_pdu(),
+ ReleaseRsp = s1ap_samples:e_rab_release_rsp_pdu(),
[?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, SetupReq)),
?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, SetupRsp)),
@@ -240,11 +240,11 @@
test_e_rab_release_ind(#{handler := Pid}) ->
%% [eNB <- MME] E-RAB SETUP REQUEST
- SetupReq = e_rab_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
+ SetupReq = s1ap_samples:e_rab_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
%% [eNB -> MME] E-RAB SETUP RESPONSE
- SetupRsp = e_rab_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
+ SetupRsp = s1ap_samples:e_rab_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
%% [eNB -> MME] E-RAB RELEASE INDICATION
- ReleaseInd = e_rab_release_ind_pdu(),
+ ReleaseInd = s1ap_samples:e_rab_release_ind_pdu(),
[?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, SetupReq)),
?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, SetupRsp)),
@@ -258,18 +258,18 @@
test_e_rab_modify_req_rsp(#{handler := Pid}) ->
%% [eNB <- MME] E-RAB SETUP REQUEST
- SetupReq = e_rab_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
+ SetupReq = s1ap_samples:e_rab_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
%% [eNB -> MME] E-RAB SETUP RESPONSE
- SetupRsp = e_rab_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
+ SetupRsp = s1ap_samples:e_rab_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
%% eNB <- [S1GW <- MME] E-RAB MODIFY REQUEST (new F-TEID)
- ModifyReqIn = e_rab_modify_req_pdu(?ADDR_U2CM, ?TEID_U2CM),
+ ModifyReqIn = s1ap_samples:e_rab_modify_req_pdu(?ADDR_U2CM, ?TEID_U2CM),
%% [eNB <- S1GW] <- MME E-RAB MODIFY REQUEST
%% for the eNB F-TEID remains unchanged
- ModifyReqExp = e_rab_modify_req_pdu(?ADDR_A2U, ?TEID_A2U),
+ ModifyReqExp = s1ap_samples:e_rab_modify_req_pdu(?ADDR_A2U, ?TEID_A2U),
%% [eNB -> MME] E-RAB MODIFY RESPONSE
- ModifyRsp = e_rab_modify_rsp_pdu(),
+ ModifyRsp = s1ap_samples:e_rab_modify_rsp_pdu(),
%% [eNB -> MME] E-RAB RELEASE INDICATION
- ReleaseInd = e_rab_release_ind_pdu(),
+ ReleaseInd = s1ap_samples:e_rab_release_ind_pdu(),
[?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, SetupReq)),
?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, SetupRsp)),
@@ -287,15 +287,15 @@
test_e_rab_modify_req_rsp_fail(#{handler := Pid}) ->
%% [eNB <- MME] E-RAB SETUP REQUEST
- SetupReq = e_rab_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
+ SetupReq = s1ap_samples:e_rab_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
%% [eNB -> MME] E-RAB SETUP RESPONSE
- SetupRsp = e_rab_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
+ SetupRsp = s1ap_samples:e_rab_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
%% [eNB <- MME] E-RAB MODIFY REQUEST (new F-TEID)
- ModifyReq = e_rab_modify_req_pdu(?ADDR_U2CM, ?TEID_U2CM),
+ ModifyReq = s1ap_samples:e_rab_modify_req_pdu(?ADDR_U2CM, ?TEID_U2CM),
%% [eNB -> MME] E-RAB MODIFY RESPONSE (failure)
- ModifyRsp = e_rab_modify_rsp_fail_pdu(),
+ ModifyRsp = s1ap_samples:e_rab_modify_rsp_fail_pdu(),
%% [eNB -> MME] E-RAB RELEASE INDICATION
- ReleaseInd = e_rab_release_ind_pdu(),
+ ReleaseInd = s1ap_samples:e_rab_release_ind_pdu(),
[?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, SetupReq)),
?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, SetupRsp)),
@@ -313,18 +313,18 @@
test_e_rab_modify_ind_cnf_modified(#{handler := Pid}) ->
%% [eNB <- MME] E-RAB SETUP REQUEST
- SetupReq = e_rab_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
+ SetupReq = s1ap_samples:e_rab_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
%% [eNB -> MME] E-RAB SETUP RESPONSE
- SetupRsp = e_rab_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
+ SetupRsp = s1ap_samples:e_rab_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
%% [eNB -> S1GW] -> MME E-RAB MODIFICATION INDICATION (new F-TEID)
- ModifyIndIn = e_rab_modify_ind_pdu(?ADDR_U2AM, ?TEID_U2AM),
+ ModifyIndIn = s1ap_samples:e_rab_modify_ind_pdu(?ADDR_U2AM, ?TEID_U2AM),
%% eNB -> [S1GW -> MME] E-RAB MODIFICATION INDICATION
%% for the MME F-TEID remains unchanged
- ModifyIndExp = e_rab_modify_ind_pdu(?ADDR_C2U, ?TEID_C2U),
+ ModifyIndExp = s1ap_samples:e_rab_modify_ind_pdu(?ADDR_C2U, ?TEID_C2U),
%% [eNB <- MME] E-RAB MODIFICATION CONFIRMATION
- ModifyCnf = e_rab_modify_cnf_pdu(modified),
+ ModifyCnf = s1ap_samples:e_rab_modify_cnf_pdu(modified),
%% [eNB -> MME] E-RAB RELEASE INDICATION
- ReleaseInd = e_rab_release_ind_pdu(),
+ ReleaseInd = s1ap_samples:e_rab_release_ind_pdu(),
[?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, SetupReq)),
?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, SetupRsp)),
@@ -342,18 +342,18 @@
test_e_rab_modify_ind_cnf_not_modified(#{handler := Pid}) ->
%% [eNB <- MME] E-RAB SETUP REQUEST
- SetupReq = e_rab_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
+ SetupReq = s1ap_samples:e_rab_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
%% [eNB -> MME] E-RAB SETUP RESPONSE
- SetupRsp = e_rab_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
+ SetupRsp = s1ap_samples:e_rab_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
%% [eNB -> S1GW] -> MME E-RAB MODIFICATION INDICATION (new F-TEID)
- ModifyIndIn = e_rab_modify_ind_pdu(?ADDR_U2AM, ?TEID_U2AM),
+ ModifyIndIn = s1ap_samples:e_rab_modify_ind_pdu(?ADDR_U2AM, ?TEID_U2AM),
%% eNB -> [S1GW -> MME] E-RAB MODIFICATION INDICATION
%% for the MME F-TEID remains unchanged
- ModifyIndExp = e_rab_modify_ind_pdu(?ADDR_C2U, ?TEID_C2U),
+ ModifyIndExp = s1ap_samples:e_rab_modify_ind_pdu(?ADDR_C2U, ?TEID_C2U),
%% [eNB <- MME] E-RAB MODIFICATION CONFIRMATION
- ModifyCnf = e_rab_modify_cnf_pdu(not_modified),
+ ModifyCnf = s1ap_samples:e_rab_modify_cnf_pdu(not_modified),
%% [eNB -> MME] E-RAB RELEASE INDICATION
- ReleaseInd = e_rab_release_ind_pdu(),
+ ReleaseInd = s1ap_samples:e_rab_release_ind_pdu(),
[?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, SetupReq)),
?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, SetupRsp)),
@@ -371,16 +371,16 @@
test_e_rab_modify_ind_cnf_release(#{handler := Pid}) ->
%% [eNB <- MME] E-RAB SETUP REQUEST
- SetupReq = e_rab_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
+ SetupReq = s1ap_samples:e_rab_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
%% [eNB -> MME] E-RAB SETUP RESPONSE
- SetupRsp = e_rab_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
+ SetupRsp = s1ap_samples:e_rab_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
%% [eNB -> S1GW] -> MME E-RAB MODIFICATION INDICATION (new F-TEID)
- ModifyIndIn = e_rab_modify_ind_pdu(?ADDR_U2AM, ?TEID_U2AM),
+ ModifyIndIn = s1ap_samples:e_rab_modify_ind_pdu(?ADDR_U2AM, ?TEID_U2AM),
%% eNB -> [S1GW -> MME] E-RAB MODIFICATION INDICATION
%% for the MME F-TEID remains unchanged
- ModifyIndExp = e_rab_modify_ind_pdu(?ADDR_C2U, ?TEID_C2U),
+ ModifyIndExp = s1ap_samples:e_rab_modify_ind_pdu(?ADDR_C2U, ?TEID_C2U),
%% [eNB <- MME] E-RAB MODIFICATION CONFIRMATION
- ModifyCnf = e_rab_modify_cnf_pdu(release),
+ ModifyCnf = s1ap_samples:e_rab_modify_cnf_pdu(release),
[?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, SetupReq)),
?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, SetupRsp)),
@@ -397,14 +397,14 @@
test_initial_context_setup(#{handler := Pid}) ->
%% [eNB <- MME] INITIAL CONTEXT SETUP REQUEST
- InitCtxSetupReqIn = initial_context_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
- InitCtxSetupReqExp = initial_context_setup_req_pdu(?ADDR_A2U, ?TEID_A2U),
+ InitCtxSetupReqIn = s1ap_samples:initial_context_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
+ InitCtxSetupReqExp = s1ap_samples:initial_context_setup_req_pdu(?ADDR_A2U, ?TEID_A2U),
%% [eNB -> MME] INITIAL CONTEXT SETUP RESPONSE
- InitCtxSetupRspIn = initial_context_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
- InitCtxSetupRspExp = initial_context_setup_rsp_pdu(?ADDR_C2U, ?TEID_C2U),
+ InitCtxSetupRspIn = s1ap_samples:initial_context_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
+ InitCtxSetupRspExp = s1ap_samples:initial_context_setup_rsp_pdu(?ADDR_C2U, ?TEID_C2U),
- [?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, s1_setup_req_pdu())),
- ?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, s1_setup_rsp_pdu())),
+ [?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, s1ap_samples:s1_setup_req_pdu())),
+ ?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, s1ap_samples:s1_setup_rsp_pdu())),
?_assertEqual({forward, InitCtxSetupReqExp}, s1ap_proxy:process_pdu(Pid, InitCtxSetupReqIn)),
?_assertEqual({forward, InitCtxSetupRspExp}, s1ap_proxy:process_pdu(Pid, InitCtxSetupRspIn)),
%% global counters
@@ -427,9 +427,9 @@
test_initial_context_setup_dup(#{handler := Pid}) ->
%% [eNB <- MME] INITIAL CONTEXT SETUP REQUEST
- InitCtxSetupReqIn = initial_context_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
+ InitCtxSetupReqIn = s1ap_samples:initial_context_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
%% [eNB -> MME] INITIAL CONTEXT SETUP RESPONSE
- InitCtxSetupRspIn = initial_context_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
+ InitCtxSetupRspIn = s1ap_samples:initial_context_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
[?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, InitCtxSetupReqIn)),
?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, InitCtxSetupRspIn)),
@@ -441,17 +441,17 @@
test_initial_context_setup_rsp_during_release(#{handler := Pid}) ->
%% [eNB <- MME] INITIAL CONTEXT SETUP REQUEST
- InitCtxSetupReq = initial_context_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
- InitCtxSetupReqExp = initial_context_setup_req_pdu(?ADDR_A2U, ?TEID_A2U),
+ InitCtxSetupReq = s1ap_samples:initial_context_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
+ InitCtxSetupReqExp = s1ap_samples:initial_context_setup_req_pdu(?ADDR_A2U, ?TEID_A2U),
%% [eNB -> MME] INITIAL CONTEXT SETUP RESPONSE
- InitCtxSetupRsp = initial_context_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
- InitCtxSetupRspExp = initial_context_setup_rsp_pdu(?ADDR_C2U, ?TEID_C2U),
+ InitCtxSetupRsp = s1ap_samples:initial_context_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
+ InitCtxSetupRspExp = s1ap_samples:initial_context_setup_rsp_pdu(?ADDR_C2U, ?TEID_C2U),
%% [eNB -> MME] UE CONTEXT RELEASE REQUEST
- UeCtxReleaseReq = ue_ctx_release_req_pdu(),
+ UeCtxReleaseReq = s1ap_samples:ue_ctx_release_req_pdu(),
%% [eNB <- MME] UE CONTEXT RELEASE COMMAND
- UeCtxReleaseCmd = ue_ctx_release_cmd_pdu(),
+ UeCtxReleaseCmd = s1ap_samples:ue_ctx_release_cmd_pdu(),
%% [eNB -> MME] UE CONTEXT RELEASE COMPLETE
- UeCtxReleaseCompl = ue_ctx_release_compl_pdu(),
+ UeCtxReleaseCompl = s1ap_samples:ue_ctx_release_compl_pdu(),
[%% MME orders creation of the UE context
?_assertMatch({forward, InitCtxSetupReqExp}, s1ap_proxy:process_pdu(Pid, InitCtxSetupReq)),
@@ -479,9 +479,9 @@
test_handover_preparation(#{handler := Pid}) ->
%% [eNB -> MME] HANDOVER REQUIRED
- HandoverRqd = handover_required(),
+ HandoverRqd = s1ap_samples:handover_required_pdu(),
%% [MME -> eNB] HANDOVER COMMAND
- HandoverCmd = handover_command(),
+ HandoverCmd = s1ap_samples:handover_command_pdu(),
[?_assertMatch({forward, HandoverRqd}, s1ap_proxy:process_pdu(Pid, HandoverRqd)),
?_assertMatch({forward, HandoverCmd}, s1ap_proxy:process_pdu(Pid, HandoverCmd)),
@@ -494,14 +494,14 @@
test_handover_res_alloc(#{handler := Pid}) ->
%% [MME -> eNB] HANDOVER REQUEST
- HandoverReqIn = handover_request(?ADDR_U2C, ?TEID_U2C),
- HandoverReqExp = handover_request(?ADDR_A2U, ?TEID_A2U),
+ HandoverReqIn = s1ap_samples:handover_request_pdu(?ADDR_U2C, ?TEID_U2C),
+ HandoverReqExp = s1ap_samples:handover_request_pdu(?ADDR_A2U, ?TEID_A2U),
%% [eNB -> MME] HANDOVER REQUEST ACKNOWLEDGE
- HandoverAckIn = handover_request_ack(?ADDR_U2A, ?TEID_U2A),
- HandoverAckExp = handover_request_ack(?ADDR_C2U, ?TEID_C2U),
+ HandoverAckIn = s1ap_samples:handover_request_ack_pdu(?ADDR_U2A, ?TEID_U2A),
+ HandoverAckExp = s1ap_samples:handover_request_ack_pdu(?ADDR_C2U, ?TEID_C2U),
- [?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, s1_setup_req_pdu())),
- ?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, s1_setup_rsp_pdu())),
+ [?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, s1ap_samples:s1_setup_req_pdu())),
+ ?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, s1ap_samples:s1_setup_rsp_pdu())),
?_assertEqual({forward, HandoverReqExp}, s1ap_proxy:process_pdu(Pid, HandoverReqIn)),
?_assertEqual({forward, HandoverAckExp}, s1ap_proxy:process_pdu(Pid, HandoverAckIn)),
%% global counters
@@ -523,11 +523,11 @@
test_ue_ctx_release_req(#{handler := Pid}) ->
%% [eNB <- MME] INITIAL CONTEXT SETUP REQUEST
- InitCtxSetupReq = initial_context_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
+ InitCtxSetupReq = s1ap_samples:initial_context_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
%% [eNB -> MME] INITIAL CONTEXT SETUP RESPONSE
- InitCtxSetupRsp = initial_context_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
+ InitCtxSetupRsp = s1ap_samples:initial_context_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
%% [eNB -> MME] UE CONTEXT RELEASE REQUEST
- UeCtxReleaseReq = ue_ctx_release_req_pdu(),
+ UeCtxReleaseReq = s1ap_samples:ue_ctx_release_req_pdu(),
[?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, InitCtxSetupReq)),
?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, InitCtxSetupRsp)),
@@ -544,13 +544,13 @@
test_ue_ctx_release_cmd(#{handler := Pid}) ->
%% [eNB <- MME] INITIAL CONTEXT SETUP REQUEST
- InitCtxSetupReq = initial_context_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
+ InitCtxSetupReq = s1ap_samples:initial_context_setup_req_pdu(?ADDR_U2C, ?TEID_U2C),
%% [eNB -> MME] INITIAL CONTEXT SETUP RESPONSE
- InitCtxSetupRsp = initial_context_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
+ InitCtxSetupRsp = s1ap_samples:initial_context_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
%% [eNB <- MME] UE CONTEXT RELEASE COMMAND
- UeCtxReleaseCmd = ue_ctx_release_cmd_pdu(),
+ UeCtxReleaseCmd = s1ap_samples:ue_ctx_release_cmd_pdu(),
%% [eNB -> MME] UE CONTEXT RELEASE COMPLETE
- UeCtxReleaseCompl = ue_ctx_release_compl_pdu(),
+ UeCtxReleaseCompl = s1ap_samples:ue_ctx_release_compl_pdu(),
[?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, InitCtxSetupReq)),
?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, InitCtxSetupRsp)),
@@ -574,10 +574,10 @@
test_drop_proc_error(#{handler := Pid}) ->
%% [eNB -> MME] INITIAL CONTEXT SETUP RESPONSE
- InitCtxSetupRsp = initial_context_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
+ InitCtxSetupRsp = s1ap_samples:initial_context_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A),
- [?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, s1_setup_req_pdu())),
- ?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, s1_setup_rsp_pdu())),
+ [?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, s1ap_samples:s1_setup_req_pdu())),
+ ?_assertMatch({forward, _}, s1ap_proxy:process_pdu(Pid, s1ap_samples:s1_setup_rsp_pdu())),
%% INITIAL CONTEXT SETUP RESPONSE without prior request
%% "Failed to process INITIAL CONTEXT SETUP RESPONSE: erab_not_registered"
?_assertMatch({drop, _}, s1ap_proxy:process_pdu(Pid, InitCtxSetupRsp)),
@@ -591,313 +591,4 @@
?_assertMetricENB(?S1GW_CTR_S1AP_PROXY_IN_PKT_DROP_ALL, 1)].
-%% ------------------------------------------------------------------
-%% S1AP PDU templates
-%% ------------------------------------------------------------------
-
-%% S1 SETUP REQUEST
-s1_setup_req_pdu() ->
- << 16#00, 16#11, 16#00, 16#1a, 16#00, 16#00, 16#02, 16#00,
- 16#3b, 16#40, 16#08, 16#00, 16#00, 16#f1, 16#10, 16#00,
- 16#00, 16#00, 16#00, 16#00, 16#40, 16#00, 16#07, 16#00,
- 16#0c, 16#0e, 16#40, 16#00, 16#f1, 16#10
- >>.
-
-
-%% S1 SETUP RESPONSE
-s1_setup_rsp_pdu() ->
- << 16#20, 16#11, 16#00, 16#29, 16#00, 16#00, 16#03, 16#00,
- 16#3d, 16#40, 16#0e, 16#05, 16#80, 16#6f, 16#70, 16#65,
- 16#6e, 16#35, 16#67, 16#73, 16#2d, 16#6d, 16#6d, 16#65,
- 16#30, 16#00, 16#69, 16#00, 16#0b, 16#00, 16#00, 16#00,
- 16#f1, 16#10, 16#00, 16#00, 16#00, 16#02, 16#00, 16#01,
- 16#00, 16#57, 16#40, 16#01, 16#ff
- >>.
-
-
-%% [eNB <- MME] E-RAB SETUP REQUEST
-e_rab_setup_req_pdu(TLA, TEID) when is_binary(TLA),
- is_integer(TEID) ->
- << 16#00, 16#05, 16#00, 16#80, 16#9b, 16#00, 16#00, 16#03,
- 16#00, 16#00, 16#00, 16#02, 16#00, 16#07, 16#00, 16#08,
- 16#00, 16#02, 16#00, 16#09, 16#00, 16#10, 16#00, 16#80,
- 16#87, 16#00, 16#00, 16#11, 16#00, 16#80, 16#81, 16#0c,
- 16#00, 16#05, 16#04, 16#0f, 16#80,
- TLA/bytes, %% transportLayerAddress (IPv4)
- TEID:32/big, %% GTP-TEID
- 16#72, 16#27, 16#c8,
- 16#1a, 16#bc, 16#ec, 16#11, 16#62, 16#54, 16#c1, 16#01,
- 16#05, 16#04, 16#03, 16#69, 16#6d, 16#73, 16#05, 16#01,
- 16#c0, 16#a8, 16#65, 16#02, 16#5e, 16#02, 16#b3, 16#8c,
- 16#58, 16#32, 16#27, 16#54, 16#80, 16#80, 16#21, 16#10,
- 16#02, 16#00, 16#00, 16#10, 16#81, 16#06, 16#08, 16#08,
- 16#08, 16#08, 16#83, 16#06, 16#08, 16#08, 16#04, 16#04,
- 16#00, 16#0d, 16#04, 16#08, 16#08, 16#08, 16#08, 16#00,
- 16#0d, 16#04, 16#08, 16#08, 16#04, 16#04, 16#00, 16#03,
- 16#10, 16#20, 16#01, 16#48, 16#60, 16#48, 16#60, 16#00,
- 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#88,
- 16#88, 16#00, 16#03, 16#10, 16#20, 16#01, 16#48, 16#60,
- 16#48, 16#60, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00,
- 16#00, 16#00, 16#88, 16#44, 16#00, 16#0c, 16#04, 16#ac,
- 16#16, 16#00, 16#15, 16#00, 16#10, 16#02, 16#05, 16#78
- >>.
-
-
-%% [eNB -> MME] E-RAB SETUP RESPONSE
-e_rab_setup_rsp_pdu(TLA, TEID) when is_binary(TLA),
- is_integer(TEID) ->
- << 16#20, 16#05, 16#00, 16#22, 16#00, 16#00, 16#03, 16#00,
- 16#00, 16#40, 16#02, 16#00, 16#07, 16#00, 16#08, 16#40,
- 16#02, 16#00, 16#09, 16#00, 16#1c, 16#40, 16#0f, 16#00,
- 16#00, 16#27, 16#40, 16#0a, 16#0c, 16#1f,
- TLA/bytes, %% transportLayerAddress (IPv4)
- TEID:32/big %% GTP-TEID
- >>.
-
-
-%% [S1GW -> MME] E-RAB SETUP RESPONSE (failure)
-%% Transport-cause: transport-resource-unavailable
-e_rab_setup_rsp_fail_pdu() ->
- << 16#20, 16#05, 16#00, 16#1a, 16#00, 16#00, 16#03, 16#00,
- 16#00, 16#40, 16#02, 16#00, 16#07, 16#00, 16#08, 16#40,
- 16#02, 16#00, 16#09, 16#00, 16#1d, 16#40, 16#07, 16#00,
- 16#00, 16#23, 16#40, 16#02, 16#0c, 16#20
- >>.
-
-
-%% [eNB <- MME] E-RAB RELEASE COMMAND
-%% TODO: make E-RAB IDs configurable
-e_rab_release_cmd_pdu() ->
- << 16#00, 16#07, 16#00, 16#1a, 16#00, 16#00, 16#03, 16#00,
- 16#00, 16#00, 16#02, 16#00, 16#07, 16#00, 16#08, 16#00,
- 16#02, 16#00, 16#09, 16#00, 16#21, 16#40, 16#07, 16#00,
- 16#00, 16#23, 16#40, 16#02, 16#0c, 16#40
- >>.
-
-
-%% [eNB -> MME] E-RAB RELEASE RESPONSE
-%% TODO: make E-RAB IDs configurable
-e_rab_release_rsp_pdu() ->
- << 16#20, 16#07, 16#00, 16#19, 16#00, 16#00, 16#03, 16#00,
- 16#00, 16#00, 16#02, 16#00, 16#07, 16#00, 16#08, 16#00,
- 16#02, 16#00, 16#09, 16#00, 16#45, 16#40, 16#06, 16#00,
- 16#00, 16#0f, 16#40, 16#01, 16#0c
- >>.
-
-
-%% [eNB -> MME] E-RAB RELEASE INDICATION
-%% TODO: make E-RAB IDs configurable
-e_rab_release_ind_pdu() ->
- << 16#00, 16#08, 16#00, 16#1a, 16#00, 16#00, 16#03, 16#00,
- 16#00, 16#00, 16#02, 16#00, 16#07, 16#00, 16#08, 16#00,
- 16#02, 16#00, 16#09, 16#00, 16#6e, 16#40, 16#07, 16#00,
- 16#00, 16#23, 16#40, 16#02, 16#0c, 16#40
- >>.
-
-
-%% [eNB <- MME] E-RAB MODIFY REQUEST
-e_rab_modify_req_pdu(TLA, TEID) when is_binary(TLA),
- is_integer(TEID) ->
- << 16#00, 16#06, 16#00, 16#2d, 16#00, 16#00, 16#03, 16#00,
- 16#00, 16#00, 16#02, 16#00, 16#07, 16#00, 16#08, 16#00,
- 16#02, 16#00, 16#09, 16#00, 16#1e, 16#00, 16#1a, 16#00,
- 16#00, 16#24, 16#00, 16#15, 16#4c, 16#00, 16#05, 16#04,
- 16#00, 16#00, 16#00, 16#00, 16#b9, 16#00, 16#0a, 16#07,
- 16#c0,
- TLA/bytes, %% transportLayerAddress (IPv4)
- TEID:32/big %% GTP-TEID
- >>.
-
-
-%% [eNB -> MME] E-RAB MODIFY RESPONSE (success)
-e_rab_modify_rsp_pdu() ->
- << 16#20, 16#06, 16#00, 16#19, 16#00, 16#00, 16#03, 16#00,
- 16#00, 16#40, 16#02, 16#00, 16#07, 16#00, 16#08, 16#40,
- 16#02, 16#00, 16#09, 16#00, 16#1f, 16#40, 16#06, 16#00,
- 16#00, 16#25, 16#40, 16#01, 16#0c
- >>.
-
-
-%% [eNB -> MME] E-RAB MODIFY RESPONSE (failure)
-e_rab_modify_rsp_fail_pdu() ->
- << 16#20, 16#06, 16#00, 16#1a, 16#00, 16#00, 16#03, 16#00,
- 16#00, 16#40, 16#02, 16#00, 16#07, 16#00, 16#08, 16#40,
- 16#02, 16#00, 16#09, 16#00, 16#20, 16#40, 16#07, 16#00,
- 16#00, 16#23, 16#40, 16#02, 16#0c, 16#40
- >>.
-
-
-%% [eNB -> MME] E-RAB MODIFICATION INDICATION
-e_rab_modify_ind_pdu(TLA, TEID) when is_binary(TLA),
- is_integer(TEID) ->
- << 16#00, 16#32, 16#00, 16#22, 16#00, 16#00, 16#03, 16#00,
- 16#00, 16#00, 16#02, 16#00, 16#07, 16#00, 16#08, 16#00,
- 16#02, 16#00, 16#09, 16#00, 16#c7, 16#00, 16#0f, 16#00,
- 16#00, 16#c8, 16#00, 16#0a, 16#0c, 16#1f,
- TLA/bytes, %% transportLayerAddress (IPv4)
- TEID:32/big %% GTP-TEID
- >>.
-
-
-%% [eNB -> MME] E-RAB MODIFICATION CONFIRMATION
-e_rab_modify_cnf_pdu(Res) ->
- IEs = case Res of
- modified ->
- << 16#00, 16#cb, 16#40, 16#06, 16#00,
- 16#00, 16#cc, 16#40, 16#01, 16#0c >>;
- not_modified ->
- %% cause: transport: transport-resource-unavailable (0)
- << 16#00, 16#cd, 16#40, 16#07, 16#00,
- 16#00, 16#23, 16#40, 16#02, 16#0c, 16#20 >>;
- release ->
- %% cause: transport: transport-resource-unavailable (0)
- << 16#00, 16#d2, 16#40, 16#07, 16#00,
- 16#00, 16#23, 16#40, 16#02, 16#0c, 16#20 >>
- end,
- << 16#20, 16#32, 16#00, (15 + byte_size(IEs)),
- 16#00, 16#00, 16#03, 16#00, 16#00, 16#40, 16#02, 16#00,
- 16#07, 16#00, 16#08, 16#40, 16#02, 16#00, 16#09,
- IEs/bytes
- >>.
-
-
-%% [eNB <- MME] INITIAL CONTEXT SETUP REQUEST
-initial_context_setup_req_pdu(TLA, TEID) when is_binary(TLA),
- is_integer(TEID) ->
- << 16#00, 16#09, 16#00, 16#81, 16#10, 16#00, 16#00, 16#07,
- 16#00, 16#00, 16#00, 16#02, 16#00, 16#01, 16#00, 16#08,
- 16#00, 16#02, 16#00, 16#01, 16#00, 16#42, 16#00, 16#0a,
- 16#18, 16#3b, 16#9a, 16#ca, 16#00, 16#60, 16#3b, 16#9a,
- 16#ca, 16#00, 16#00, 16#18, 16#00, 16#80, 16#b5, 16#00,
- 16#00, 16#34, 16#00, 16#80, 16#af, 16#45, 16#00, 16#09,
- 16#20, 16#0f, 16#80,
- TLA/bytes, %% transportLayerAddress (IPv4)
- TEID:32/big, %% GTP-TEID
- 16#80, 16#9f, 16#27, 16#bd, 16#de,
- 16#61, 16#4e, 16#02, 16#07, 16#42, 16#02, 16#29, 16#06,
- 16#40, 16#32, 16#f8, 16#10, 16#00, 16#01, 16#00, 16#6e,
- 16#52, 16#05, 16#c1, 16#01, 16#09, 16#09, 16#08, 16#69,
- 16#6e, 16#74, 16#65, 16#72, 16#6e, 16#65, 16#74, 16#05,
- 16#01, 16#c0, 16#a8, 16#64, 16#02, 16#5e, 16#06, 16#fe,
- 16#fe, 16#fa, 16#fa, 16#02, 16#02, 16#58, 16#32, 16#27,
- 16#4d, 16#80, 16#80, 16#21, 16#10, 16#02, 16#00, 16#00,
- 16#10, 16#81, 16#06, 16#08, 16#08, 16#08, 16#08, 16#83,
- 16#06, 16#08, 16#08, 16#04, 16#04, 16#00, 16#0d, 16#04,
- 16#08, 16#08, 16#08, 16#08, 16#00, 16#0d, 16#04, 16#08,
- 16#08, 16#04, 16#04, 16#00, 16#03, 16#10, 16#20, 16#01,
- 16#48, 16#60, 16#48, 16#60, 16#00, 16#00, 16#00, 16#00,
- 16#00, 16#00, 16#00, 16#00, 16#88, 16#88, 16#00, 16#03,
- 16#10, 16#20, 16#01, 16#48, 16#60, 16#48, 16#60, 16#00,
- 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#88,
- 16#44, 16#00, 16#10, 16#02, 16#05, 16#aa, 16#50, 16#0b,
- 16#f6, 16#32, 16#f8, 16#10, 16#00, 16#02, 16#01, 16#c0,
- 16#00, 16#02, 16#86, 16#13, 16#32, 16#f8, 16#10, 16#00,
- 16#01, 16#23, 16#05, 16#f4, 16#04, 16#94, 16#25, 16#f8,
- 16#64, 16#02, 16#01, 16#08, 16#00, 16#6b, 16#00, 16#05,
- 16#1c, 16#00, 16#0e, 16#00, 16#00, 16#00, 16#49, 16#00,
- 16#20, 16#57, 16#5d, 16#d3, 16#66, 16#69, 16#73, 16#4c,
- 16#8c, 16#48, 16#42, 16#76, 16#5f, 16#fe, 16#f9, 16#bd,
- 16#d5, 16#89, 16#08, 16#ae, 16#f6, 16#f4, 16#88, 16#62,
- 16#22, 16#d7, 16#80, 16#fb, 16#36, 16#33, 16#d9, 16#9e,
- 16#9f, 16#00, 16#c0, 16#40, 16#08, 16#35, 16#87, 16#61,
- 16#10, 16#03, 16#ff, 16#ff, 16#74
- >>.
-
-
-%% [eNB -> MME] INITIAL CONTEXT SETUP RESPONSE
-initial_context_setup_rsp_pdu(TLA, TEID) when is_binary(TLA),
- is_integer(TEID) ->
- << 16#20, 16#09, 16#00, 16#22, 16#00, 16#00, 16#03, 16#00,
- 16#00, 16#40, 16#02, 16#00, 16#01, 16#00, 16#08, 16#40,
- 16#02, 16#00, 16#01, 16#00, 16#33, 16#40, 16#0f, 16#00,
- 16#00, 16#32, 16#40, 16#0a, 16#0a, 16#1f,
- TLA/bytes, %% transportLayerAddress (IPv4)
- TEID:32/big %% GTP-TEID
- >>.
-
-
-%% [eNB -> MME] UE CONTEXT RELEASE REQUEST
-ue_ctx_release_req_pdu() ->
- << 16#00, 16#12, 16#40, 16#14, 16#00, 16#00, 16#03, 16#00,
- 16#00, 16#00, 16#02, 16#00, 16#01, 16#00, 16#08, 16#00,
- 16#02, 16#00, 16#01, 16#00, 16#02, 16#40, 16#01, 16#20
- >>.
-
-
-%% [eNB <- MME] UE CONTEXT RELEASE COMMAND
-ue_ctx_release_cmd_pdu() ->
- << 16#00, 16#17, 16#00, 16#10, 16#00, 16#00, 16#02, 16#00,
- 16#63, 16#00, 16#04, 16#00, 16#01, 16#00, 16#01, 16#00,
- 16#02, 16#40, 16#01, 16#20
- >>.
-
-
-%% [eNB -> MME] UE CONTEXT RELEASE COMPLETE
-ue_ctx_release_compl_pdu() ->
- << 16#20, 16#17, 16#00, 16#0f, 16#00, 16#00, 16#02, 16#00,
- 16#00, 16#40, 16#02, 16#00, 16#01, 16#00, 16#08, 16#40,
- 16#02, 16#00, 16#01
- >>.
-
-
-%% [eNB -> MME] HANDOVER REQUIRED
-handover_required() ->
- << 16#00, 16#00, 16#00, 16#35, 16#00, 16#00, 16#06, 16#00,
- 16#00, 16#00, 16#03, 16#40, 16#10, 16#92, 16#00, 16#08,
- 16#00, 16#02, 16#00, 16#00, 16#00, 16#01, 16#00, 16#01,
- 16#00, 16#00, 16#02, 16#40, 16#02, 16#04, 16#20, 16#00,
- 16#04, 16#00, 16#0e, 16#00, 16#62, 16#f2, 16#10, 16#40,
- 16#00, 16#00, 16#00, 16#00, 16#62, 16#f2, 16#10, 16#00,
- 16#07, 16#00, 16#68, 16#00, 16#04, 16#03, 16#12, 16#34,
- 16#56
- >>.
-
-
-%% [MME -> eNB] HANDOVER COMMAND
-handover_command() ->
- << 16#20, 16#00, 16#00, 16#28, 16#00, 16#00, 16#05, 16#00,
- 16#00, 16#00, 16#03, 16#40, 16#10, 16#92, 16#00, 16#08,
- 16#00, 16#02, 16#00, 16#00, 16#00, 16#01, 16#00, 16#01,
- 16#00, 16#00, 16#0c, 16#40, 16#07, 16#00, 16#00, 16#0e,
- 16#40, 16#02, 16#00, 16#00, 16#00, 16#7b, 16#00, 16#04,
- 16#03, 16#12, 16#34, 16#56
- >>.
-
-
-%% [MME -> eNB] HANDOVER REQUEST
-handover_request(TLA, TEID) when is_binary(TLA),
- is_integer(TEID) ->
- << 16#00, 16#01, 16#00, 16#6f, 16#00, 16#00, 16#08, 16#00,
- 16#00, 16#00, 16#03, 16#40, 16#10, 16#92, 16#00, 16#01,
- 16#00, 16#01, 16#00, 16#00, 16#02, 16#40, 16#02, 16#04,
- 16#20, 16#00, 16#42, 16#00, 16#0a, 16#18, 16#40, 16#00,
- 16#00, 16#00, 16#60, 16#40, 16#00, 16#00, 16#00, 16#00,
- 16#35, 16#00, 16#12, 16#00, 16#00, 16#1b, 16#00, 16#0d,
- 16#00, 16#1f,
- TLA/bytes, %% transportLayerAddress (IPv4)
- TEID:32/big, %% GTP-TEID
- 16#00, 16#05, 16#04, 16#00, 16#68, 16#00,
- 16#04, 16#03, 16#12, 16#34, 16#56, 16#00, 16#6b, 16#00,
- 16#05, 16#1c, 16#00, 16#0e, 16#00, 16#00, 16#00, 16#28,
- 16#00, 16#21, 16#28, 16#e0, 16#3f, 16#02, 16#35, 16#f1,
- 16#1e, 16#13, 16#68, 16#a8, 16#55, 16#04, 16#db, 16#fb,
- 16#8f, 16#65, 16#2b, 16#8c, 16#c7, 16#1c, 16#7c, 16#87,
- 16#cc, 16#f3, 16#f6, 16#4d, 16#4f, 16#84, 16#5e, 16#e1,
- 16#d2, 16#fc, 16#c6
- >>.
-
-
-%% [eNB -> MME] HANDOVER REQUEST ACKNOWLEDGE
-handover_request_ack(TLA, TEID) when is_binary(TLA),
- is_integer(TEID) ->
- << 16#20, 16#01, 16#00, 16#2c, 16#00, 16#00, 16#04, 16#00,
- 16#00, 16#40, 16#03, 16#40, 16#10, 16#92, 16#00, 16#08,
- 16#40, 16#02, 16#00, 16#00, 16#00, 16#12, 16#40, 16#10,
- 16#00, 16#00, 16#14, 16#40, 16#0b, 16#00, 16#01, 16#f0,
- TLA/bytes, %% transportLayerAddress (IPv4)
- TEID:32/big, %% GTP-TEID
- 16#00, 16#7b, 16#00, 16#04, 16#03, 16#12, 16#34, 16#56
- >>.
-
-
%% vim:set ts=4 sw=4 et:
diff --git a/test/s1ap_samples.erl b/test/s1ap_samples.erl
new file mode 100644
index 0000000..e3c3ac1
--- /dev/null
+++ b/test/s1ap_samples.erl
@@ -0,0 +1,336 @@
+-module(s1ap_samples).
+
+-export([s1_setup_req_pdu/0,
+ s1_setup_rsp_pdu/0,
+ e_rab_setup_req_pdu/2,
+ e_rab_setup_rsp_pdu/2,
+ e_rab_setup_rsp_fail_pdu/0,
+ e_rab_release_cmd_pdu/0,
+ e_rab_release_rsp_pdu/0,
+ e_rab_release_ind_pdu/0,
+ e_rab_modify_req_pdu/2,
+ e_rab_modify_rsp_pdu/0,
+ e_rab_modify_rsp_fail_pdu/0,
+ e_rab_modify_ind_pdu/2,
+ e_rab_modify_cnf_pdu/1,
+ initial_context_setup_req_pdu/2,
+ initial_context_setup_rsp_pdu/2,
+ ue_ctx_release_req_pdu/0,
+ ue_ctx_release_cmd_pdu/0,
+ ue_ctx_release_compl_pdu/0,
+ handover_required_pdu/0,
+ handover_command_pdu/0,
+ handover_request_pdu/2,
+ handover_request_ack_pdu/2]).
+
+
+%% ------------------------------------------------------------------
+%% S1AP PDU samples
+%% ------------------------------------------------------------------
+
+%% S1 SETUP REQUEST
+s1_setup_req_pdu() ->
+ << 16#00, 16#11, 16#00, 16#1a, 16#00, 16#00, 16#02, 16#00,
+ 16#3b, 16#40, 16#08, 16#00, 16#00, 16#f1, 16#10, 16#00,
+ 16#00, 16#00, 16#00, 16#00, 16#40, 16#00, 16#07, 16#00,
+ 16#0c, 16#0e, 16#40, 16#00, 16#f1, 16#10
+ >>.
+
+
+%% S1 SETUP RESPONSE
+s1_setup_rsp_pdu() ->
+ << 16#20, 16#11, 16#00, 16#29, 16#00, 16#00, 16#03, 16#00,
+ 16#3d, 16#40, 16#0e, 16#05, 16#80, 16#6f, 16#70, 16#65,
+ 16#6e, 16#35, 16#67, 16#73, 16#2d, 16#6d, 16#6d, 16#65,
+ 16#30, 16#00, 16#69, 16#00, 16#0b, 16#00, 16#00, 16#00,
+ 16#f1, 16#10, 16#00, 16#00, 16#00, 16#02, 16#00, 16#01,
+ 16#00, 16#57, 16#40, 16#01, 16#ff
+ >>.
+
+
+%% [eNB <- MME] E-RAB SETUP REQUEST
+e_rab_setup_req_pdu(TLA, TEID) when is_binary(TLA),
+ is_integer(TEID) ->
+ << 16#00, 16#05, 16#00, 16#80, 16#9b, 16#00, 16#00, 16#03,
+ 16#00, 16#00, 16#00, 16#02, 16#00, 16#07, 16#00, 16#08,
+ 16#00, 16#02, 16#00, 16#09, 16#00, 16#10, 16#00, 16#80,
+ 16#87, 16#00, 16#00, 16#11, 16#00, 16#80, 16#81, 16#0c,
+ 16#00, 16#05, 16#04, 16#0f, 16#80,
+ TLA/bytes, %% transportLayerAddress (IPv4)
+ TEID:32/big, %% GTP-TEID
+ 16#72, 16#27, 16#c8,
+ 16#1a, 16#bc, 16#ec, 16#11, 16#62, 16#54, 16#c1, 16#01,
+ 16#05, 16#04, 16#03, 16#69, 16#6d, 16#73, 16#05, 16#01,
+ 16#c0, 16#a8, 16#65, 16#02, 16#5e, 16#02, 16#b3, 16#8c,
+ 16#58, 16#32, 16#27, 16#54, 16#80, 16#80, 16#21, 16#10,
+ 16#02, 16#00, 16#00, 16#10, 16#81, 16#06, 16#08, 16#08,
+ 16#08, 16#08, 16#83, 16#06, 16#08, 16#08, 16#04, 16#04,
+ 16#00, 16#0d, 16#04, 16#08, 16#08, 16#08, 16#08, 16#00,
+ 16#0d, 16#04, 16#08, 16#08, 16#04, 16#04, 16#00, 16#03,
+ 16#10, 16#20, 16#01, 16#48, 16#60, 16#48, 16#60, 16#00,
+ 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#88,
+ 16#88, 16#00, 16#03, 16#10, 16#20, 16#01, 16#48, 16#60,
+ 16#48, 16#60, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00,
+ 16#00, 16#00, 16#88, 16#44, 16#00, 16#0c, 16#04, 16#ac,
+ 16#16, 16#00, 16#15, 16#00, 16#10, 16#02, 16#05, 16#78
+ >>.
+
+
+%% [eNB -> MME] E-RAB SETUP RESPONSE
+e_rab_setup_rsp_pdu(TLA, TEID) when is_binary(TLA),
+ is_integer(TEID) ->
+ << 16#20, 16#05, 16#00, 16#22, 16#00, 16#00, 16#03, 16#00,
+ 16#00, 16#40, 16#02, 16#00, 16#07, 16#00, 16#08, 16#40,
+ 16#02, 16#00, 16#09, 16#00, 16#1c, 16#40, 16#0f, 16#00,
+ 16#00, 16#27, 16#40, 16#0a, 16#0c, 16#1f,
+ TLA/bytes, %% transportLayerAddress (IPv4)
+ TEID:32/big %% GTP-TEID
+ >>.
+
+
+%% [S1GW -> MME] E-RAB SETUP RESPONSE (failure)
+%% Transport-cause: transport-resource-unavailable
+e_rab_setup_rsp_fail_pdu() ->
+ << 16#20, 16#05, 16#00, 16#1a, 16#00, 16#00, 16#03, 16#00,
+ 16#00, 16#40, 16#02, 16#00, 16#07, 16#00, 16#08, 16#40,
+ 16#02, 16#00, 16#09, 16#00, 16#1d, 16#40, 16#07, 16#00,
+ 16#00, 16#23, 16#40, 16#02, 16#0c, 16#20
+ >>.
+
+
+%% [eNB <- MME] E-RAB RELEASE COMMAND
+%% TODO: make E-RAB IDs configurable
+e_rab_release_cmd_pdu() ->
+ << 16#00, 16#07, 16#00, 16#1a, 16#00, 16#00, 16#03, 16#00,
+ 16#00, 16#00, 16#02, 16#00, 16#07, 16#00, 16#08, 16#00,
+ 16#02, 16#00, 16#09, 16#00, 16#21, 16#40, 16#07, 16#00,
+ 16#00, 16#23, 16#40, 16#02, 16#0c, 16#40
+ >>.
+
+
+%% [eNB -> MME] E-RAB RELEASE RESPONSE
+%% TODO: make E-RAB IDs configurable
+e_rab_release_rsp_pdu() ->
+ << 16#20, 16#07, 16#00, 16#19, 16#00, 16#00, 16#03, 16#00,
+ 16#00, 16#00, 16#02, 16#00, 16#07, 16#00, 16#08, 16#00,
+ 16#02, 16#00, 16#09, 16#00, 16#45, 16#40, 16#06, 16#00,
+ 16#00, 16#0f, 16#40, 16#01, 16#0c
+ >>.
+
+
+%% [eNB -> MME] E-RAB RELEASE INDICATION
+%% TODO: make E-RAB IDs configurable
+e_rab_release_ind_pdu() ->
+ << 16#00, 16#08, 16#00, 16#1a, 16#00, 16#00, 16#03, 16#00,
+ 16#00, 16#00, 16#02, 16#00, 16#07, 16#00, 16#08, 16#00,
+ 16#02, 16#00, 16#09, 16#00, 16#6e, 16#40, 16#07, 16#00,
+ 16#00, 16#23, 16#40, 16#02, 16#0c, 16#40
+ >>.
+
+
+%% [eNB <- MME] E-RAB MODIFY REQUEST
+e_rab_modify_req_pdu(TLA, TEID) when is_binary(TLA),
+ is_integer(TEID) ->
+ << 16#00, 16#06, 16#00, 16#2d, 16#00, 16#00, 16#03, 16#00,
+ 16#00, 16#00, 16#02, 16#00, 16#07, 16#00, 16#08, 16#00,
+ 16#02, 16#00, 16#09, 16#00, 16#1e, 16#00, 16#1a, 16#00,
+ 16#00, 16#24, 16#00, 16#15, 16#4c, 16#00, 16#05, 16#04,
+ 16#00, 16#00, 16#00, 16#00, 16#b9, 16#00, 16#0a, 16#07,
+ 16#c0,
+ TLA/bytes, %% transportLayerAddress (IPv4)
+ TEID:32/big %% GTP-TEID
+ >>.
+
+
+%% [eNB -> MME] E-RAB MODIFY RESPONSE (success)
+e_rab_modify_rsp_pdu() ->
+ << 16#20, 16#06, 16#00, 16#19, 16#00, 16#00, 16#03, 16#00,
+ 16#00, 16#40, 16#02, 16#00, 16#07, 16#00, 16#08, 16#40,
+ 16#02, 16#00, 16#09, 16#00, 16#1f, 16#40, 16#06, 16#00,
+ 16#00, 16#25, 16#40, 16#01, 16#0c
+ >>.
+
+
+%% [eNB -> MME] E-RAB MODIFY RESPONSE (failure)
+e_rab_modify_rsp_fail_pdu() ->
+ << 16#20, 16#06, 16#00, 16#1a, 16#00, 16#00, 16#03, 16#00,
+ 16#00, 16#40, 16#02, 16#00, 16#07, 16#00, 16#08, 16#40,
+ 16#02, 16#00, 16#09, 16#00, 16#20, 16#40, 16#07, 16#00,
+ 16#00, 16#23, 16#40, 16#02, 16#0c, 16#40
+ >>.
+
+
+%% [eNB -> MME] E-RAB MODIFICATION INDICATION
+e_rab_modify_ind_pdu(TLA, TEID) when is_binary(TLA),
+ is_integer(TEID) ->
+ << 16#00, 16#32, 16#00, 16#22, 16#00, 16#00, 16#03, 16#00,
+ 16#00, 16#00, 16#02, 16#00, 16#07, 16#00, 16#08, 16#00,
+ 16#02, 16#00, 16#09, 16#00, 16#c7, 16#00, 16#0f, 16#00,
+ 16#00, 16#c8, 16#00, 16#0a, 16#0c, 16#1f,
+ TLA/bytes, %% transportLayerAddress (IPv4)
+ TEID:32/big %% GTP-TEID
+ >>.
+
+
+%% [eNB -> MME] E-RAB MODIFICATION CONFIRMATION
+e_rab_modify_cnf_pdu(Res) ->
+ IEs = case Res of
+ modified ->
+ << 16#00, 16#cb, 16#40, 16#06, 16#00,
+ 16#00, 16#cc, 16#40, 16#01, 16#0c >>;
+ not_modified ->
+ %% cause: transport: transport-resource-unavailable (0)
+ << 16#00, 16#cd, 16#40, 16#07, 16#00,
+ 16#00, 16#23, 16#40, 16#02, 16#0c, 16#20 >>;
+ release ->
+ %% cause: transport: transport-resource-unavailable (0)
+ << 16#00, 16#d2, 16#40, 16#07, 16#00,
+ 16#00, 16#23, 16#40, 16#02, 16#0c, 16#20 >>
+ end,
+ << 16#20, 16#32, 16#00, (15 + byte_size(IEs)),
+ 16#00, 16#00, 16#03, 16#00, 16#00, 16#40, 16#02, 16#00,
+ 16#07, 16#00, 16#08, 16#40, 16#02, 16#00, 16#09,
+ IEs/bytes
+ >>.
+
+
+%% [eNB <- MME] INITIAL CONTEXT SETUP REQUEST
+initial_context_setup_req_pdu(TLA, TEID) when is_binary(TLA),
+ is_integer(TEID) ->
+ << 16#00, 16#09, 16#00, 16#81, 16#10, 16#00, 16#00, 16#07,
+ 16#00, 16#00, 16#00, 16#02, 16#00, 16#01, 16#00, 16#08,
+ 16#00, 16#02, 16#00, 16#01, 16#00, 16#42, 16#00, 16#0a,
+ 16#18, 16#3b, 16#9a, 16#ca, 16#00, 16#60, 16#3b, 16#9a,
+ 16#ca, 16#00, 16#00, 16#18, 16#00, 16#80, 16#b5, 16#00,
+ 16#00, 16#34, 16#00, 16#80, 16#af, 16#45, 16#00, 16#09,
+ 16#20, 16#0f, 16#80,
+ TLA/bytes, %% transportLayerAddress (IPv4)
+ TEID:32/big, %% GTP-TEID
+ 16#80, 16#9f, 16#27, 16#bd, 16#de,
+ 16#61, 16#4e, 16#02, 16#07, 16#42, 16#02, 16#29, 16#06,
+ 16#40, 16#32, 16#f8, 16#10, 16#00, 16#01, 16#00, 16#6e,
+ 16#52, 16#05, 16#c1, 16#01, 16#09, 16#09, 16#08, 16#69,
+ 16#6e, 16#74, 16#65, 16#72, 16#6e, 16#65, 16#74, 16#05,
+ 16#01, 16#c0, 16#a8, 16#64, 16#02, 16#5e, 16#06, 16#fe,
+ 16#fe, 16#fa, 16#fa, 16#02, 16#02, 16#58, 16#32, 16#27,
+ 16#4d, 16#80, 16#80, 16#21, 16#10, 16#02, 16#00, 16#00,
+ 16#10, 16#81, 16#06, 16#08, 16#08, 16#08, 16#08, 16#83,
+ 16#06, 16#08, 16#08, 16#04, 16#04, 16#00, 16#0d, 16#04,
+ 16#08, 16#08, 16#08, 16#08, 16#00, 16#0d, 16#04, 16#08,
+ 16#08, 16#04, 16#04, 16#00, 16#03, 16#10, 16#20, 16#01,
+ 16#48, 16#60, 16#48, 16#60, 16#00, 16#00, 16#00, 16#00,
+ 16#00, 16#00, 16#00, 16#00, 16#88, 16#88, 16#00, 16#03,
+ 16#10, 16#20, 16#01, 16#48, 16#60, 16#48, 16#60, 16#00,
+ 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#88,
+ 16#44, 16#00, 16#10, 16#02, 16#05, 16#aa, 16#50, 16#0b,
+ 16#f6, 16#32, 16#f8, 16#10, 16#00, 16#02, 16#01, 16#c0,
+ 16#00, 16#02, 16#86, 16#13, 16#32, 16#f8, 16#10, 16#00,
+ 16#01, 16#23, 16#05, 16#f4, 16#04, 16#94, 16#25, 16#f8,
+ 16#64, 16#02, 16#01, 16#08, 16#00, 16#6b, 16#00, 16#05,
+ 16#1c, 16#00, 16#0e, 16#00, 16#00, 16#00, 16#49, 16#00,
+ 16#20, 16#57, 16#5d, 16#d3, 16#66, 16#69, 16#73, 16#4c,
+ 16#8c, 16#48, 16#42, 16#76, 16#5f, 16#fe, 16#f9, 16#bd,
+ 16#d5, 16#89, 16#08, 16#ae, 16#f6, 16#f4, 16#88, 16#62,
+ 16#22, 16#d7, 16#80, 16#fb, 16#36, 16#33, 16#d9, 16#9e,
+ 16#9f, 16#00, 16#c0, 16#40, 16#08, 16#35, 16#87, 16#61,
+ 16#10, 16#03, 16#ff, 16#ff, 16#74
+ >>.
+
+
+%% [eNB -> MME] INITIAL CONTEXT SETUP RESPONSE
+initial_context_setup_rsp_pdu(TLA, TEID) when is_binary(TLA),
+ is_integer(TEID) ->
+ << 16#20, 16#09, 16#00, 16#22, 16#00, 16#00, 16#03, 16#00,
+ 16#00, 16#40, 16#02, 16#00, 16#01, 16#00, 16#08, 16#40,
+ 16#02, 16#00, 16#01, 16#00, 16#33, 16#40, 16#0f, 16#00,
+ 16#00, 16#32, 16#40, 16#0a, 16#0a, 16#1f,
+ TLA/bytes, %% transportLayerAddress (IPv4)
+ TEID:32/big %% GTP-TEID
+ >>.
+
+
+%% [eNB -> MME] UE CONTEXT RELEASE REQUEST
+ue_ctx_release_req_pdu() ->
+ << 16#00, 16#12, 16#40, 16#14, 16#00, 16#00, 16#03, 16#00,
+ 16#00, 16#00, 16#02, 16#00, 16#01, 16#00, 16#08, 16#00,
+ 16#02, 16#00, 16#01, 16#00, 16#02, 16#40, 16#01, 16#20
+ >>.
+
+
+%% [eNB <- MME] UE CONTEXT RELEASE COMMAND
+ue_ctx_release_cmd_pdu() ->
+ << 16#00, 16#17, 16#00, 16#10, 16#00, 16#00, 16#02, 16#00,
+ 16#63, 16#00, 16#04, 16#00, 16#01, 16#00, 16#01, 16#00,
+ 16#02, 16#40, 16#01, 16#20
+ >>.
+
+
+%% [eNB -> MME] UE CONTEXT RELEASE COMPLETE
+ue_ctx_release_compl_pdu() ->
+ << 16#20, 16#17, 16#00, 16#0f, 16#00, 16#00, 16#02, 16#00,
+ 16#00, 16#40, 16#02, 16#00, 16#01, 16#00, 16#08, 16#40,
+ 16#02, 16#00, 16#01
+ >>.
+
+
+%% [eNB -> MME] HANDOVER REQUIRED
+handover_required_pdu() ->
+ << 16#00, 16#00, 16#00, 16#35, 16#00, 16#00, 16#06, 16#00,
+ 16#00, 16#00, 16#03, 16#40, 16#10, 16#92, 16#00, 16#08,
+ 16#00, 16#02, 16#00, 16#00, 16#00, 16#01, 16#00, 16#01,
+ 16#00, 16#00, 16#02, 16#40, 16#02, 16#04, 16#20, 16#00,
+ 16#04, 16#00, 16#0e, 16#00, 16#62, 16#f2, 16#10, 16#40,
+ 16#00, 16#00, 16#00, 16#00, 16#62, 16#f2, 16#10, 16#00,
+ 16#07, 16#00, 16#68, 16#00, 16#04, 16#03, 16#12, 16#34,
+ 16#56
+ >>.
+
+
+%% [MME -> eNB] HANDOVER COMMAND
+handover_command_pdu() ->
+ << 16#20, 16#00, 16#00, 16#28, 16#00, 16#00, 16#05, 16#00,
+ 16#00, 16#00, 16#03, 16#40, 16#10, 16#92, 16#00, 16#08,
+ 16#00, 16#02, 16#00, 16#00, 16#00, 16#01, 16#00, 16#01,
+ 16#00, 16#00, 16#0c, 16#40, 16#07, 16#00, 16#00, 16#0e,
+ 16#40, 16#02, 16#00, 16#00, 16#00, 16#7b, 16#00, 16#04,
+ 16#03, 16#12, 16#34, 16#56
+ >>.
+
+
+%% [MME -> eNB] HANDOVER REQUEST
+handover_request_pdu(TLA, TEID) when is_binary(TLA),
+ is_integer(TEID) ->
+ << 16#00, 16#01, 16#00, 16#6f, 16#00, 16#00, 16#08, 16#00,
+ 16#00, 16#00, 16#03, 16#40, 16#10, 16#92, 16#00, 16#01,
+ 16#00, 16#01, 16#00, 16#00, 16#02, 16#40, 16#02, 16#04,
+ 16#20, 16#00, 16#42, 16#00, 16#0a, 16#18, 16#40, 16#00,
+ 16#00, 16#00, 16#60, 16#40, 16#00, 16#00, 16#00, 16#00,
+ 16#35, 16#00, 16#12, 16#00, 16#00, 16#1b, 16#00, 16#0d,
+ 16#00, 16#1f,
+ TLA/bytes, %% transportLayerAddress (IPv4)
+ TEID:32/big, %% GTP-TEID
+ 16#00, 16#05, 16#04, 16#00, 16#68, 16#00,
+ 16#04, 16#03, 16#12, 16#34, 16#56, 16#00, 16#6b, 16#00,
+ 16#05, 16#1c, 16#00, 16#0e, 16#00, 16#00, 16#00, 16#28,
+ 16#00, 16#21, 16#28, 16#e0, 16#3f, 16#02, 16#35, 16#f1,
+ 16#1e, 16#13, 16#68, 16#a8, 16#55, 16#04, 16#db, 16#fb,
+ 16#8f, 16#65, 16#2b, 16#8c, 16#c7, 16#1c, 16#7c, 16#87,
+ 16#cc, 16#f3, 16#f6, 16#4d, 16#4f, 16#84, 16#5e, 16#e1,
+ 16#d2, 16#fc, 16#c6
+ >>.
+
+
+%% [eNB -> MME] HANDOVER REQUEST ACKNOWLEDGE
+handover_request_ack_pdu(TLA, TEID) when is_binary(TLA),
+ is_integer(TEID) ->
+ << 16#20, 16#01, 16#00, 16#2c, 16#00, 16#00, 16#04, 16#00,
+ 16#00, 16#40, 16#03, 16#40, 16#10, 16#92, 16#00, 16#08,
+ 16#40, 16#02, 16#00, 16#00, 16#00, 16#12, 16#40, 16#10,
+ 16#00, 16#00, 16#14, 16#40, 16#0b, 16#00, 16#01, 16#f0,
+ TLA/bytes, %% transportLayerAddress (IPv4)
+ TEID:32/big, %% GTP-TEID
+ 16#00, 16#7b, 16#00, 16#04, 16#03, 16#12, 16#34, 16#56
+ >>.
+
+
+%% vim:set ts=4 sw=4 et:
--
To view, visit https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41611?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: erlang/osmo-s1gw
Gerrit-Branch: master
Gerrit-Change-Id: I4b1d3f3a009009ab7620656a3b906e60481e47a1
Gerrit-Change-Number: 41611
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <vyanitskiy(a)sysmocom.de>
1
0
[S] Change in ...osmo-epdg[master]: s2b: allow to set the restart counter/recovery field
by pespin 05 Dec '25
by pespin 05 Dec '25
05 Dec '25
Attention is currently required from: laforge, lynxis lazus.
pespin has posted comments on this change by lynxis lazus. ( https://gerrit.osmocom.org/c/erlang/osmo-epdg/+/41588?usp=email )
Change subject: s2b: allow to set the restart counter/recovery field
......................................................................
Patch Set 5:
(2 comments)
Patchset:
PS5:
I'm not following here.
1- You are adding a default value which is basically rand()%256, which defeats the purpose of restart_counter.
2- AFAIU you can configure the restart_counter from config file, but then that means everytime osmo-epdg restarts a user needs to manually edit the file and start osmo-epdg again?
I don't see how is this improving the situation over last commit, actually it's worse afaiu.
File src/epdg_gtpc_s2b.erl:
https://gerrit.osmocom.org/c/erlang/osmo-epdg/+/41588/comment/3dc38dfb_1c6e… :
PS5, Line 111: % Use system_time in order to ensure a fresh system wouldn't re-use always the same restart_counter
AFAIU this is not true, you have 1/256 chance to get the same restart_counter every time you start osmo-epdg.
--
To view, visit https://gerrit.osmocom.org/c/erlang/osmo-epdg/+/41588?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: comment
Gerrit-Project: erlang/osmo-epdg
Gerrit-Branch: master
Gerrit-Change-Id: I1e894a2c54dd180c0bc3a6f78d0bb7dd455cad81
Gerrit-Change-Number: 41588
Gerrit-PatchSet: 5
Gerrit-Owner: lynxis lazus <lynxis(a)fe80.eu>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-CC: pespin <pespin(a)sysmocom.de>
Gerrit-Attention: laforge <laforge(a)osmocom.org>
Gerrit-Attention: lynxis lazus <lynxis(a)fe80.eu>
Gerrit-Comment-Date: Fri, 05 Dec 2025 10:35:55 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
1
0
[XS] Change in libosmocore[master]: osmo-release.sh: Fix coloring output under bash
by osmith 05 Dec '25
by osmith 05 Dec '25
05 Dec '25
Attention is currently required from: fixeria, pespin.
osmith has posted comments on this change by pespin. ( https://gerrit.osmocom.org/c/libosmocore/+/41547?usp=email )
Change subject: osmo-release.sh: Fix coloring output under bash
......................................................................
Patch Set 3: Code-Review+2
(1 comment)
File osmo-release.sh:
https://gerrit.osmocom.org/c/libosmocore/+/41547/comment/c82f1b8e_ff47f228?… :
PS2, Line 39: printf "${GREEN}OK:${RESET} $@\n"
> the first argument to printf is the format string, just like in C it would be better practice to use […]
Done
--
To view, visit https://gerrit.osmocom.org/c/libosmocore/+/41547?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: comment
Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: Ib9e33ec8650ad8bc2e4b1893d9a7195c041c52dc
Gerrit-Change-Number: 41547
Gerrit-PatchSet: 3
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: osmith <osmith(a)sysmocom.de>
Gerrit-Attention: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Attention: pespin <pespin(a)sysmocom.de>
Gerrit-Comment-Date: Fri, 05 Dec 2025 10:29:54 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: Yes
Comment-In-Reply-To: osmith <osmith(a)sysmocom.de>
Comment-In-Reply-To: pespin <pespin(a)sysmocom.de>
1
0