fixeria has submitted this change. ( 
https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/39077?usp=email )

Change subject: s1gw: add TC_e_rab_modify_req_rsp[_multi]
......................................................................

s1gw: add TC_e_rab_modify_req_rsp[_multi]

Test the E-RAB Modify procedure (MME initiated), which is defined
in 3GPP TS 36.413 section 8.2.2.

Change-Id: I58b9964bae24b5aac526ee0c0c8ac8798f351e05
Related: osmo-s1gw.git I24d57ea390d71b640cb42046a8658e9d30670682
Related: osmo-s1gw.git I057a1c58d0c6ad04c00ad3ea4c68230d8632a07e
Related: SYS#7308
---
M s1gw/S1GW_ConnHdlr.ttcn
M s1gw/S1GW_Tests.ttcn
M s1gw/expected-results.xml
3 files changed, 210 insertions(+), 1 deletion(-)

Approvals:
  pespin: Looks good to me, approved
  osmith: Looks good to me, but someone else must approve
  Jenkins Builder: Verified




diff --git a/s1gw/S1GW_ConnHdlr.ttcn b/s1gw/S1GW_ConnHdlr.ttcn
index 3f79e47..f5ff588 100644
--- a/s1gw/S1GW_ConnHdlr.ttcn
+++ b/s1gw/S1GW_ConnHdlr.ttcn
@@ -280,6 +280,9 @@
        setverdict(pass);
 }

+type integer ERabIdx (0..255);
+type record of ERabIdx ERabIdxList;
+
 /* 256 is maxnoofE-RABs (see S1AP_Constants.asn) */
 type record length(1..256) of ERab ERabList;
 type record ERab {
@@ -288,6 +291,7 @@
        ERabParams c2u,         /* Core -> UPF params */
        ERabParams a2u,         /* Access -> UPF params */
        ERabParams u2a,         /* UPF -> Access params */
+       ERabParams u2cm,        /* UPF -> Core params (modified) */
        OCT8 pfcp_loc_seid,
        OCT8 pfcp_rem_seid optional
 };
@@ -407,6 +411,133 @@
        return pdu;
 }

