fixeria submitted this change.

View Change

Approvals: pespin: Looks good to me, but someone else must approve fixeria: Looks good to me, approved laforge: Looks good to me, but someone else must approve Jenkins Builder: Verified
s1gw: add testcases for INITIAL CONTEXT SETUP

Change-Id: I72e3ab932fee1de0fce8ddf4041b8f2174416bc1
---
M s1gw/S1GW_ConnHdlr.ttcn
M s1gw/S1GW_Tests.ttcn
M s1gw/expected-results.xml
3 files changed, 192 insertions(+), 1 deletion(-)

diff --git a/s1gw/S1GW_ConnHdlr.ttcn b/s1gw/S1GW_ConnHdlr.ttcn
index 97df4c0..775f44c 100644
--- a/s1gw/S1GW_ConnHdlr.ttcn
+++ b/s1gw/S1GW_ConnHdlr.ttcn
@@ -501,6 +501,110 @@
return pdu;
}

+function f_ConnHdlr_tx_initial_ctx_setup_req(in ERabList erabs,
+ MME_UE_S1AP_ID mme_ue_id := c_MME_UE_ID)
+runs on ConnHdlr {
+ var template (value) E_RABToBeSetupListCtxtSUReq 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_RABToBeSetupItemCtxtSUReq item;
+ var template (value) TransportLayerAddress tla;
+ var ERabParams epars := erabs[i].u2c;
+
+ tla := oct2bit(f_inet_addr(epars.tla));
+ item := ts_E_RABToBeSetupItemCtxtSUReq(rab_id := erabs[i].erab_id,
+ qos_params := qos_params,
+ tla := tla,
+ gtp_teid := epars.teid,
+ nas_pdu := omit);
+ items[i] := ts_E_RABToBeSetupListCtxtSUReq(item)[0];
+ }
+
+ f_ConnHdlr_tx_s1ap_from_mme(ts_S1AP_IntialCtxSetupReq(mme_id := mme_ue_id,
+ enb_id := enb_ue_id,
+ max_br := ts_UEAggregateMaximumBitrate,
+ rab_setup_items := items,
+ ue_sec_par := ts_UESecurityCapabilities,
+ sec_key := f_rnd_bitstring(256)));
+}
+
+function f_ConnHdlr_rx_initial_ctx_setup_req(in ERabList erabs,
+ MME_UE_S1AP_ID mme_ue_id := c_MME_UE_ID)
+runs on ConnHdlr return S1AP_PDU {
+ var template (present) E_RABToBeSetupListCtxtSUReq 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_RABToBeSetupItemCtxtSUReq item;
+ var template (present) TransportLayerAddress tla;
+ var ERabParams epars := erabs[i].a2u;
+
+ tla := oct2bit(f_inet_addr(epars.tla));
+ item := tr_E_RABToBeSetupItemCtxtSUReq(rab_id := erabs[i].erab_id,
+ qos_params := ?,
+ tla := tla,
+ gtp_teid := epars.teid,
+ nas_pdu := omit);
+ items[i] := tr_E_RABToBeSetupListCtxtSUReq(item)[0];
+ }
+
+ f_ConnHdlr_rx_s1ap_from_mme(pdu, tr_S1AP_IntialCtxSetupReq(mme_id := mme_ue_id,
+ enb_id := enb_ue_id,
+ max_br := tr_UEAggregateMaximumBitrate,
+ rab_setup_items := items,
+ ue_sec_par := tr_UESecurityCapabilities));
+ return pdu;
+}
+
+function f_ConnHdlr_tx_initial_ctx_setup_rsp(in ERabList erabs,
+ MME_UE_S1AP_ID mme_ue_id := c_MME_UE_ID)
+runs on ConnHdlr {
+ var template (value) E_RABSetupListCtxtSURes items;
+ var ENB_UE_S1AP_ID enb_ue_id := g_pars.idx;
+
+ for (var integer i := 0; i < lengthof(erabs); i := i + 1) {
+ var template (value) E_RABSetupItemCtxtSURes item;
+ var template (value) TransportLayerAddress tla;
+ var ERabParams epars := erabs[i].u2a;
+
+ tla := oct2bit(f_inet_addr(epars.tla));
+ item := ts_S1AP_RABSetupItemCtxtSURes(rab_id := erabs[i].erab_id,
+ tla := tla,
+ gtp_teid := epars.teid);
+ items[i] := ts_S1AP_RABSetupListCtxtSURes(item)[0];
+ }
+
+ f_ConnHdlr_tx_s1ap_from_enb(ts_S1AP_InitialCtxSetupResp(mme_ue_id, enb_ue_id, items));
+}
+
+function f_ConnHdlr_rx_initial_ctx_setup_rsp(in ERabList erabs,
+ MME_UE_S1AP_ID mme_ue_id := c_MME_UE_ID)
+runs on ConnHdlr return S1AP_PDU {
+ var template (present) E_RABSetupListCtxtSURes 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_RABSetupItemCtxtSURes item;
+ var template (present) TransportLayerAddress tla;
+ var ERabParams epars := erabs[i].c2u;
+
+ tla := oct2bit(f_inet_addr(epars.tla));
+ item := tr_S1AP_RABSetupItemCtxtSURes(rab_id := erabs[i].erab_id,
+ tla := tla,
+ gtp_teid := epars.teid);
+ items[i] := tr_S1AP_RABSetupListCtxtSURes(item)[0];
+ }
+
+ f_ConnHdlr_rx_s1ap_from_enb(pdu, tr_S1AP_InitialCtxSetupResp(mme_ue_id, enb_ue_id, items));
+ return pdu;
+}
+
function f_ConnHdlr_rx_session_establish_req(in ERab erab)
runs on ConnHdlr return PDU_PFCP {
var OCT4 addr := f_inet_addr(g_pars.pfcp_rem_addr);
@@ -725,4 +829,41 @@
f_ConnHdlr_rx_erab_release_ind(erabs, cause);
}

