lists.osmocom.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2025
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
List overview
Download
gerrit-log
June 2024
----- 2025 -----
June 2025
May 2025
April 2025
March 2025
February 2025
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
gerrit-log@lists.osmocom.org
1 participants
1566 discussions
Start a n
N
ew thread
[S] Change in osmo-s1gw[master]: sctp_server: allow passing bind address as string
by osmith
osmith has submitted this change. (
https://gerrit.osmocom.org/c/osmo-s1gw/+/37040?usp=email
) Change subject: sctp_server: allow passing bind address as string ...................................................................... sctp_server: allow passing bind address as string Change-Id: I1557e4dd8c918ed70e93ff23dcf0e77c9c9e34a3 --- M src/sctp_server.erl 1 file changed, 14 insertions(+), 1 deletion(-) Approvals: osmith: Looks good to me, approved; Verified diff --git a/src/sctp_server.erl b/src/sctp_server.erl index 883991a..f032492 100644 --- a/src/sctp_server.erl +++ b/src/sctp_server.erl @@ -25,7 +25,7 @@ %% ------------------------------------------------------------------ start_link() -> - start_link({127,0,0,1}, ?S1AP_PORT). + start_link("127.0.0.1", ?S1AP_PORT). start_link(BindAddr, BindPort) -> gen_server:start_link({local, ?MODULE}, ?MODULE, @@ -40,6 +40,10 @@ %% gen_server API %% ------------------------------------------------------------------ +init([BindAddrStr, BindPort]) when is_list(BindAddrStr) -> + {ok, BindAddr} = inet:parse_address(BindAddrStr), + init([BindAddr, BindPort]); + init([BindAddr, BindPort]) -> process_flag(trap_exit, true), {ok, Sock} = gen_sctp:open([{ip, BindAddr}, -- To view, visit
https://gerrit.osmocom.org/c/osmo-s1gw/+/37040?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-s1gw Gerrit-Branch: master Gerrit-Change-Id: I1557e4dd8c918ed70e93ff23dcf0e77c9c9e34a3 Gerrit-Change-Number: 37040 Gerrit-PatchSet: 1 Gerrit-Owner: osmith <osmith(a)sysmocom.de> Gerrit-Reviewer: osmith <osmith(a)sysmocom.de> Gerrit-CC: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-MessageType: merged
1 year
1
0
0
0
[M] Change in osmo-s1gw[master]: Add a global supervisor and env parameters
by osmith
osmith has submitted this change. (
https://gerrit.osmocom.org/c/osmo-s1gw/+/37042?usp=email
) Change subject: Add a global supervisor and env parameters ...................................................................... Add a global supervisor and env parameters Change-Id: I2da6bccf728bdbe615aaf853b33077ceb4481176 --- M src/osmo_s1gw_app.erl A src/osmo_s1gw_sup.erl M src/sctp_proxy.erl M src/sctp_server.erl 4 files changed, 78 insertions(+), 19 deletions(-) Approvals: osmith: Looks good to me, approved; Verified diff --git a/src/osmo_s1gw_app.erl b/src/osmo_s1gw_app.erl index 596b3e8..7e1bc56 100644 --- a/src/osmo_s1gw_app.erl +++ b/src/osmo_s1gw_app.erl @@ -4,8 +4,9 @@ -export([start/2, stop/1]). start(_StartType, _StartArgs) -> - sctp_server:start_link(). - %% TODO: osmo_s1gw_sup:start_link(). + osmo_s1gw_sup:start_link(). stop(_State) -> - ok. + ok. + +%% vim:set ts=4 sw=4 et: diff --git a/src/osmo_s1gw_sup.erl b/src/osmo_s1gw_sup.erl new file mode 100644 index 0000000..a62f266 --- /dev/null +++ b/src/osmo_s1gw_sup.erl @@ -0,0 +1,46 @@ +-module(osmo_s1gw_sup). +-behaviour(supervisor). + +-export([init/1, + start_link/0]). + +-include("s1ap.hrl"). + +-define(SERVER, ?MODULE). +-define(ENV_APP_NAME, osmo_s1gw). +-define(ENV_DEFAULT_S1GW_BIND_ADDR, "0.0.0.0"). +-define(ENV_DEFAULT_S1GW_BIND_PORT, ?S1AP_PORT). +-define(ENV_DEFAULT_MME_ADDR, "127.0.0.1"). +-define(ENV_DEFAULT_MME_PORT, ?S1AP_PORT). + +%% ------------------------------------------------------------------ +%% supervisor API +%% ------------------------------------------------------------------ + +start_link() -> + supervisor:start_link({local, ?SERVER}, ?MODULE, []). + + +init([]) -> + S1GWBindAddr = get_env(s1gw_bind_addr, ?ENV_DEFAULT_S1GW_BIND_ADDR), + S1GWBindPort = get_env(s1gw_bind_port, ?ENV_DEFAULT_S1GW_BIND_PORT), + MmeAddr = get_env(mme_addr, ?ENV_DEFAULT_MME_ADDR), + MmePort = get_env(mme_port, ?ENV_DEFAULT_MME_PORT), + SctpServer = {sctp_server, {sctp_server, start_link, + [S1GWBindAddr, S1GWBindPort, + {MmeAddr, MmePort}]}, + permanent, + 5000, + worker, + [sctp_server]}, + {ok, {{one_for_all, 5, 10}, [SctpServer]}}. + + +%% ------------------------------------------------------------------ +%% private API +%% ------------------------------------------------------------------ + +get_env(Param, Default) -> + application:get_env(?ENV_APP_NAME, Param, Default). + +%% vim:set ts=4 sw=4 et: diff --git a/src/sctp_proxy.erl b/src/sctp_proxy.erl index 2cc6165..43cb081 100644 --- a/src/sctp_proxy.erl +++ b/src/sctp_proxy.erl @@ -34,6 +34,10 @@ %% gen_statem API %% ------------------------------------------------------------------ +init([Aid, MmeAddrStr, MmePort]) when is_list(MmeAddrStr) -> + {ok, MmeAddr} = inet:parse_address(MmeAddrStr), + init([Aid, MmeAddr, MmePort]); + init([Aid, MmeAddr, MmePort]) -> {ok, connecting, #{enb_aid => Aid, diff --git a/src/sctp_server.erl b/src/sctp_server.erl index 48583c5..249cd8f 100644 --- a/src/sctp_server.erl +++ b/src/sctp_server.erl @@ -6,28 +6,25 @@ handle_call/3, handle_cast/2, terminate/2]). --export([start_link/0, - start_link/2]). --export([send_data/2]). +-export([start_link/3, + send_data/2]). -include_lib("kernel/include/inet.hrl"). -include_lib("kernel/include/inet_sctp.hrl"). -include("s1ap.hrl"). --record(server_state, {sock, clients}). +-record(server_state, {sock, clients, mme_addr_port}). -record(client_state, {addr_port, pid}). %% ------------------------------------------------------------------ %% public API %% ------------------------------------------------------------------ -start_link() -> - start_link("127.0.0.1", ?S1AP_PORT). - -start_link(BindAddr, BindPort) -> +start_link(BindAddr, BindPort, MmeAddrPort) -> gen_server:start_link({local, ?MODULE}, ?MODULE, - [BindAddr, BindPort], []). + [BindAddr, BindPort, MmeAddrPort], + []). send_data(Aid, Data) -> @@ -38,11 +35,11 @@ %% gen_server API %% ------------------------------------------------------------------ -init([BindAddrStr, BindPort]) when is_list(BindAddrStr) -> +init([BindAddrStr, BindPort, MmeAddrPort]) when is_list(BindAddrStr) -> {ok, BindAddr} = inet:parse_address(BindAddrStr), - init([BindAddr, BindPort]); + init([BindAddr, BindPort, MmeAddrPort]); -init([BindAddr, BindPort]) -> +init([BindAddr, BindPort, MmeAddrPort]) -> process_flag(trap_exit, true), {ok, Sock} = gen_sctp:open([{ip, BindAddr}, {port, BindPort}, @@ -52,7 +49,8 @@ logger:info("SCTP server listening on ~w:~w", [BindAddr, BindPort]), ok = gen_sctp:listen(Sock, true), {ok, #server_state{sock = Sock, - clients = dict:new()}}. + clients = dict:new(), + mme_addr_port = MmeAddrPort}}. handle_call(Info, _From, State) -> @@ -116,7 +114,8 @@ case ConnState of comm_up -> logger:notice("Connection (id=~p, ~p:~p) established", [Aid, FromAddr, FromPort]), - Clients = client_add(State#server_state.clients, Aid, FromAddr, FromPort); + Clients = client_add(State#server_state.clients, Aid, FromAddr, FromPort, + State#server_state.mme_addr_port); shutdown_comp -> logger:notice("Connection (id=~p, ~p:~p) closed", [Aid, FromAddr, FromPort]), Clients = client_del(State#server_state.clients, Aid); @@ -151,8 +150,8 @@ %% Add a new client to the list, spawning a proxy process -client_add(Clients, Aid, FromAddr, FromPort) -> - {ok, Pid} = sctp_proxy:start_link(Aid, {127,0,1,1}, ?S1AP_PORT), %% XXX! +client_add(Clients, Aid, FromAddr, FromPort, {MmeAddr, MmePort}) -> + {ok, Pid} = sctp_proxy:start_link(Aid, MmeAddr, MmePort), NewClient = #client_state{addr_port = {FromAddr, FromPort}, pid = Pid}, dict:store(Aid, NewClient, Clients). -- To view, visit
https://gerrit.osmocom.org/c/osmo-s1gw/+/37042?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-s1gw Gerrit-Branch: master Gerrit-Change-Id: I2da6bccf728bdbe615aaf853b33077ceb4481176 Gerrit-Change-Number: 37042 Gerrit-PatchSet: 1 Gerrit-Owner: osmith <osmith(a)sysmocom.de> Gerrit-Reviewer: osmith <osmith(a)sysmocom.de> Gerrit-CC: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-MessageType: merged
1 year
1
0
0
0
[S] Change in osmo-s1gw[master]: Rework logging config, colorize output
by osmith
osmith has submitted this change. (
https://gerrit.osmocom.org/c/osmo-s1gw/+/37043?usp=email
) Change subject: Rework logging config, colorize output ...................................................................... Rework logging config, colorize output Change-Id: Icb24c9ab0f7f236424c08f6461d058d9a6e8a40b --- M config/sys.config M rebar.config M rebar.lock 3 files changed, 25 insertions(+), 4 deletions(-) Approvals: osmith: Looks good to me, approved; Verified diff --git a/config/sys.config b/config/sys.config index 072f183..dcace60 100644 --- a/config/sys.config +++ b/config/sys.config @@ -4,5 +4,12 @@ [{logger_level, info}, {logger, [{handler, default, logger_std_h, - #{ level => debug, formatter => {logger_formatter, - #{ template => ["[", level, "] ", pid, " ", file, ":", line, " ", msg, "\n"] }}}}]}]}]. + #{formatter => + {logger_color_formatter, #{legacy_header => false, + single_line => false, + template => [time, " ", color, "[", level, "]", + {pid, [" ", pid, ""], ""}, + {mfa, [" ", mfa, ":", line], ""}, + ": ", msg, reset, "\n"]}}}}]}]}]. + +%% vim:set ts=2 sw=2 et: diff --git a/rebar.config b/rebar.config index e4da64f..57da0ba 100644 --- a/rebar.config +++ b/rebar.config @@ -4,7 +4,9 @@ {minimum_otp_vsn, "25.2.3"}. -{deps, []}. +{deps, [ + {logger_color_formatter, {git, "
https://github.com/rlipscombe/logger_color_formatter.git
", {tag, "0.5.0"}}} +]}. {plugins, [ {provider_asn1, ".*", {git, "
https://github.com/knusbaum/provider_asn1.git
", {tag, "0.4.0"}}} diff --git a/rebar.lock b/rebar.lock index 57afcca..0d93593 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1 +1,4 @@ -[]. +[{<<"logger_color_formatter">>, + {git,"
https://github.com/rlipscombe/logger_color_formatter.git
", + {ref,"f1c96f979e6350f8cd787d27fe9ff003cbf3416b"}}, + 0}]. -- To view, visit
https://gerrit.osmocom.org/c/osmo-s1gw/+/37043?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-s1gw Gerrit-Branch: master Gerrit-Change-Id: Icb24c9ab0f7f236424c08f6461d058d9a6e8a40b Gerrit-Change-Number: 37043 Gerrit-PatchSet: 1 Gerrit-Owner: osmith <osmith(a)sysmocom.de> Gerrit-Reviewer: osmith <osmith(a)sysmocom.de> Gerrit-CC: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-MessageType: merged
1 year
1
0
0
0
[S] Change in osmo-s1gw[master]: sctp_server: add public API to shutdown the server
by osmith
osmith has submitted this change. (
https://gerrit.osmocom.org/c/osmo-s1gw/+/37044?usp=email
) Change subject: sctp_server: add public API to shutdown the server ...................................................................... sctp_server: add public API to shutdown the server Change-Id: I706dc7d79feb9d3c6d527fc767e5c5574004a95b --- M src/sctp_server.erl 1 file changed, 15 insertions(+), 1 deletion(-) Approvals: osmith: Looks good to me, approved; Verified diff --git a/src/sctp_server.erl b/src/sctp_server.erl index 249cd8f..4ba49eb 100644 --- a/src/sctp_server.erl +++ b/src/sctp_server.erl @@ -7,7 +7,8 @@ handle_cast/2, terminate/2]). -export([start_link/3, - send_data/2]). + send_data/2, + shutdown/0]). -include_lib("kernel/include/inet.hrl"). -include_lib("kernel/include/inet_sctp.hrl"). @@ -31,6 +32,10 @@ gen_server:cast(?MODULE, {send_data, Aid, Data}). +shutdown() -> + gen_server:stop(?MODULE). + + %% ------------------------------------------------------------------ %% gen_server API %% ------------------------------------------------------------------ -- To view, visit
https://gerrit.osmocom.org/c/osmo-s1gw/+/37044?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-s1gw Gerrit-Branch: master Gerrit-Change-Id: I706dc7d79feb9d3c6d527fc767e5c5574004a95b Gerrit-Change-Number: 37044 Gerrit-PatchSet: 1 Gerrit-Owner: osmith <osmith(a)sysmocom.de> Gerrit-Reviewer: osmith <osmith(a)sysmocom.de> Gerrit-CC: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-MessageType: merged
1 year
1
0
0
0
[S] Change in osmo-s1gw[master]: sctp_server: fix terminate/2: match any Reason
by osmith
osmith has submitted this change. (
https://gerrit.osmocom.org/c/osmo-s1gw/+/37045?usp=email
) Change subject: sctp_server: fix terminate/2: match any Reason ...................................................................... sctp_server: fix terminate/2: match any Reason Change-Id: I57f1604ef3febee6c330521a044271988110cf2a --- M src/sctp_server.erl 1 file changed, 11 insertions(+), 2 deletions(-) Approvals: osmith: Looks good to me, approved; Verified diff --git a/src/sctp_server.erl b/src/sctp_server.erl index 4ba49eb..a2b722a 100644 --- a/src/sctp_server.erl +++ b/src/sctp_server.erl @@ -102,8 +102,8 @@ {noreply, State}. -terminate(shutdown, State) -> - logger:notice("Terminating ~p", [?MODULE]), +terminate(Reason, State) -> + logger:notice("Terminating, reason ~p", [Reason]), close_conns(State), gen_sctp:close(State#server_state.sock), ok. -- To view, visit
https://gerrit.osmocom.org/c/osmo-s1gw/+/37045?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-s1gw Gerrit-Branch: master Gerrit-Change-Id: I57f1604ef3febee6c330521a044271988110cf2a Gerrit-Change-Number: 37045 Gerrit-PatchSet: 1 Gerrit-Owner: osmith <osmith(a)sysmocom.de> Gerrit-Reviewer: osmith <osmith(a)sysmocom.de> Gerrit-CC: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-MessageType: merged
1 year
1
0
0
0
[M] Change in osmo-s1gw[master]: s1ap_proxy: implement patching of E-RAB SETUP REQ/RSP
by osmith
osmith has submitted this change. (
https://gerrit.osmocom.org/c/osmo-s1gw/+/37046?usp=email
) Change subject: s1ap_proxy: implement patching of E-RAB SETUP REQ/RSP ...................................................................... s1ap_proxy: implement patching of E-RAB SETUP REQ/RSP Change-Id: I88cb261d93b56a4e0ca06ad1d676d1ac16d115bb --- M src/s1ap_proxy.erl A test/s1ap_proxy_test.erl 2 files changed, 209 insertions(+), 3 deletions(-) Approvals: osmith: Looks good to me, approved; Verified diff --git a/src/s1ap_proxy.erl b/src/s1ap_proxy.erl index 62701ef..a78f084 100644 --- a/src/s1ap_proxy.erl +++ b/src/s1ap_proxy.erl @@ -1,17 +1,25 @@ -module(s1ap_proxy). --export([handle_pdu/1]). +-export([handle_pdu/1, + encode_pdu/1, + decode_pdu/1]). + +-include("S1AP-PDU-Descriptions.hrl"). +-include("S1AP-PDU-Contents.hrl"). +-include("S1AP-Containers.hrl"). +-include("S1AP-Constants.hrl"). %% ------------------------------------------------------------------ %% public API %% ------------------------------------------------------------------ %% Process an S1AP PDU -handle_pdu(Data) -> +-spec handle_pdu(binary()) -> binary(). +handle_pdu(Data) when is_binary(Data) -> case decode_pdu(Data) of {ok, Pdu} -> logger:info("S1AP PDU: ~p", [Pdu]), - Data; + handle_pdu(Data, Pdu); {error, {asn1, Error}} -> logger:error("S1AP PDU decoding failed: ~p", [Error]), Data @@ -22,10 +30,111 @@ %% private API %% ------------------------------------------------------------------ +%% Encode an S1AP PDU +-spec encode_pdu(tuple()) -> {ok, binary()} | + {error, {asn1, tuple()}}. +encode_pdu(Pdu) -> + 'S1AP-PDU-Descriptions':encode('S1AP-PDU', Pdu). + + %% Decode an S1AP PDU -spec decode_pdu(binary()) -> {ok, tuple()} | {error, {asn1, tuple()}}. decode_pdu(Data) -> 'S1AP-PDU-Descriptions':decode('S1AP-PDU', Data). + +%% Helper function for handle_pdu/2. +%% Attempt to encode a new (modified) S1AP PDU, +%% return a new binary() on success or Data on error. +handle_pdu_new(Data, NewPdu) -> + case encode_pdu(NewPdu) of + {ok, NewData} -> + NewData; + {error, {asn1, Error}} -> + logger:error("S1AP PDU encoding failed: ~p", [Error]), + Data + end. + + +%% E-RAB SETUP REQUEST +handle_pdu(Data, {Outcome = initiatingMessage, + #'InitiatingMessage'{procedureCode = ?'id-E-RABSetup', + value = Content} = Pdu}) -> + logger:debug("Patching E-RAB SETUP REQUEST"), + IEs = handle_ies(Content#'E-RABSetupRequest'.protocolIEs, + ?'id-E-RABToBeSetupListBearerSUReq'), + NewContent = Content#'E-RABSetupRequest'{protocolIEs = IEs}, + handle_pdu_new(Data, {Outcome, Pdu#'InitiatingMessage'{value = NewContent}}); + +%% E-RAB SETUP RESPONSE +handle_pdu(Data, {Outcome = successfulOutcome, + #'SuccessfulOutcome'{procedureCode = ?'id-E-RABSetup', + value = Content} = Pdu}) -> + logger:debug("Patching E-RAB SETUP RESPONSE"), + IEs = handle_ies(Content#'E-RABSetupResponse'.protocolIEs, + ?'id-E-RABSetupListBearerSURes'), + NewContent = Content#'E-RABSetupResponse'{protocolIEs = IEs}, + handle_pdu_new(Data, {Outcome, Pdu#'SuccessfulOutcome'{value = NewContent}}); + +%% Proxy all other messages unmodified +handle_pdu(Data, _Pdu) -> + Data. + + +%% Handle a single IE (Information Element) +-spec handle_ie(tuple()) -> tuple(). + +%% E-RAB SETUP REQUEST related IEs +handle_ie(#'ProtocolIE-Field'{id = ?'id-E-RABToBeSetupListBearerSUReq', + value = Content}) -> + %% This IE contains a list of BearerSUReq, so patch inner IEs + handle_ies(Content, ?'id-E-RABToBeSetupItemBearerSUReq'); + +handle_ie(#'ProtocolIE-Field'{id = ?'id-E-RABToBeSetupItemBearerSUReq', + value = Content}) -> + Content#'E-RABToBeSetupItemBearerSUReq'{transportLayerAddress = transp_layer_addr()}; + +%% E-RAB SETUP RESPONSE related IEs +handle_ie(#'ProtocolIE-Field'{id = ?'id-E-RABSetupListBearerSURes', + value = Content}) -> + %% This IE contains a list of BearerSURes, so patch inner IEs + handle_ies(Content, ?'id-E-RABSetupItemBearerSURes'); + +handle_ie(#'ProtocolIE-Field'{id = ?'id-E-RABSetupItemBearerSURes', + value = Content}) -> + Content#'E-RABSetupItemBearerSURes'{transportLayerAddress = transp_layer_addr()}; + +%% Catch-all variant, which should not be called normally +handle_ie(#'ProtocolIE-Field'{value = Content} = IE) -> + logger:error("[BUG] Unhandled S1AP IE: ~p", [IE]), + Content. + + +%% Iterate over the given list of 'ProtocolIE-Field' IEs, +%% calling function handle_ie/1 for IEs matching the given IEI. +-spec handle_ies(list(), integer()) -> list(). +handle_ies(IEs, IEI) -> + handle_ies([], IEs, IEI). + +handle_ies(Acc, [IE | IEs], IEI) -> + case IE of + #'ProtocolIE-Field'{id = IEI} -> + NewIE = IE#'ProtocolIE-Field'{value = handle_ie(IE)}, + handle_ies([NewIE | Acc], IEs, IEI); + _ -> + handle_ies([IE | Acc], IEs, IEI) + end; + +handle_ies(Acc, [], _) -> + lists:reverse(Acc). + + +%% GTP-U IP address (TransportLayerAddress) to be used while patching +transp_layer_addr() -> + AddrStr = application:get_env(osmo_s1gw, transp_layer_addr, "255.255.255.255"), + {ok, Addr} = inet:parse_address(AddrStr), + %% sadly, there exists inet:ntoa/1, but not inet:aton/1 + list_to_binary(tuple_to_list(Addr)). + %% vim:set ts=4 sw=4 et: diff --git a/test/s1ap_proxy_test.erl b/test/s1ap_proxy_test.erl new file mode 100644 index 0000000..408f468 --- /dev/null +++ b/test/s1ap_proxy_test.erl @@ -0,0 +1,88 @@ +-module(s1ap_proxy_test). + +-include_lib("eunit/include/eunit.hrl"). + +%% ------------------------------------------------------------------ +%% testcases +%% ------------------------------------------------------------------ + +%% 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_req_test() -> + OrigData = s1_setup_req_pdu(), + %% Expect the PDU to be proxied unmodified + ?assertEqual(OrigData, s1ap_proxy:handle_pdu(OrigData)). + + +%% E-RAB SETUP REQUEST +e_rab_setup_req_pdu(TLA, TEID) when is_binary(TLA), + is_binary(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/bytes, %% 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 + >>. + +e_rab_setup_req_test() -> + %% Original input data + TEID = << 16#00, 16#00, 16#00, 16#18 >>, + OrigTLA = << 16#ac, 16#16, 16#00, 16#06 >>, + OrigData = e_rab_setup_req_pdu(OrigTLA, TEID), + + %% Expected output data + ExpTLA = << 16#7f, 16#00, 16#00, 16#01 >>, + ExpData = e_rab_setup_req_pdu(ExpTLA, TEID), + + application:set_env(osmo_s1gw, transp_layer_addr, "127.0.0.1"), + ?assertEqual(ExpData, s1ap_proxy:handle_pdu(OrigData)). + + +%% E-RAB SETUP RESPONSE +e_rab_setup_rsp_pdu(TLA, TEID) when is_binary(TLA), + is_binary(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/bytes %% GTP-TEID + >>. + +e_rab_setup_rsp_test() -> + %% Original input data + TEID = << 16#6c, 16#05, 16#bf, 16#56 >>, + OrigTLA = << 16#c0, 16#a8, 16#68, 16#a7 >>, + OrigData = e_rab_setup_rsp_pdu(OrigTLA, TEID), + + %% Expected output data + ExpTLA = << 16#7f, 16#00, 16#00, 16#01 >>, + ExpData = e_rab_setup_rsp_pdu(ExpTLA, TEID), + + application:set_env(osmo_s1gw, transp_layer_addr, "127.0.0.1"), + ?assertEqual(ExpData, s1ap_proxy:handle_pdu(OrigData)). + +%% vim:set ts=4 sw=4 et: -- To view, visit
https://gerrit.osmocom.org/c/osmo-s1gw/+/37046?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-s1gw Gerrit-Branch: master Gerrit-Change-Id: I88cb261d93b56a4e0ca06ad1d676d1ac16d115bb Gerrit-Change-Number: 37046 Gerrit-PatchSet: 1 Gerrit-Owner: osmith <osmith(a)sysmocom.de> Gerrit-Reviewer: osmith <osmith(a)sysmocom.de> Gerrit-CC: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-MessageType: merged
1 year
1
0
0
0
[XL] Change in osmo-s1gw[master]: Check-in S1AP ASN.1 definitions (3GPP TS 36.413 v17.6.0)
by osmith
osmith has submitted this change. (
https://gerrit.osmocom.org/c/osmo-s1gw/+/37037?usp=email
) Change subject: Check-in S1AP ASN.1 definitions (3GPP TS 36.413 v17.6.0) ...................................................................... Check-in S1AP ASN.1 definitions (3GPP TS 36.413 v17.6.0) Change-Id: Ifda18e71abea29f9bf5dac901f1aae70dab8ff75 --- A asn1/S1AP-CommonDataTypes.asn A asn1/S1AP-Constants.asn A asn1/S1AP-Containers.asn A asn1/S1AP-IEs.asn A asn1/S1AP-PDU-Contents.asn A asn1/S1AP-PDU-Descriptions.asn A asn1/S1AP-SonTransfer-IEs.asn M rebar.config 8 files changed, 8,599 insertions(+), 0 deletions(-) Approvals: osmith: Looks good to me, approved; Verified -- To view, visit
https://gerrit.osmocom.org/c/osmo-s1gw/+/37037?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-s1gw Gerrit-Branch: master Gerrit-Change-Id: Ifda18e71abea29f9bf5dac901f1aae70dab8ff75 Gerrit-Change-Number: 37037 Gerrit-PatchSet: 1 Gerrit-Owner: osmith <osmith(a)sysmocom.de> Gerrit-Reviewer: osmith <osmith(a)sysmocom.de> Gerrit-CC: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-MessageType: merged
1 year
1
0
0
0
[S] Change in osmo-s1gw[master]: .gitignore: ignore generated S1AP code
by osmith
osmith has submitted this change. (
https://gerrit.osmocom.org/c/osmo-s1gw/+/37038?usp=email
) Change subject: .gitignore: ignore generated S1AP code ...................................................................... .gitignore: ignore generated S1AP code Change-Id: I89df49e1290f32d2fabbc4ffd9a5767bf0fdac00 --- M .gitignore 1 file changed, 13 insertions(+), 0 deletions(-) Approvals: osmith: Looks good to me, approved; Verified diff --git a/.gitignore b/.gitignore index 83aa88b..483ba30 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ _build *.beam + +# generated S1AP code +/include/S1AP-*.hrl +/src/S1AP-*.erl -- To view, visit
https://gerrit.osmocom.org/c/osmo-s1gw/+/37038?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-s1gw Gerrit-Branch: master Gerrit-Change-Id: I89df49e1290f32d2fabbc4ffd9a5767bf0fdac00 Gerrit-Change-Number: 37038 Gerrit-PatchSet: 1 Gerrit-Owner: osmith <osmith(a)sysmocom.de> Gerrit-Reviewer: osmith <osmith(a)sysmocom.de> Gerrit-CC: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-MessageType: merged
1 year
1
0
0
0
[L] Change in osmo-s1gw[master]: Initial SCTP proxy (server/client) implementation
by osmith
osmith has submitted this change. (
https://gerrit.osmocom.org/c/osmo-s1gw/+/37036?usp=email
) Change subject: Initial SCTP proxy (server/client) implementation ...................................................................... Initial SCTP proxy (server/client) implementation Change-Id: Ia317f58f7dcbec42930165fdcd42d0ddd23e289c --- A .gitignore A config/sys.config A rebar.config A rebar.lock A src/osmo_s1gw.app.src A src/osmo_s1gw_app.erl A src/sctp_client.erl A src/sctp_proxy.erl A src/sctp_server.erl 9 files changed, 480 insertions(+), 0 deletions(-) Approvals: osmith: Looks good to me, approved; Verified diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..83aa88b --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +_build +*.beam diff --git a/config/sys.config b/config/sys.config new file mode 100644 index 0000000..072f183 --- /dev/null +++ b/config/sys.config @@ -0,0 +1,8 @@ +%% -*- erlang -*- + +[{kernel, + [{logger_level, info}, + {logger, + [{handler, default, logger_std_h, + #{ level => debug, formatter => {logger_formatter, + #{ template => ["[", level, "] ", pid, " ", file, ":", line, " ", msg, "\n"] }}}}]}]}]. diff --git a/rebar.config b/rebar.config new file mode 100644 index 0000000..7d7b6f2 --- /dev/null +++ b/rebar.config @@ -0,0 +1,15 @@ +%% -*- erlang -*- + +{erl_opts, [debug_info, {parse_transform}]}. + +{minimum_otp_vsn, "25.2.3"}. + +{deps, []}. + +{xref_checks, [undefined_function_calls, undefined_functions, + deprecated_function_calls, deprecated_functions]}. + +{dialyzer, [ + {plt_extra_apps, [kernel, stdlib, erts, tools, inets, compiler]}, + {warnings, [no_improper_lists]} +]}. diff --git a/rebar.lock b/rebar.lock new file mode 100644 index 0000000..57afcca --- /dev/null +++ b/rebar.lock @@ -0,0 +1 @@ +[]. diff --git a/src/osmo_s1gw.app.src b/src/osmo_s1gw.app.src new file mode 100644 index 0000000..bc2a8d7 --- /dev/null +++ b/src/osmo_s1gw.app.src @@ -0,0 +1,14 @@ +%-*- mode: erlang -*- + +{application, osmo_s1gw, [ + {description, "Osmocom S1AP Gateway"}, + {vsn, "1"}, + {registered, []}, + {applications, [ + kernel, + stdlib + ]}, + {modules, []}, + {mod, {osmo_s1gw_app, []}}, + {env, []} +]}. diff --git a/src/osmo_s1gw_app.erl b/src/osmo_s1gw_app.erl new file mode 100644 index 0000000..596b3e8 --- /dev/null +++ b/src/osmo_s1gw_app.erl @@ -0,0 +1,11 @@ +-module(osmo_s1gw_app). +-behaviour(application). + +-export([start/2, stop/1]). + +start(_StartType, _StartArgs) -> + sctp_server:start_link(). + %% TODO: osmo_s1gw_sup:start_link(). + +stop(_State) -> + ok. diff --git a/src/sctp_client.erl b/src/sctp_client.erl new file mode 100644 index 0000000..67c7069 --- /dev/null +++ b/src/sctp_client.erl @@ -0,0 +1,42 @@ +-module(sctp_client). + +-export([connect/0, + connect/1, + connect/2, + send_data/2, + disconnect/1]). + +-include_lib("kernel/include/inet.hrl"). +-include_lib("kernel/include/inet_sctp.hrl"). + +-define(S1AP_PORT, 36412). +-define(S1AP_PPID, 18). +-define(SCTP_STREAM, 0). + +%% ------------------------------------------------------------------ +%% public API +%% ------------------------------------------------------------------ + +connect() -> + connect(localhost). + +connect(Host) -> + connect(Host, ?S1AP_PORT). + +connect(Host, Port) -> + {ok, Sock} = gen_sctp:open([{type, seqpacket}, + {active, true}]), + gen_sctp:connect_init(Sock, Host, Port, []), + {ok, Sock}. + + +send_data({Sock, Aid}, Data) -> + gen_sctp:send(Sock, #sctp_sndrcvinfo{stream = ?SCTP_STREAM, + ppid = ?S1AP_PPID, + assoc_id = Aid}, Data). + + +disconnect({Sock, Aid}) -> + gen_sctp:eof(Sock, #sctp_assoc_change{assoc_id = Aid}). + +%% vim:set ts=4 sw=4 et: diff --git a/src/sctp_proxy.erl b/src/sctp_proxy.erl new file mode 100644 index 0000000..e09720c --- /dev/null +++ b/src/sctp_proxy.erl @@ -0,0 +1,177 @@ +-module(sctp_proxy). +-behaviour(gen_statem). + +-export([init/1, + callback_mode/0, + connecting/3, + connected/3, + code_change/4, + terminate/3]). +-export([start_link/3, + send_data/2, + shutdown/1]). + +-include_lib("kernel/include/inet.hrl"). +-include_lib("kernel/include/inet_sctp.hrl"). + +%% ------------------------------------------------------------------ +%% public API +%% ------------------------------------------------------------------ + +start_link(Aid, MmeAddr, MmePort) -> + gen_statem:start_link(?MODULE, [Aid, MmeAddr, MmePort], []). + + +send_data(Pid, Data) -> + gen_statem:cast(Pid, {send_data, Data}). + + +shutdown(Pid) -> + gen_statem:stop(Pid). + + +%% ------------------------------------------------------------------ +%% gen_statem API +%% ------------------------------------------------------------------ + +init([Aid, MmeAddr, MmePort]) -> + {ok, connecting, + #{enb_aid => Aid, + mme_addr => MmeAddr, + mmr_port => MmePort, + tx_queue => []}}. + + +callback_mode() -> + [state_functions, state_enter]. + + +%% CONNECTING state +connecting(enter, OldState, + #{mme_addr := MmeAddr, mmr_port := MmePort} = S) -> + logger:info("State change: ~p -> ~p", [OldState, ?FUNCTION_NAME]), + %% Initiate connection establishment with the MME + {ok, Sock} = sctp_client:connect(MmeAddr, MmePort), + {keep_state, S#{sock => Sock}, + [{state_timeout, 2_000_000, conn_est_timeout}]}; + +%% Handle connection establishment timeout +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}, + #{tx_queue := Pending} = S) -> + {keep_state, S#{tx_queue := [Data | Pending]}}; + +%% Handle an #sctp_assoc_change event (connection state) +connecting(info, {sctp, _Socket, MmeAddr, MmePort, + {[], #sctp_assoc_change{state = ConnState, + assoc_id = Aid}}}, S) -> + case ConnState of + comm_up -> + logger:notice("MME connection (id=~p, ~p:~p) established", + [Aid, MmeAddr, MmePort]), + {next_state, connected, S#{mme_aid => Aid}}; + _ -> + logger:notice("MME connection establishment failed: ~p", [ConnState]), + {stop, {shutdown, conn_est_fail}} + end; + +%% Catch-all for other kinds of SCTP events +connecting(info, {sctp, _Socket, MmeAddr, MmePort, + {AncData, Data}}, S) -> + logger:debug("Unhandled SCTP event (~p:~p): ~p, ~p", + [MmeAddr, MmePort, AncData, Data]), + {keep_state, S}; + +connecting(Event, EventData, S) -> + logger:error("Unexpected event ~p: ~p", [Event, EventData]), + {keep_state, S}. + + +%% CONNECTED state +connected(enter, OldState, S) -> + logger:info("State change: ~p -> ~p", [OldState, ?FUNCTION_NAME]), + %% Send pending eNB -> MME messages (if any) + ok = sctp_send_pending(S), + {keep_state, maps:remove(tx_queue, S)}; + +%% Handle an eNB -> MME data forwarding request (forward) +connected(cast, {send_data, Data}, S) -> + ok = sctp_send(S, Data), + {keep_state, S}; + +%% Handle an #sctp_assoc_change event (MME connection state) +connected(info, {sctp, _Socket, MmeAddr, MmePort, + {[], #sctp_assoc_change{state = ConnState, + assoc_id = Aid}}}, S) -> + case ConnState of + comm_up -> + logger:notice("MME connection (id=~p, ~p:~p) is already established?!?", + [Aid, MmeAddr, MmePort]), + {keep_state, S}; + _ -> + logger:notice("MME connection state: ~p", [ConnState]), + {stop, {shutdown, conn_fail}} + end; + +%% Handle an #sctp_sndrcvinfo event (MME -> eNB data) +connected(info, {sctp, _Socket, MmeAddr, MmePort, + {[#sctp_sndrcvinfo{assoc_id = Aid}], Data}}, S) -> + logger:info("MME connection (id=~p, ~p:~p) Rx ~p", + [Aid, MmeAddr, MmePort, Data]), + sctp_server:send_data(maps:get(enb_aid, S), Data), + {keep_state, S}; + +%% Catch-all for other kinds of SCTP events +connected(info, {sctp, _Socket, MmeAddr, MmePort, + {AncData, Data}}, S) -> + logger:debug("Unhandled SCTP event (~p:~p): ~p, ~p", + [MmeAddr, MmePort, AncData, Data]), + {keep_state, S}; + +%% Catch-all handler for this state +connected(Event, EventData, S) -> + logger:error("Unexpected event ~p: ~p", [Event, EventData]), + {keep_state, S}. + + + +code_change(_Vsn, State, S, _Extra) -> + {ok, State, S}. + + +terminate(Reason, State, S) -> + logger:notice("Terminating in state ~p, reason ~p", [State, Reason]), + case S of + #{sock := Sock, mme_aid := Aid} -> + sctp_client:disconnect({Sock, Aid}), + gen_sctp:close(Sock); + #{sock := Sock} -> + gen_sctp:close(Sock); + _ -> ok + end. + + +%% ------------------------------------------------------------------ +%% private API +%% ------------------------------------------------------------------ + +%% Send a single message to the MME +sctp_send(#{sock := Sock, mme_aid := Aid}, Data) -> + sctp_client:send_data({Sock, Aid}, Data). + + +%% Send pending messages to the MME +sctp_send_pending(#{tx_queue := Pending} = S) -> + sctp_send_pending(S, lists:reverse(Pending)). + +sctp_send_pending(S, [Data | Pending]) -> + sctp_send(S, Data), + sctp_send_pending(S, Pending); + +sctp_send_pending(_S, []) -> + ok. + +%% vim:set ts=4 sw=4 et: diff --git a/src/sctp_server.erl b/src/sctp_server.erl new file mode 100644 index 0000000..883991a --- /dev/null +++ b/src/sctp_server.erl @@ -0,0 +1,202 @@ +-module(sctp_server). +-behaviour(gen_server). + +-export([init/1, + handle_info/2, + handle_call/3, + handle_cast/2, + terminate/2]). +-export([start_link/0, + start_link/2]). +-export([send_data/2]). + +-include_lib("kernel/include/inet.hrl"). +-include_lib("kernel/include/inet_sctp.hrl"). + +-define(S1AP_PORT, 36412). +-define(S1AP_PPID, 18). +-define(SCTP_STREAM, 0). + +-record(server_state, {sock, clients}). +-record(client_state, {addr_port, pid}). + +%% ------------------------------------------------------------------ +%% public API +%% ------------------------------------------------------------------ + +start_link() -> + start_link({127,0,0,1}, ?S1AP_PORT). + +start_link(BindAddr, BindPort) -> + gen_server:start_link({local, ?MODULE}, ?MODULE, + [BindAddr, BindPort], []). + + +send_data(Aid, Data) -> + gen_server:cast(?MODULE, {send_data, Aid, Data}). + + +%% ------------------------------------------------------------------ +%% gen_server API +%% ------------------------------------------------------------------ + +init([BindAddr, BindPort]) -> + process_flag(trap_exit, true), + {ok, Sock} = gen_sctp:open([{ip, BindAddr}, + {port, BindPort}, + {type, seqpacket}, + {reuseaddr, true}, + {active, true}]), + logger:info("SCTP server listening on ~w:~w", [BindAddr, BindPort]), + ok = gen_sctp:listen(Sock, true), + {ok, #server_state{sock = Sock, + clients = dict:new()}}. + + +handle_call(Info, _From, State) -> + error_logger:error_report(["unknown handle_call()", + {module, ?MODULE}, {info, Info}, {state, State}]), + {reply, error, not_implemented}. + + +handle_cast({send_data, Aid, Data}, State) -> + gen_sctp:send(State#server_state.sock, + #sctp_sndrcvinfo{stream = ?SCTP_STREAM, + ppid = ?S1AP_PPID, + assoc_id = Aid}, Data), + {noreply, State}; + +handle_cast(Info, State) -> + error_logger:error_report(["unknown handle_cast()", + {module, ?MODULE}, {info, Info}, {state, State}]), + {noreply, State}. + + +%% Handle SCTP events coming from gen_sctp module +handle_info({sctp, _Socket, FromAddr, FromPort, {AncData, Data}}, State) -> + NewState = sctp_recv(State, {FromAddr, FromPort, AncData, Data}), + {noreply, NewState}; + +%% Handle termination events of the child processes +handle_info({'EXIT', Pid, Reason}, + #server_state{sock = Sock, clients = Clients} = State) -> + logger:debug("Child process ~p terminated with reason ~p", [Pid, Reason]), + case client_find(State, Pid) of + {ok, {Aid, _Client}} -> + %% gracefully close the eNB connection + gen_sctp:eof(Sock, #sctp_assoc_change{assoc_id = Aid}), + {noreply, State#server_state{clients = dict:erase(Aid, Clients)}}; + error -> + {noreply, State} + end; + +%% Catch-all for unknown messages +handle_info(Info, State) -> + error_logger:error_report(["unknown handle_info()", + {module, ?MODULE}, {info, Info}, {state, State}]), + {noreply, State}. + + +terminate(shutdown, State) -> + logger:notice("Terminating ~p", [?MODULE]), + close_conns(State), + gen_sctp:close(State#server_state.sock), + ok. + +%% ------------------------------------------------------------------ +%% private API +%% ------------------------------------------------------------------ + +%% Handle an #sctp_assoc_change event (connection state) +sctp_recv(State, {FromAddr, FromPort, [], + #sctp_assoc_change{state = ConnState, + assoc_id = Aid}}) -> + case ConnState of + comm_up -> + logger:notice("Connection (id=~p, ~p:~p) established", [Aid, FromAddr, FromPort]), + Clients = client_add(State#server_state.clients, Aid, FromAddr, FromPort); + shutdown_comp -> + logger:notice("Connection (id=~p, ~p:~p) closed", [Aid, FromAddr, FromPort]), + Clients = client_del(State#server_state.clients, Aid); + comm_lost -> + logger:notice("Connection (id=~p, ~p:~p) lost", [Aid, FromAddr, FromPort]), + Clients = client_del(State#server_state.clients, Aid); + _ -> + logger:notice("Connection (id=~p, ~p:~p) state ~p", + [Aid, FromAddr, FromPort, ConnState]), + Clients = State#server_state.clients + end, + State#server_state{clients = Clients}; + +%% Handle an #sctp_sndrcvinfo event (incoming data) +sctp_recv(State, {FromAddr, FromPort, + [#sctp_sndrcvinfo{assoc_id = Aid}], Data}) -> + logger:info("Connection (id=~p, ~p:~p) Rx ~p", [Aid, FromAddr, FromPort, Data]), + case dict:find(Aid, State#server_state.clients) of + {ok, #client_state{pid = Pid}} -> + sctp_proxy:send_data(Pid, Data); + error -> + logger:error("Connection (id=~p, ~p:~p) is not known to us?!?", + [Aid, FromAddr, FromPort]) + end, + State; + +%% Catch-all for other kinds of SCTP events +sctp_recv(State, {FromAddr, FromPort, AncData, Data}) -> + logger:debug("Unhandled SCTP event (~p:~p): ~p, ~p", + [FromAddr, FromPort, AncData, Data]), + State. + + +%% Add a new client to the list, spawning a proxy process +client_add(Clients, Aid, FromAddr, FromPort) -> + {ok, Pid} = sctp_proxy:start_link(Aid, {127,0,1,1}, ?S1AP_PORT), %% XXX! + NewClient = #client_state{addr_port = {FromAddr, FromPort}, pid = Pid}, + dict:store(Aid, NewClient, Clients). + + +%% Delete an existing client from the list, stopping the proxy process +client_del(Clients, Aid) -> + case dict:find(Aid, Clients) of + {ok, Client} -> + sctp_proxy:shutdown(Client#client_state.pid), + dict:erase(Aid, Clients); + error -> + Clients + end. + + +%% Find a client by process ID +client_find(#server_state{clients = Clients}, Pid) -> + client_find(dict:to_list(Clients), Pid); + +client_find([{Aid, Client} | Clients], Pid) -> + case Client of + #client_state{pid = Pid} -> + {ok, {Aid, Client}}; + _ -> + client_find(Clients, Pid) + end; + +client_find([], _Pid) -> + error. + + +%% Gracefully terminate client connections +close_conns(#server_state{sock = Sock, clients = Clients}) -> + close_conns(Sock, dict:to_list(Clients)). + +close_conns(Sock, [{Aid, Client} | Clients]) -> + {FromAddr, FromPort} = Client#client_state.addr_port, + logger:notice("Terminating connection (id=~p, ~p:~p)", [Aid, FromAddr, FromPort]), + %% request to terminate an MME connection + sctp_proxy:shutdown(Client#client_state.pid), + %% gracefully close an eNB connection + gen_sctp:eof(Sock, #sctp_assoc_change{assoc_id = Aid}), + %% ... and so for the remaining clients + close_conns(Sock, Clients); + +close_conns(_Sock, []) -> + ok. + +%% vim:set ts=4 sw=4 et: -- To view, visit
https://gerrit.osmocom.org/c/osmo-s1gw/+/37036?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-s1gw Gerrit-Branch: master Gerrit-Change-Id: Ia317f58f7dcbec42930165fdcd42d0ddd23e289c Gerrit-Change-Number: 37036 Gerrit-PatchSet: 1 Gerrit-Owner: osmith <osmith(a)sysmocom.de> Gerrit-Reviewer: osmith <osmith(a)sysmocom.de> Gerrit-CC: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-MessageType: merged
1 year
1
0
0
0
[M] Change in osmo-s1gw[master]: README.md: initial version
by osmith
osmith has posted comments on this change. (
https://gerrit.osmocom.org/c/osmo-s1gw/+/37053?usp=email
) Change subject: README.md: initial version ...................................................................... Patch Set 1: Verified+1 Code-Review+2 (1 comment) Patchset: PS1: merging the initial patches from
https://gitea.osmocom.org/fixeria/osmo-s1gw
-- To view, visit
https://gerrit.osmocom.org/c/osmo-s1gw/+/37053?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-s1gw Gerrit-Branch: master Gerrit-Change-Id: Ifed0146b1bf609756e967e7c6b9ed159d29dfbf0 Gerrit-Change-Number: 37053 Gerrit-PatchSet: 1 Gerrit-Owner: osmith <osmith(a)sysmocom.de> Gerrit-Reviewer: osmith <osmith(a)sysmocom.de> Gerrit-CC: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-Comment-Date: Wed, 05 Jun 2024 13:06:49 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: Yes Gerrit-MessageType: comment
1 year
1
0
0
0
← Newer
1
...
123
124
125
126
127
128
129
...
157
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
Results per page:
10
25
50
100
200