+function f_ConnHdlr_tx_erab_modify_req(in ERabList erabs,
+                                      boolean transport_info := true)
+runs on ConnHdlr {
+       var template (value) E_RABToBeModifiedListBearerModReq items;
+       var template (value) E_RABLevelQoSParameters qos_params;
+       var ENB_UE_S1AP_ID enb_ue_id := g_pars.idx;
+
+       qos_params := valueof(ts_E_RABLevelQoSParameters);
+
+       for (var integer i := 0; i < lengthof(erabs); i := i + 1) {
+               var template (value) E_RABToBeModifiedItemBearerModReq item;
+
+               if (transport_info) {
+                       var template (value) TransportLayerAddress tla;
+                       var ERabParams epars := erabs[i].u2cm;
+
+                       tla := oct2bit(f_inet_addr(epars.tla));
+                       item := ts_E_RABToBeModifiedItemBearerModReqExt(rab_id 
:= erabs[i].erab_id,
+                                                                       
qos_params := qos_params,
+                                                                       nas_pdu 
:= ''O,
+                                                                       tla := 
tla,
+                                                                       
gtp_teid := epars.teid);
+               } else {
+                       item := ts_E_RABToBeModifiedItemBearerModReq(rab_id := 
erabs[i].erab_id,
+                                                                    qos_params 
:= qos_params,
+                                                                    nas_pdu := 
''O);
+               }
+
+               items[i] := ts_E_RABToBeModifiedListBearerModReq(item)[0];
+       }
+
+       f_ConnHdlr_tx_s1ap_from_mme(ts_S1AP_RABModifyReq(g_pars.mme_ue_id, 
enb_ue_id,
+                                                        rab_modify_items := 
items));
+}
+
+function f_ConnHdlr_rx_erab_modify_req(in ERabList erabs,
+                                      boolean transport_info := true)
+runs on ConnHdlr return S1AP_PDU {
+       var template (present) E_RABToBeModifiedListBearerModReq items;
+       var ENB_UE_S1AP_ID enb_ue_id := g_pars.idx;
+       var S1AP_PDU pdu;
+
+       for (var integer i := 0; i < lengthof(erabs); i := i + 1) {
+               var template (present) E_RABToBeModifiedItemBearerModReq item;
+
+               if (transport_info) {
+                       var template (present) TransportLayerAddress tla;
+                       var ERabParams epars := erabs[i].a2u;
+
+                       tla := oct2bit(f_inet_addr(epars.tla));
+                       item := tr_E_RABToBeModifiedItemBearerModReqExt(rab_id 
:= erabs[i].erab_id,
+                                                                       
qos_params := ?,
+                                                                       nas_pdu 
:= ''O,
+                                                                       tla := 
tla,
+                                                                       
gtp_teid := epars.teid);
+               } else {
+                       item := tr_E_RABToBeModifiedItemBearerModReq(rab_id := 
erabs[i].erab_id,
+                                                                    qos_params 
:= ?,
+                                                                    nas_pdu := 
''O);
+               }
+
+               items[i] := tr_E_RABToBeModifiedListBearerModReq(item)[0];
+       }
+
+       f_ConnHdlr_rx_s1ap_from_mme(pdu, tr_S1AP_RABModifyReq(g_pars.mme_ue_id, 
enb_ue_id,
+                                                             rab_modify_items 
:= items));
+       return pdu;
+}
+
+function f_ConnHdlr_tx_erab_modify_rsp(in ERabIdxList erabs_modified,
+                                      in ERabIdxList erabs_failed := {})
+runs on ConnHdlr {
+       var template (value) E_RABModifyListBearerModRes items_modified;
+       var template (omit) E_RABList items_failed := omit;
+       var ENB_UE_S1AP_ID enb_ue_id := g_pars.idx;
+
+       for (var integer i := 0; i < lengthof(erabs_modified); i := i + 1) {
+               var template (value) E_RABModifyItemBearerModRes item;
+               var ERabIdx idx := erabs_modified[i];
+
+               item := 
ts_E_RABModifyItemBearerModRes(g_pars.erabs[idx].erab_id);
+               items_modified[i] := ts_E_RABModifyListBearerModRes(item)[0];
+       }
+
+       for (var integer i := 0; i < lengthof(erabs_failed); i := i + 1) {
+               var template (value) E_RABItem item;
+               var ERabIdx idx := erabs_failed[i];
+
+               item := ts_E_RABItem(g_pars.erabs[idx].erab_id);
+               items_failed[i] := ts_E_RABList(item)[0];
+       }
+
+       f_ConnHdlr_tx_s1ap_from_enb(ts_S1AP_RABModifyRsp(g_pars.mme_ue_id, 
enb_ue_id,
+                                                        rab_modified_items := 
items_modified,
+                                                        rab_failed_items := 
items_failed));
+}
+
+function f_ConnHdlr_rx_erab_modify_rsp(in ERabIdxList erabs_modified,
+                                      in ERabIdxList erabs_failed := {})
+runs on ConnHdlr return S1AP_PDU {
+       var template (present) E_RABModifyListBearerModRes items_modified;
+       var template E_RABList items_failed := omit;
+       var ENB_UE_S1AP_ID enb_ue_id := g_pars.idx;
+       var S1AP_PDU pdu;
+
+       for (var integer i := 0; i < lengthof(erabs_modified); i := i + 1) {
+               var template (present) E_RABModifyItemBearerModRes item;
+               var ERabIdx idx := erabs_modified[i];
+
+               item := 
tr_E_RABModifyItemBearerModRes(g_pars.erabs[idx].erab_id);
+               items_modified[i] := tr_E_RABModifyListBearerModRes(item)[0];
+       }
+
+       for (var integer i := 0; i < lengthof(erabs_failed); i := i + 1) {
+               var template (present) E_RABItem item;
+               var ERabIdx idx := erabs_failed[i];
+
+               item := tr_E_RABItem(g_pars.erabs[idx].erab_id);
+               items_failed[i] := tr_E_RABList(item)[0];
+       }
+
+       f_ConnHdlr_rx_s1ap_from_enb(pdu, tr_S1AP_RABModifyRsp(g_pars.mme_ue_id, 
enb_ue_id,
+                                                             
rab_modified_items := items_modified,
+                                                             rab_failed_items 
:= items_failed));
+       return pdu;
+}
+
 private function f_ts_E_RABList(in ERabList erabs,
                                S1AP_IEs.Cause cause)
 return template (value) E_RABList {
@@ -822,6 +953,49 @@
        f_ConnHdlr_rx_erab_setup_rsp(erabs);
 }

