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]>

Reply via email to