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

Change subject: s1gw: Add initial PFCP support emulating UPF
......................................................................

s1gw: Add initial PFCP support emulating UPF

Change-Id: If2b135e113d2568092e90ac9b6c5f651ab30f5d0
---
M library/PFCP_Emulation.ttcn
M s1gw/ConnHdlr.ttcn
M s1gw/S1GW_Tests.ttcn
M s1gw/gen_links.sh
M s1gw/osmo-s1gw.config
M s1gw/regen_makefile.sh
6 files changed, 144 insertions(+), 32 deletions(-)

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




diff --git a/library/PFCP_Emulation.ttcn b/library/PFCP_Emulation.ttcn
index d5a15a2..d872367 100644
--- a/library/PFCP_Emulation.ttcn
+++ b/library/PFCP_Emulation.ttcn
@@ -199,4 +199,12 @@
        }
 }

+altstep as_pfcp_ignore(PFCPEM_PT pt, template PDU_PFCP pfcp_expect := ?)
+{
+       [] pt.receive(pfcp_expect) {
+               log("Ignoring ", pfcp_expect);
+               repeat;
+       }
+}
+
 }
diff --git a/s1gw/ConnHdlr.ttcn b/s1gw/ConnHdlr.ttcn
index e4cff0c..12c7414 100644
--- a/s1gw/ConnHdlr.ttcn
+++ b/s1gw/ConnHdlr.ttcn
@@ -19,6 +19,11 @@
 import from IPL4asp_Types all;
 import from Misc_Helpers all;

+import from PFCP_Types all;
+import from PFCP_Emulation all;
+import from PFCP_Templates all;
+import from PFCP_CodecPort all;
+
 import from S1AP_CodecPort all;
 import from S1AP_CodecPort_CtrlFunct all;
 import from S1AP_Types all;
@@ -31,13 +36,15 @@
 import from SCTP_Templates all;
 import from S1AP_Server all;

-type component ConnHdlr extends S1APSRV_ConnHdlr {
+type component ConnHdlr extends S1APSRV_ConnHdlr, PFCP_ConnHdlr {
+       var ConnHdlrPars g_pars;
        port S1AP_CODEC_PT S1AP_ENB;
        var ConnectionId g_s1ap_conn_id := -1;
 };
 type record of ConnHdlr ConnHdlrList;

 type record ConnHdlrPars {
+       integer idx,
        Global_ENB_ID genb_id
 };

@@ -52,11 +59,19 @@
 }

 template (value) ConnHdlrPars
-t_ConnHdlrPars(integer enb_id := 0) := {
-       genb_id := ts_Global_ENB_ID(enb_id)
+t_ConnHdlrPars(integer idx := 0) := {
+       idx := idx,
+       genb_id := ts_Global_ENB_ID(idx)
 }

-type function void_fn(ConnHdlrPars pars) runs on ConnHdlr;
+type function void_fn(charstring id) runs on ConnHdlr;
+
+function f_ConnHdlr_init(void_fn fn, charstring id, ConnHdlrPars pars)
+runs on ConnHdlr {
+       g_pars := pars;
+       fn.apply(id);
+}
+

 function f_ConnHdlr_connect(charstring local_addr, charstring remote_addr) 
runs on ConnHdlr {
        var Result res;
@@ -209,4 +224,50 @@
        }
 }

+altstep as_pfcp_handle_assoc_setup_req(template (present) PDU_PFCP exp_rx := 
tr_PFCP_Assoc_Setup_Req(), boolean do_repeat := false)
+runs on ConnHdlr
+{
+       var PDU_PFCP rx;
+
+       [] PFCP.receive(exp_rx) -> value rx {
+               var Node_ID upf_node_id := 
valueof(ts_PFCP_Node_ID_fqdn("\07osmocom\03org"));
+               PFCP.send(ts_PFCP_Assoc_Setup_Resp(rx.sequence_number, 
upf_node_id,
+                                                  
ts_PFCP_Cause(REQUEST_ACCEPTED),
+                                                  1234));
+               if (do_repeat) {
+                       repeat;
+               }
+       }
+}
+
+private function f_pfcp_wait_assoc_setup(template (present) PDU_PFCP exp_rx := 
tr_PFCP_Assoc_Setup_Req(),
+                                        float wait_time := 10.0)
+runs on ConnHdlr
+{
+       timer T := wait_time;
+       T.start;
+       alt {
+       [] as_pfcp_handle_assoc_setup_req(exp_rx);
+       [] PFCP.receive(PDU_PFCP:?) {
+               Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
+                                       log2str("Got an unexpected PFCP 
message, was waiting for ", exp_rx));
+               }
+       [] T.timeout {
+               Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
+                                       log2str("Timeout waiting for PFCP ", 
exp_rx));
+               }
+       }
+       T.stop;
+}
+
+function f_ConnHdlr_register_pfcp() runs on ConnHdlr
+{
+       f_pfcp_register();
+       if (g_pars.idx == 0) {
+               /* First ConnHdlr answers the AssocSetup: */
+               activate(as_pfcp_handle_assoc_setup_req(do_repeat := true));
+       } else {
+               activate(as_pfcp_ignore(PFCP, tr_PFCP_Assoc_Setup_Req()));
+       }
+}
 }