+function f_ConnHdlr_erab_modify_req(in ERabList erabs)
+runs on ConnHdlr {
+       log("eNB <- [S1GW <- MME]: E-RAB MODIFY REQUEST");
+       f_ConnHdlr_tx_erab_modify_req(erabs);
+       /* Expect the S1GW to modify FARs (id=2) of the respective PFCP 
sessions */
+       for (var integer i := 0; i < lengthof(erabs); i := i + 1) {
+               log("UPF <- S1GW: PFCP Session Modification Request for E-RAB 
ID ", erabs[i].erab_id);
+               var PDU_PFCP pdu := f_ConnHdlr_rx_session_modify_req(epars := 
erabs[i].u2cm,
+                                                                    seid := 
erabs[i].pfcp_loc_seid,
+                                                                    far_id := 
c_PFCP_FAR_ID_A2C);
+               log("UPF -> S1GW: PFCP Session Modification Response for E-RAB 
ID ", erabs[i].erab_id);
+               f_ConnHdlr_tx_session_modify_resp(erabs[i], pdu);
+       }
+       log("[eNB <- S1GW] <- MME: E-RAB MODIFY REQUEST");
+       f_ConnHdlr_rx_erab_modify_req(erabs);
+}
+
+function f_ConnHdlr_erab_modify_rsp(in ERabIdxList erabs_modified,
+                                   in ERabIdxList erabs_failed)
+runs on ConnHdlr {
+       log("[eNB -> S1GW] -> MME: E-RAB MODIFY RESPONSE");
+       f_ConnHdlr_tx_erab_modify_rsp(erabs_modified, erabs_failed);
+       /* For successfully modified E-RABs, U2CM becomes U2C */
+       for (var integer i := 0; i < lengthof(erabs_modified); i := i + 1) {
+               var ERabIdx idx := erabs_modified[i];
+               g_pars.erabs[idx].u2c := g_pars.erabs[idx].u2cm;
+       }
+       /* Expect the S1GW to modify (revert) FARs (id=2) for failed E-RABs */
+       for (var integer i := 0; i < lengthof(erabs_failed); i := i + 1) {
+               var ERabIdx idx := erabs_failed[i];
+               var ERab erab := g_pars.erabs[idx];
+
+               log("UPF <- S1GW: PFCP Session Modification Request for E-RAB 
ID ", erab.erab_id);
+               var PDU_PFCP pdu := f_ConnHdlr_rx_session_modify_req(epars := 
erab.u2c,
+                                                                    seid := 
erab.pfcp_loc_seid,
+                                                                    far_id := 
c_PFCP_FAR_ID_A2C);
+               log("UPF -> S1GW: PFCP Session Modification Response for E-RAB 
ID ", erab.erab_id);
+               f_ConnHdlr_tx_session_modify_resp(erab, pdu);
+       }
+       log("eNB -> [S1GW -> MME]: E-RAB MODIFY RESPONSE");
+       f_ConnHdlr_rx_erab_modify_rsp(erabs_modified, erabs_failed);
+}
+
 function f_ConnHdlr_erab_release_cmd(inout ERabList erabs,
                                     S1AP_IEs.Cause cause := c_REL_CMD_CAUSE)
 runs on ConnHdlr {
diff --git a/s1gw/S1GW_Tests.ttcn b/s1gw/S1GW_Tests.ttcn
index 8bb2f09..2533fd6 100644
--- a/s1gw/S1GW_Tests.ttcn
+++ b/s1gw/S1GW_Tests.ttcn
@@ -158,6 +158,7 @@
                        c2u := {'0101'O & uid, "127.0.1.1"},
                        a2u := {'0202'O & uid, "127.0.2.2"},
                        u2a := {'0002'O & uid, "127.0.0.2"},
+                       u2cm := {'0011'O & uid, "127.127.0.1"},
                        pfcp_loc_seid := seid_prefix & uid,
                        pfcp_rem_seid := omit /* assigned by S1GW */
                };
@@ -403,6 +404,36 @@
        f_TC_exec(refers(f_TC_e_rab_setup_failure));
 }

+/* Test E-RAB MODIFY Req/Rsp procedure */
+function f_TC_e_rab_modify_req_rsp(charstring id) runs on ConnHdlr {
+       f_ConnHdlr_s1ap_register(g_pars.genb_id);
+       f_ConnHdlr_s1ap_connect(mp_enb_bind_ip, mp_s1gw_enb_ip);
+       f_ConnHdlr_s1ap_setup(g_pars.genb_id);
+
+       f_ConnHdlr_erab_setup_req(g_pars.erabs);
+       f_ConnHdlr_erab_setup_rsp(g_pars.erabs);
+
+       /* MME orders eNB to modify all 4 E-RABs */
+       f_ConnHdlr_erab_modify_req(g_pars.erabs);
+       /* eNB modifies E-RABs 1 and 3, but not E-RAB 0 and 2 */
+       f_ConnHdlr_erab_modify_rsp(erabs_modified := {1, 3},
+                                  erabs_failed := {0, 2});
+
+       f_ConnHdlr_erab_release_cmd(g_pars.erabs);
+       f_ConnHdlr_erab_release_rsp(g_pars.erabs);
+
+       f_ConnHdlr_s1ap_disconnect();
+       f_ConnHdlr_s1ap_unregister(g_pars.genb_id);
+}
+/* 4 E-RABs at a time, single eNB */
+testcase TC_e_rab_modify_req_rsp() runs on test_CT {
+       f_TC_exec(refers(f_TC_e_rab_modify_req_rsp), 1, 4);
+}
+/* 4 E-RABs at a time, multiple eNB connections */
+testcase TC_e_rab_modify_req_rsp_multi() runs on test_CT {
+       f_TC_exec(refers(f_TC_e_rab_modify_req_rsp), mp_multi_enb_num, 4);
+}
+
 /* Test INITIAL CONTEXT SETUP procedure (successful case) */
 function f_TC_initial_ctx_setup(charstring id) runs on ConnHdlr {
        f_ConnHdlr_s1ap_register(g_pars.genb_id);
@@ -538,6 +569,8 @@
        execute( TC_e_rab_setup3_multi() );
        execute( TC_e_rab_release_ind() );
        execute( TC_e_rab_setup_failure() );
+       execute( TC_e_rab_modify_req_rsp() );
+       execute( TC_e_rab_modify_req_rsp_multi() );
        execute( TC_initial_ctx_setup() );
        execute( TC_initial_ctx_setup3() );
        execute( TC_initial_ctx_setup_multi() );
diff --git a/s1gw/expected-results.xml b/s1gw/expected-results.xml
index c5cb28f..a4e6e02 100644
--- a/s1gw/expected-results.xml
+++ b/s1gw/expected-results.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<testsuite name='S1GW_Tests' tests='20' failures='0' errors='0' skipped='0' 
inconc='0' time='MASKED'>
+<testsuite name='S1GW_Tests' tests='22' failures='0' errors='0' skipped='0' 
inconc='0' time='MASKED'>
   <testcase classname='S1GW_Tests' name='TC_setup' time='MASKED'/>
   <testcase classname='S1GW_Tests' name='TC_setup_multi' time='MASKED'/>
   <testcase classname='S1GW_Tests' name='TC_conn_term_by_mme' time='MASKED'/>
@@ -10,6 +10,8 @@
   <testcase classname='S1GW_Tests' name='TC_e_rab_setup3_multi' time='MASKED'/>
   <testcase classname='S1GW_Tests' name='TC_e_rab_release_ind' time='MASKED'/>
   <testcase classname='S1GW_Tests' name='TC_e_rab_setup_failure' 
time='MASKED'/>
+  <testcase classname='S1GW_Tests' name='TC_e_rab_modify_req_rsp' 
time='MASKED'/>
+  <testcase classname='S1GW_Tests' name='TC_e_rab_modify_req_rsp_multi' 
time='MASKED'/>
   <testcase classname='S1GW_Tests' name='TC_initial_ctx_setup' time='MASKED'/>
   <testcase classname='S1GW_Tests' name='TC_initial_ctx_setup3' time='MASKED'/>
   <testcase classname='S1GW_Tests' name='TC_initial_ctx_setup_multi' 
time='MASKED'/>

--
To view, visit https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/39077?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings?usp=email

Gerrit-MessageType: merged
Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-Change-Id: I58b9964bae24b5aac526ee0c0c8ac8798f351e05
Gerrit-Change-Number: 39077
Gerrit-PatchSet: 8
Gerrit-Owner: fixeria <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <[email protected]>
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-Reviewer: osmith <[email protected]>
Gerrit-Reviewer: pespin <[email protected]>

Reply via email to