+function f_ConnHdlr_initial_ctx_setup_req(inout ERabList erabs)
+runs on ConnHdlr {
+ const OCT8 c_SEID0 := '0000000000000000'O;
+
+ /* This code block cannot be executed by more than one component at a time because
+ * the S1AP E-RAB SETUP REQUEST triggers the IUT to send PFCP Session Establishment
+ * Request PDU(s), with need to be routed to the respective ConnHdlr component (us).
+ * As per 3GPP TS 29.244, section 7.2.2.4.2, these PFCP PDUs shall all have SEID=0,
+ * so that the PFCPEM component cannot route them unambiguously. This is why we
+ * need to ensure that only one ConnHdlr is triggering PFCP session establishment
+ * at the given moment of time. */
+ f_Mutex_lock(__BFILE__, __LINE__);
+ f_PFCPEM_subscribe_seid(c_SEID0);
+
+ log("eNB <- [S1GW <- MME]: INITIAL CONTEXT SETUP REQUEST");
+ f_ConnHdlr_tx_initial_ctx_setup_req(erabs);
+ f_ConnHdlr_session_establish(erabs);
+
+ /* We're done establishing PFCP sessions, so at this point we no longer expect to
+ * receive Session Establishment Request PDUs with SEID=0. Unregister and unlock
+ * the mutex, enabling other components to establish PFCP sessions after us. */
+ f_PFCPEM_unsubscribe_seid(c_SEID0);
+ f_Mutex_unlock(__BFILE__, __LINE__);
+
+ log("[eNB <- S1GW] <- MME: INITIAL CONTEXT SETUP REQUEST");
+ f_ConnHdlr_rx_initial_ctx_setup_req(erabs);
+}
+
+function f_ConnHdlr_initial_ctx_setup_rsp(inout ERabList erabs)
+runs on ConnHdlr {
+ log("[eNB -> S1GW] -> MME: INITIAL CONTEXT SETUP RESPONSE");
+ f_ConnHdlr_tx_initial_ctx_setup_rsp(erabs);
+ f_ConnHdlr_session_modify(erabs);
+ log("eNB -> [S1GW -> MME]: INITIAL CONTEXT SETUP RESPONSE");
+ f_ConnHdlr_rx_initial_ctx_setup_rsp(erabs);
+}
+
}
diff --git a/s1gw/S1GW_Tests.ttcn b/s1gw/S1GW_Tests.ttcn
index 9713c1a..2e8ebcb 100644
--- a/s1gw/S1GW_Tests.ttcn
+++ b/s1gw/S1GW_Tests.ttcn
@@ -366,6 +366,48 @@
vc_conn.done;
}

