fixeria has uploaded this change for review. (
https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41762?usp=email )
Change subject: s1ap_utils: add API for building S1 SETUP FAILURE PDU
......................................................................
s1ap_utils: add API for building S1 SETUP FAILURE PDU
This API will be used in a follow-up patch adding the MME pooling.
Take a chance to add a parsing test for the new PDU blob.
Change-Id: I5a4e060e0a2ebdfbcfafac42f9de2e49ac3583b8
Related: SYS#7052
---
M src/s1ap_utils.erl
M test/s1ap_samples.erl
M test/s1ap_utils_test.erl
3 files changed, 89 insertions(+), 2 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-s1gw
refs/changes/62/41762/1
diff --git a/src/s1ap_utils.erl b/src/s1ap_utils.erl
index 6f7e6b6..2ecd0bf 100644
--- a/src/s1ap_utils.erl
+++ b/src/s1ap_utils.erl
@@ -40,6 +40,8 @@
parse_plmn_id/1,
parse_enb_id/1,
genb_id_str/1]).
+-export([build_pdu/1,
+ build_s1setup_fail_pdu/1]).
-include_lib("kernel/include/logger.hrl").
@@ -120,6 +122,34 @@
MCC ++ "-" ++ MNC ++ "-" ++ integer_to_list(ENBId).
+%% Build an S1AP PDU
+-spec build_pdu(s1ap_pdu_info()) -> {ok, binary()} | {error, term()}.
+build_pdu({MsgType, Content}) ->
+ case build_pdu(MsgType, Content) of
+ {error, Error} ->
+ ?LOG_ERROR("Failed to build an S1AP PDU: ~p", [Error]),
+ {error, {build_pdu, Error}};
+ PDU ->
+ try encode_pdu(PDU) of
+ {ok, Data} ->
+ {ok, Data};
+ {error, Error} ->
+ ?LOG_ERROR("S1AP PDU encoding failed: ~p", [Error]),
+ {error, {encode_pdu, Error}}
+ catch
+ Exception:Reason:StackTrace ->
+ ?LOG_ERROR("An exception occurred: ~p, ~p, ~p",
[Exception, Reason, StackTrace]),
+ {error, encode_pdu}
+ end
+ end.
+
+
+%% Build an S1AP S1 SETUP FAILURE PDU
+-spec build_s1setup_fail_pdu(proplists:proplist()) -> {ok, binary()} | {error,
term()}.
+build_s1setup_fail_pdu(Content) ->
+ build_pdu({{?'id-S1Setup', unsuccessfulOutcome}, Content}).
+
+
%% ------------------------------------------------------------------
%% private API
%% ------------------------------------------------------------------
@@ -207,4 +237,28 @@
lists:map(fun parse_ie/1, IEs).
+-spec build_pdu(MsgType, Content) -> s1ap_pdu() | {error, term()}
+ when MsgType :: s1ap_msg_type(),
+ Content :: proplists:proplist().
+build_pdu({?'id-S1Setup' = PC,
+ unsuccessfulOutcome = Outcome}, Content) ->
+ Cause = proplists:get_value(?'id-Cause', Content, {misc, unspecified}),
+ TimeToWait = proplists:get_value(?'id-TimeToWait', Content, v10s),
+ IEs = [#'ProtocolIE-Field'{id = ?'id-Cause',
+ criticality = ignore,
+ value = Cause},
+ #'ProtocolIE-Field'{id = ?'id-TimeToWait',
+ criticality = ignore,
+ value = TimeToWait}],
+ {Outcome,
+ #'UnsuccessfulOutcome'{procedureCode = PC,
+ criticality = reject,
+ value = #'S1SetupFailure'{protocolIEs = IEs}}};
+
+
+build_pdu(MsgType, _Content) ->
+ ?LOG_ERROR("~p(~p): not implemented", [?FUNCTION_NAME, MsgType]),
+ {error, not_implemented}.
+
+
%% vim:set ts=4 sw=4 et:
diff --git a/test/s1ap_samples.erl b/test/s1ap_samples.erl
index e3c3ac1..183aad6 100644
--- a/test/s1ap_samples.erl
+++ b/test/s1ap_samples.erl
@@ -2,6 +2,7 @@
-export([s1_setup_req_pdu/0,
s1_setup_rsp_pdu/0,
+ s1_setup_fail_pdu/0,
e_rab_setup_req_pdu/2,
e_rab_setup_rsp_pdu/2,
e_rab_setup_rsp_fail_pdu/0,
@@ -48,6 +49,14 @@
>>.
+%% S1 SETUP FAILURE
+s1_setup_fail_pdu() ->
+ << 16#40, 16#11, 16#00, 16#0d, 16#00, 16#00, 16#02, 16#00,
+ 16#02, 16#40, 16#01, 16#44, 16#00, 16#41, 16#40, 16#01,
+ 16#30
+ >>.
+
+
%% [eNB <- MME] E-RAB SETUP REQUEST
e_rab_setup_req_pdu(TLA, TEID) when is_binary(TLA),
is_integer(TEID) ->
diff --git a/test/s1ap_utils_test.erl b/test/s1ap_utils_test.erl
index ca63606..9285da8 100644
--- a/test/s1ap_utils_test.erl
+++ b/test/s1ap_utils_test.erl
@@ -16,7 +16,7 @@
%% actual testcases
%% ------------------------------------------------------------------
-s1ap_setup_req_test_() ->
+s1ap_setup_req_parse_test_() ->
{MsgType, IEs} = s1ap_utils:parse_pdu(s1ap_samples:s1_setup_req_pdu()),
[?_assertEqual({?'id-S1Setup', initiatingMessage}, MsgType),
?_assertEqualIE(?'id-Global-ENB-ID', #{enb_id => 0,
@@ -25,7 +25,7 @@
?_assertMatchIE(?'id-SupportedTAs', [12345])]. %% we only parse the TACs
-s1ap_setup_rsp_test_() ->
+s1ap_setup_rsp_parse_test_() ->
{MsgType, IEs} = s1ap_utils:parse_pdu(s1ap_samples:s1_setup_rsp_pdu()),
[?_assertEqual({?'id-S1Setup', successfulOutcome}, MsgType),
?_assertEqualIE(?'id-MMEname', "open5gs-mme0"),
@@ -33,4 +33,28 @@
?_assertEqualIE(?'id-RelativeMMECapacity', 16#ff)].
+s1ap_setup_fail_parse_test_() ->
+ {MsgType, IEs} = s1ap_utils:parse_pdu(s1ap_samples:s1_setup_fail_pdu()),
+ [?_assertEqual({?'id-S1Setup', unsuccessfulOutcome}, MsgType),
+ ?_assertEqualIE(?'id-Cause', {misc, unspecified}),
+ ?_assertEqualIE(?'id-TimeToWait', v10s)].
+
+
+s1ap_setup_fail_build_test_() ->
+ [?_assertEqual({ok, s1ap_samples:s1_setup_fail_pdu()},
+ s1ap_utils:build_s1setup_fail_pdu([]))].
+
+
+build_pdu_error_test_() ->
+ TraceStartReq = {{?'id-TraceStart', initiatingMessage}, []},
+ S1SetupFailure = {{?'id-S1Setup', unsuccessfulOutcome},
+ [{?'id-TimeToWait', 42}]}, %% wrong value
+ [%% test building a non-implemented PDU
+ ?_assertEqual({error, {build_pdu, not_implemented}},
+ s1ap_utils:build_pdu(TraceStartReq)),
+ %% test building a PDU with a wrong user-supplied IE
+ ?_assertMatch({error, {encode_pdu, {asn1, _}}},
+ s1ap_utils:build_pdu(S1SetupFailure))].
+
+
%% vim:set ts=4 sw=4 et:
--
To view, visit https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41762?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: I5a4e060e0a2ebdfbcfafac42f9de2e49ac3583b8
Gerrit-Change-Number: 41762
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <[email protected]>