fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/39077?usp=email )
Change subject: s1gw: add TC_e_rab_modify & TC_e_rab_modify_multi ......................................................................
s1gw: add TC_e_rab_modify & TC_e_rab_modify_multi
Test the E-RAB Modify procedure (MME initiated), which is defined in 3GPP TS 36.413 section 8.2.2.
Change-Id: I58b9964bae24b5aac526ee0c0c8ac8798f351e05 --- M s1gw/S1GW_ConnHdlr.ttcn M s1gw/S1GW_Tests.ttcn M s1gw/expected-results.xml 3 files changed, 217 insertions(+), 1 deletion(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks refs/changes/77/39077/1
diff --git a/s1gw/S1GW_ConnHdlr.ttcn b/s1gw/S1GW_ConnHdlr.ttcn index 4634064..c1c1701 100644 --- a/s1gw/S1GW_ConnHdlr.ttcn +++ b/s1gw/S1GW_ConnHdlr.ttcn @@ -281,6 +281,7 @@ }
/* 256 is maxnoofE-RABs (see S1AP_Constants.asn) */ +type record length(0..256) of E_RAB_ID ERabIdList; type record length(1..256) of ERab ERabList; type record ERab { E_RAB_ID erab_id, /* ::= INTEGER (0..15, ...) */ @@ -288,6 +289,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 }; @@ -390,6 +392,129 @@ 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 ERabIdList erabs_modified, + in ERabIdList 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; + + item := ts_E_RABModifyItemBearerModRes(erabs_modified[i]); + 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; + + item := ts_E_RABItem(erabs_failed[i]); + 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 ERabIdList erabs_modified, + in ERabIdList erabs_failed) +runs on ConnHdlr return S1AP_PDU { + var template (present) E_RABModifyListBearerModRes items_modified; + var template E_RABList items_failed; + 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; + + item := tr_E_RABModifyItemBearerModRes(erabs_modified[i]); + 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; + + item := tr_E_RABItem(erabs_failed[i]); + 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 { @@ -791,6 +916,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 := 2); /* Access -> Core */ + 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 ERabIdList erabs_modified, + in ERabIdList 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 E_RAB_ID erab_id := erabs_modified[i]; + g_pars.erabs[erab_id].u2c := g_pars.erabs[erab_id].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 E_RAB_ID erab_id := erabs_failed[i]; + var ERab erab := g_pars.erabs[erab_id]; + + log("UPF <- S1GW: PFCP Session Modification Request for E-RAB ID ", erab_id); + var PDU_PFCP pdu := f_ConnHdlr_rx_session_modify_req(epars := erab.u2c, + seid := erab.pfcp_loc_seid, + far_id := 2); /* Access -> Core */ + log("UPF -> S1GW: PFCP Session Modification Response for E-RAB ID ", 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 729bc77..9cd1e6a 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 */ }; @@ -427,6 +428,49 @@ vc_conn.done; }
+/* Test E-RAB MODIFY Req/Rsp procedure */ +function f_TC_e_rab_modify(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); +} +private function TC_e_rab_modify_exec(integer num_enbs) +runs on test_CT { + var ConnHdlrList vc_conns; + + f_init(); + + for (var integer i := 0; i < num_enbs; i := i + 1) { + var ConnHdlrPars pars := valueof(t_ConnHdlrPars(i, num_erabs := 4)); + vc_conns[i] := f_ConnHdlr_spawn(refers(f_TC_e_rab_modify), pars); + } + + f_ConnHdlrList_all_done(vc_conns); +} +/* 4 E-RABs at a time, single eNB */ +testcase TC_e_rab_modify() runs on test_CT { + TC_e_rab_modify_exec(num_enbs := 1); +} +/* 4 E-RABs at a time, multiple eNB connections */ +testcase TC_e_rab_modify_multi() runs on test_CT { + TC_e_rab_modify_exec(num_enbs := mp_multi_enb_num); +} + /* 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); @@ -545,6 +589,8 @@ execute( TC_e_rab_setup3_multi() ); execute( TC_e_rab_release_ind() ); execute( TC_e_rab_setup_failure() ); + execute( TC_e_rab_modify() ); + execute( TC_e_rab_modify_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 c6995c9..34d98a8 100644 --- a/s1gw/expected-results.xml +++ b/s1gw/expected-results.xml @@ -1,5 +1,5 @@ <?xml version="1.0"?> -<testsuite name='S1GW_Tests' tests='16' failures='0' errors='0' skipped='0' inconc='0' time='MASKED'> +<testsuite name='S1GW_Tests' tests='17' 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' time='MASKED'/> + <testcase classname='S1GW_Tests' name='TC_e_rab_modify_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'/>