+/* Test INITIAL CONTEXT SETUP procedure */
+function f_TC_initial_ctx_setup(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_initial_ctx_setup_req(g_pars.erabs);
+ f_ConnHdlr_initial_ctx_setup_rsp(g_pars.erabs);
+
+ f_ConnHdlr_s1ap_disconnect();
+ f_ConnHdlr_s1ap_unregister(g_pars.genb_id);
+}
+private function f_TC_initial_ctx_setup_exec(integer num_enbs, integer num_erabs)
+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));
+ vc_conns[i] := f_ConnHdlr_spawn(refers(f_TC_initial_ctx_setup), pars);
+ }
+
+ f_ConnHdlrList_all_done(vc_conns);
+}
+/* 1 E-RAB at a time, single eNB */
+testcase TC_initial_ctx_setup() runs on test_CT {
+ f_TC_initial_ctx_setup_exec(num_enbs := 1, num_erabs := 1);
+}
+/* 1 E-RAB at a time, multiple eNB connections */
+testcase TC_initial_ctx_setup_multi() runs on test_CT {
+ f_TC_initial_ctx_setup_exec(num_enbs := mp_multi_enb_num, num_erabs := 1);
+}
+/* 3 E-RABs at a time, single eNB */
+testcase TC_initial_ctx_setup3() runs on test_CT {
+ f_TC_initial_ctx_setup_exec(num_enbs := 1, num_erabs := 3);
+}
+/* 3 E-RABs at a time, multiple eNB connections */
+testcase TC_initial_ctx_setup3_multi() runs on test_CT {
+ f_TC_initial_ctx_setup_exec(num_enbs := mp_multi_enb_num, num_erabs := 3);
+}
+
function f_TC_pfcp_heartbeat(charstring id) runs on ConnHdlr {
var integer rts := f_PFCPEM_get_recovery_timestamp();
var PDU_PFCP pfcp_pdu;
@@ -399,6 +441,10 @@
execute( TC_e_rab_setup_multi() );
execute( TC_e_rab_setup3_multi() );
execute( TC_e_rab_release_ind() );
+ execute( TC_initial_ctx_setup() );
+ execute( TC_initial_ctx_setup3() );
+ execute( TC_initial_ctx_setup_multi() );
+ execute( TC_initial_ctx_setup3_multi() );
execute( TC_pfcp_heartbeat() );
}

diff --git a/s1gw/expected-results.xml b/s1gw/expected-results.xml
index 9075dc3..e50f978 100644
--- a/s1gw/expected-results.xml
+++ b/s1gw/expected-results.xml
@@ -1,5 +1,5 @@
<?xml version="1.0"?>
-<testsuite name='S1GW_Tests' tests='10' failures='0' errors='0' skipped='0' inconc='0' time='MASKED'>
+<testsuite name='S1GW_Tests' tests='14' 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'/>
@@ -9,5 +9,9 @@
<testcase classname='S1GW_Tests' name='TC_e_rab_setup_multi' time='MASKED'/>
<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_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'/>
+ <testcase classname='S1GW_Tests' name='TC_initial_ctx_setup3_multi' time='MASKED'/>
<testcase classname='S1GW_Tests' name='TC_pfcp_heartbeat' time='MASKED'/>
</testsuite>

To view, visit change 38279. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: merged
Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-Change-Id: I72e3ab932fee1de0fce8ddf4041b8f2174416bc1
Gerrit-Change-Number: 38279
Gerrit-PatchSet: 2
Gerrit-Owner: fixeria <vyanitskiy@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy@sysmocom.de>
Gerrit-Reviewer: laforge <laforge@osmocom.org>
Gerrit-Reviewer: pespin <pespin@sysmocom.de>