diff --git a/s1gw/S1GW_Tests.ttcn b/s1gw/S1GW_Tests.ttcn
index 1f4bb71..9448ed5 100644
--- a/s1gw/S1GW_Tests.ttcn
+++ b/s1gw/S1GW_Tests.ttcn
@@ -28,20 +28,28 @@
 import from S1AP_PDU_Contents all;
 import from S1AP_Constants all;

+import from PFCP_Types all;
+import from PFCP_Emulation all;
+import from PFCP_Templates all;
+import from PFCP_CodecPort all;
+
 import from SCTP_Templates all;
 import from S1AP_Server all;
 import from ConnHdlr all;

 modulepar {
-       charstring mp_s1gw_enb_ip;      /* eNB facing address of the S1GW */
-       charstring mp_s1gw_mme_ip;      /* MME facing address of the S1GW */
-       charstring mp_enb_bind_ip;      /* eNB address to use locally when 
connecting to S1GW */
-       charstring mp_mme_bind_ip;      /* MME address on which we get 
connections from S1GW */
+       charstring mp_s1gw_enb_ip := "127.0.1.1";       /* eNB facing address 
of the S1GW */
+       charstring mp_s1gw_mme_ip := "127.0.2.1";       /* MME facing address 
of the S1GW */
+       charstring mp_s1gw_upf_ip := "127.0.3.1";       /* UPF facing address 
of the S1GW */
+       charstring mp_enb_bind_ip := "127.0.1.10";      /* eNB address to use 
locally when connecting to S1GW */
+       charstring mp_mme_bind_ip := "127.0.2.10";      /* MME address on which 
we get connections from S1GW */
+       charstring mp_upf_bind_ip := "127.0.3.10";      /* UPF address on which 
we get connections from S1GW */
 }

 type component test_CT {
        timer g_Tguard;
        var S1AP_Server_CT vc_S1APSRV;
+       var PFCP_Emulation_CT vc_PFCP;
 };

 private altstep as_Tguard() runs on test_CT {
@@ -50,9 +58,18 @@
        }
 }

-function f_init(float Tval := 20.0) runs on test_CT {
+function f_init(boolean s1apsrv_start := true,
+               boolean upf_start := true,
+               float Tval := 20.0) runs on test_CT {
        g_Tguard.start(Tval);
        activate(as_Tguard());
+
+       if (s1apsrv_start) {
+               f_init_s1ap_srv();
+       }
+       if (upf_start) {
+               f_init_pfcp();
+       }
 }

 function f_init_s1ap_srv() runs on test_CT {
@@ -65,36 +82,54 @@
        vc_S1APSRV.start(S1AP_Server.main(cpars));
 }

+function f_init_pfcp() runs on test_CT {
+       var PFCP_Emulation_Cfg pfcp_cfg := {
+               pfcp_bind_ip := mp_upf_bind_ip,
+               pfcp_bind_port := PFCP_PORT,
+               pfcp_remote_ip := mp_s1gw_upf_ip,
+               pfcp_remote_port := PFCP_PORT,
+               role := UPF
+       };
+
+       vc_PFCP := PFCP_Emulation_CT.create("PFCP-" & testcasename()) alive;
+       vc_PFCP.start(PFCP_Emulation.main(pfcp_cfg));
+}
+
 function f_ConnHdlr_spawn(void_fn fn, ConnHdlrPars pars)
 runs on test_CT return ConnHdlr {
        var ConnHdlr vc_conn;
+       var charstring id := "ConnHdlr-" & testcasename() & "-" & 
int2str(pars.idx);

-       vc_conn := ConnHdlr.create("ConnHdlr-" & testcasename()) alive;
-       if (vc_S1APSRV.running) {
+       vc_conn := ConnHdlr.create(id) alive;
+       if (isbound(vc_S1APSRV) and vc_S1APSRV.running) {
                connect(vc_conn:S1AP_CONN, vc_S1APSRV:S1AP_CLIENT);
                connect(vc_conn:S1AP_PROC, vc_S1APSRV:S1AP_PROC);
        }
-       vc_conn.start(derefers(fn)(pars));
+       if (isbound(vc_PFCP) and vc_PFCP.running) {
+               connect(vc_conn:PFCP, vc_PFCP:CLIENT);
+               connect(vc_conn:PFCP_PROC, vc_PFCP:CLIENT_PROC);
+       }
+       vc_conn.start(f_ConnHdlr_init(fn, id, pars));

        return vc_conn;
 }

-function f_TC_setup(ConnHdlrPars pars) runs on ConnHdlr {
-       f_ConnHdlr_register(pars.genb_id);
+function f_TC_setup(charstring id) runs on ConnHdlr {
+       f_ConnHdlr_register_pfcp();
+       f_ConnHdlr_register(g_pars.genb_id);

        f_ConnHdlr_connect(mp_enb_bind_ip, mp_s1gw_enb_ip);
-       f_ConnHdlr_setup(pars.genb_id);
+       f_ConnHdlr_setup(g_pars.genb_id);
        f_sleep(0.5); /* keep the connection idle for some time */
        f_ConnHdlr_disconnect();

-       f_ConnHdlr_unregister(pars.genb_id);
+       f_ConnHdlr_unregister(g_pars.genb_id);
 }
 testcase TC_setup() runs on test_CT {
        var ConnHdlrPars pars := valueof(t_ConnHdlrPars);
        var ConnHdlr vc_conn;

        f_init();
-       f_init_s1ap_srv();

        vc_conn := f_ConnHdlr_spawn(refers(f_TC_setup), pars);
        vc_conn.done;
@@ -103,7 +138,6 @@
        var ConnHdlrList vc_conns := { };

        f_init();
-       f_init_s1ap_srv();

        for (var integer i := 0; i < 42; i := i + 1) {
                var ConnHdlrPars pars := valueof(t_ConnHdlrPars(i));
@@ -118,26 +152,26 @@


 /* MME terminates connection, expect S1GW to terminate the eNB connection */
-function f_TC_conn_term_by_mme(ConnHdlrPars pars) runs on ConnHdlr {
-       f_ConnHdlr_register(pars.genb_id);
+function f_TC_conn_term_by_mme(charstring id) runs on ConnHdlr {
+       f_ConnHdlr_register_pfcp();
+       f_ConnHdlr_register(g_pars.genb_id);

        f_ConnHdlr_connect(mp_enb_bind_ip, mp_s1gw_enb_ip);
-       f_ConnHdlr_setup(pars.genb_id);
+       f_ConnHdlr_setup(g_pars.genb_id);
        f_sleep(0.5); /* keep the connection idle for some time */

        /* MME (S1AP_Server_CT) terminates connection */
-       f_ConnHdlr_close_conn(pars.genb_id);
+       f_ConnHdlr_close_conn(g_pars.genb_id);
        /* expect our eNB connection to be released gracefully */
        f_ConnHdlr_expect_shutdown();

-       f_ConnHdlr_unregister(pars.genb_id);
+       f_ConnHdlr_unregister(g_pars.genb_id);
 }
 testcase TC_conn_term_by_mme() runs on test_CT {
        var ConnHdlrPars pars := valueof(t_ConnHdlrPars);
        var ConnHdlr vc_conn;

        f_init();
-       f_init_s1ap_srv();

        vc_conn := f_ConnHdlr_spawn(refers(f_TC_conn_term_by_mme), pars);
        vc_conn.done;
@@ -145,7 +179,8 @@


 /* MME is not available, expect S1GW to terminate the eNB connection */
-function f_TC_conn_term_mme_unavail(ConnHdlrPars pars) runs on ConnHdlr {
+function f_TC_conn_term_mme_unavail(charstring id) runs on ConnHdlr {
+       f_ConnHdlr_register_pfcp();
        /* establish an eNB connection to the S1GW */
        f_ConnHdlr_connect(mp_enb_bind_ip, mp_s1gw_enb_ip);
        /* expect our eNB connection to be released gracefully */
@@ -156,21 +191,22 @@
        var ConnHdlrPars pars := valueof(t_ConnHdlrPars);
        var ConnHdlr vc_conn;

-       f_init();
+       f_init(s1apsrv_start := false);

        vc_conn := f_ConnHdlr_spawn(refers(f_TC_conn_term_mme_unavail), pars);
        vc_conn.done;
 }

-function f_TC_e_rab_setup(ConnHdlrPars pars) runs on ConnHdlr {
+function f_TC_e_rab_setup(charstring id) runs on ConnHdlr {
        const integer mme_id := 7;
        const integer enb_id := 9;
        const integer erab_id := 6;
        var S1AP_PDU pdu;

-       f_ConnHdlr_register(pars.genb_id);
+       f_ConnHdlr_register_pfcp();
+       f_ConnHdlr_register(g_pars.genb_id);
        f_ConnHdlr_connect(mp_enb_bind_ip, mp_s1gw_enb_ip);
-       f_ConnHdlr_setup(pars.genb_id);
+       f_ConnHdlr_setup(g_pars.genb_id);

        log("eNB <- [S1GW] <- MME: E-RAB SETUP REQUEST");
        var template (value) E_RABToBeSetupListBearerSUReq items_req;
@@ -224,14 +260,13 @@
        f_ConnHdlr_rx_s1ap_from_enb(pdu, tr_S1AP_RABSetupRsp(mme_id, enb_id, 
items_res));

        f_ConnHdlr_disconnect();
-       f_ConnHdlr_unregister(pars.genb_id);
+       f_ConnHdlr_unregister(g_pars.genb_id);
 }
 testcase TC_e_rab_setup() runs on test_CT {
        var ConnHdlrPars pars := valueof(t_ConnHdlrPars);
        var ConnHdlr vc_conn;

        f_init();
-       f_init_s1ap_srv();

        vc_conn := f_ConnHdlr_spawn(refers(f_TC_e_rab_setup), pars);
        vc_conn.done;
diff --git a/s1gw/gen_links.sh b/s1gw/gen_links.sh
index fd54815..ef8bdde 100755
--- a/s1gw/gen_links.sh
+++ b/s1gw/gen_links.sh
@@ -17,6 +17,10 @@
 FILES="IPL4asp_Functions.ttcn  IPL4asp_PT.cc  IPL4asp_PT.hh 
IPL4asp_PortType.ttcn  IPL4asp_Types.ttcn  IPL4asp_discovery.cc 
IPL4asp_protocol_L234.hh"
 gen_links $DIR $FILES

+DIR=$BASEDIR/titan.ProtocolModules.PFCP_v15.1.0/src
+FILES="PFCP_Types.ttcn"
+gen_links $DIR $FILES
+
 DIR=../library/s1ap
 FILES="S1AP_CommonDataTypes.asn S1AP_Constants.asn S1AP_Containers.asn 
S1AP_IEs.asn "
 FILES+="S1AP_PDU_Contents.asn S1AP_PDU_Descriptions.asn "
@@ -25,6 +29,7 @@

 DIR=../library
 FILES="Misc_Helpers.ttcn General_Types.ttcn Osmocom_Types.ttcn 
Native_Functions.ttcn Native_FunctionDefs.cc IPCP_Types.ttcn "
+FILES+="PFCP_CodecPort.ttcn PFCP_CodecPort_CtrlFunct.ttcn 
PFCP_CodecPort_CtrlFunctDef.cc PFCP_Emulation.ttcn PFCP_Templates.ttcn "
 FILES+="S1AP_CodecPort.ttcn S1AP_CodecPort_CtrlFunctDef.cc 
S1AP_CodecPort_CtrlFunct.ttcn "
 FILES+="SCTP_Templates.ttcn "
 gen_links $DIR $FILES
diff --git a/s1gw/osmo-s1gw.config b/s1gw/osmo-s1gw.config
index f4a4a73..a04d1cf 100644
--- a/s1gw/osmo-s1gw.config
+++ b/s1gw/osmo-s1gw.config
@@ -13,7 +13,9 @@
  {osmo_s1gw,
   [{s1gw_bind_addr, "127.0.1.1"}, %% S1GW bind address for incoming eNB 
connections
    {mme_loc_addr, "127.0.2.1"}, %% local address for outgoing connections to 
the MME
-   {mme_rem_addr, "127.0.2.10"} %% remote address for outgoing connections to 
the MME
+   {mme_rem_addr, "127.0.2.10"}, %% remote address for outgoing connections to 
the MME
+   {pfcp_loc_addr, "127.0.3.1"}, %% local address for outgoing connections to 
the UPF
+   {pfcp_rem_addr, "127.0.3.10"} %% local address for outgoing connections to 
the UPF
   ]},
  %% 
================================================================================
  %% kernel config
diff --git a/s1gw/regen_makefile.sh b/s1gw/regen_makefile.sh
index 7eef51b..8c32b3d 100755
--- a/s1gw/regen_makefile.sh
+++ b/s1gw/regen_makefile.sh
@@ -8,6 +8,7 @@
        IPL4asp_PT.cc
        IPL4asp_discovery.cc
        Native_FunctionDefs.cc
+       PFCP_CodecPort_CtrlFunctDef.cc
        S1AP_CodecPort_CtrlFunctDef.cc
        S1AP_EncDec.cc
        TCCConversion.cc

--
To view, visit https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/37920?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: If2b135e113d2568092e90ac9b6c5f651ab30f5d0
Gerrit-Change-Number: 37920
Gerrit-PatchSet: 5
Gerrit-Owner: pespin <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <[email protected]>
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-Reviewer: pespin <[email protected]>

Reply via email to