<p>Harald Welte <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/9412">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Harald Welte: Looks good to me, approved; Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">bsc: Add LCLS related test cases<br><br>This is an early WIP, we actually will need to establish two calls/legs<br>before the BSC is able to locally correlate them.<br><br>Related: OS#1602<br>Change-Id: Ie6d0b9c38027abf65c7c564fc79b889d013fa6a7<br>---<br>M bsc/BSC_Tests.ttcn<br>A bsc/BSC_Tests_LCLS.ttcn<br>M bsc/MSC_ConnectionHandler.ttcn<br>M library/BSSMAP_Templates.ttcn<br>4 files changed, 634 insertions(+), 4 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/bsc/BSC_Tests.ttcn b/bsc/BSC_Tests.ttcn</span><br><span>index 80fb8c3..3830e7d 100644</span><br><span>--- a/bsc/BSC_Tests.ttcn</span><br><span>+++ b/bsc/BSC_Tests.ttcn</span><br><span>@@ -1830,8 +1830,6 @@</span><br><span>  vc_conn.done;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* test if L3 RR CLASSMARK CHANGE is translated to BSSMAP CLASSMARK UPDATE */</span><br><span> private function f_tc_classmark(charstring id) runs on MSC_ConnHdlr {</span><br><span>     g_pars := valueof(t_def_TestHdlrPars);</span><br><span>diff --git a/bsc/BSC_Tests_LCLS.ttcn b/bsc/BSC_Tests_LCLS.ttcn</span><br><span>new file mode 100644</span><br><span>index 0000000..42feb57</span><br><span>--- /dev/null</span><br><span>+++ b/bsc/BSC_Tests_LCLS.ttcn</span><br><span>@@ -0,0 +1,579 @@</span><br><span style="color: hsl(120, 100%, 40%);">+module BSC_Tests_LCLS {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Integration Tests for OsmoBSC</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2018 by Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(120, 100%, 40%);">+ * All rights reserved.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Released under the terms of GNU General Public License, Version 2 or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This test suite tests OsmoBSC while emulating both multiple BTS + MS as</span><br><span style="color: hsl(120, 100%, 40%);">+ * well as the MSC. See README for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * There are test cases that run in so-called 'handler mode' and test cases</span><br><span style="color: hsl(120, 100%, 40%);">+ * that run directly on top of the BSSAP and RSL CodecPorts.  The "handler mode"</span><br><span style="color: hsl(120, 100%, 40%);">+ * tests abstract the multiplexing/demultiplexing of multiple SCCP connections</span><br><span style="color: hsl(120, 100%, 40%);">+ * and/or RSL channels and are hence suitable for higher-level test cases, while</span><br><span style="color: hsl(120, 100%, 40%);">+ * the "raw" tests directly on top of the CodecPorts are more suitable for lower-</span><br><span style="color: hsl(120, 100%, 40%);">+ * level testing.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import from General_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from Osmocom_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from GSM_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from IPL4asp_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import from BSSAP_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from BSSAP_Adapter all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from BSSAP_CodecPort all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from BSSMAP_Templates all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from IPA_Emulation all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from IPA_CodecPort all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from IPA_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from RSL_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from RSL_Emulation all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from MGCP_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from MGCP_Emulation all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from MGCP_Templates all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from SDP_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import from Osmocom_CTRL_Functions all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from Osmocom_CTRL_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from Osmocom_CTRL_Adapter all;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import from Osmocom_VTY_Functions all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from TELNETasp_PortType all;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import from MobileL3_CommonIE_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from MobileL3_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from L3_Templates all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from GSM_RR_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import from BSSMAP_Templates all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from BSSMAP_Emulation all;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import from MSC_ConnectionHandler all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from BSC_Tests all;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* The philosophy of this testsuite is to re-use as much as possible the existing components</span><br><span style="color: hsl(120, 100%, 40%);">+ * and functions that we have in BSC_Tests and its dependencies.  However, as opposed to those</span><br><span style="color: hsl(120, 100%, 40%);">+ * normal BSC tests, we here have to run *two* ConnHdlr and synchronize activity between them.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * We do this by adding some special-purpose ports between the main test component running the</span><br><span style="color: hsl(120, 100%, 40%);">+ * test case [lcls_]test_CT and the per-connection [LCLS_]MSC_ConnHdlr.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* take test_CT from BSC_Tests and extend it with LCLS specific bits */</span><br><span style="color: hsl(120, 100%, 40%);">+type component lcls_test_CT extends test_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Component references */</span><br><span style="color: hsl(120, 100%, 40%);">+    var LCLS_MSC_ConnHdlr vc_CONN_A;</span><br><span style="color: hsl(120, 100%, 40%);">+      var LCLS_MSC_ConnHdlr vc_CONN_B;</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Ports to the two call legs */</span><br><span style="color: hsl(120, 100%, 40%);">+      port LCLS_InterComp_PT CONN_A;</span><br><span style="color: hsl(120, 100%, 40%);">+        port LCLS_InterComp_PT CONN_B;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* take MSC_ConnHdlr and extend it with LCLS specific bits */</span><br><span style="color: hsl(120, 100%, 40%);">+type component LCLS_MSC_ConnHdlr extends MSC_ConnHdlr {</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Port back to the controlling lcls_test_CT */</span><br><span style="color: hsl(120, 100%, 40%);">+       port LCLS_InterComp_PT MASTER;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* port type between lcls_test_CT and LCLS_MSC_ConnHdlr */</span><br><span style="color: hsl(120, 100%, 40%);">+type port LCLS_InterComp_PT message {</span><br><span style="color: hsl(120, 100%, 40%);">+                /* BSSAP from BSSA_ConnHdlr */</span><br><span style="color: hsl(120, 100%, 40%);">+        inout   PDU_BSSAP, BSSAP_Conn_Prim, PDU_DTAP_MO, PDU_DTAP_MT,</span><br><span style="color: hsl(120, 100%, 40%);">+         /* RSL from RSL_DchanHdlr */</span><br><span style="color: hsl(120, 100%, 40%);">+          RSLDC_ChanRqd, RSL_Message,</span><br><span style="color: hsl(120, 100%, 40%);">+           /* MGCP from MGCP_ConnHdlr */</span><br><span style="color: hsl(120, 100%, 40%);">+         MgcpCommand, MgcpResponse,</span><br><span style="color: hsl(120, 100%, 40%);">+            LclsCompSync;</span><br><span style="color: hsl(120, 100%, 40%);">+} with { extension "internal" };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+type enumerated LclsCompSync {</span><br><span style="color: hsl(120, 100%, 40%);">+   /* ConnHdlr signals to master component that assignment has completed */</span><br><span style="color: hsl(120, 100%, 40%);">+      LCLS_COMP_SYNC_ASS_COMPL</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* forward messages between the RSL/MGCP/BSSAP Emulation and the master component */</span><br><span style="color: hsl(120, 100%, 40%);">+private altstep as_lcls_conn_hdlr_proxy() runs on LCLS_MSC_ConnHdlr {</span><br><span style="color: hsl(120, 100%, 40%);">+  var PDU_BSSAP bssap;</span><br><span style="color: hsl(120, 100%, 40%);">+  var BSSAP_Conn_Prim bssap_p;</span><br><span style="color: hsl(120, 100%, 40%);">+  var PDU_DTAP_MO dtap_mo;</span><br><span style="color: hsl(120, 100%, 40%);">+      var PDU_DTAP_MT dtap_mt;</span><br><span style="color: hsl(120, 100%, 40%);">+      var MgcpCommand mgcp_cmd;</span><br><span style="color: hsl(120, 100%, 40%);">+     var MgcpResponse mgcp_rsp;</span><br><span style="color: hsl(120, 100%, 40%);">+    var RSL_Message rsl_msg;</span><br><span style="color: hsl(120, 100%, 40%);">+      /* from ConnHdlr to master process */</span><br><span style="color: hsl(120, 100%, 40%);">+ [] BSSAP.receive(PDU_BSSAP:?) -> value bssap { MASTER.send(bssap); }</span><br><span style="color: hsl(120, 100%, 40%);">+       [] BSSAP.receive(BSSAP_Conn_Prim:?) -> value bssap_p { MASTER.send(bssap_p); }</span><br><span style="color: hsl(120, 100%, 40%);">+     [] BSSAP.receive(PDU_DTAP_MO:?) -> value dtap_mo { MASTER.send(dtap_mo); }</span><br><span style="color: hsl(120, 100%, 40%);">+ [] BSSAP.receive(PDU_DTAP_MT:?) -> value dtap_mt { MASTER.send(dtap_mt); }</span><br><span style="color: hsl(120, 100%, 40%);">+ [] MGCP.receive(MgcpCommand:?) -> value mgcp_cmd { MASTER.send(mgcp_cmd); }</span><br><span style="color: hsl(120, 100%, 40%);">+        [] MGCP.receive(MgcpResponse:?) -> value mgcp_rsp { MASTER.send(mgcp_rsp); }</span><br><span style="color: hsl(120, 100%, 40%);">+       [] RSL.receive(RSL_Message:?) -> value rsl_msg { MASTER.send(rsl_msg); }</span><br><span style="color: hsl(120, 100%, 40%);">+   /* from master process to ConnHdlr */</span><br><span style="color: hsl(120, 100%, 40%);">+ [] MASTER.receive(PDU_BSSAP:?) -> value bssap { BSSAP.send(bssap); }</span><br><span style="color: hsl(120, 100%, 40%);">+       [] MASTER.receive(PDU_DTAP_MO:?) -> value dtap_mo { BSSAP.send(dtap_mo); }</span><br><span style="color: hsl(120, 100%, 40%);">+ [] MASTER.receive(PDU_DTAP_MT:?) -> value dtap_mt { BSSAP.send(dtap_mt); }</span><br><span style="color: hsl(120, 100%, 40%);">+ [] MASTER.receive(MgcpCommand:?) -> value mgcp_cmd { MGCP.send(mgcp_cmd); }</span><br><span style="color: hsl(120, 100%, 40%);">+        [] MASTER.receive(MgcpResponse:?) -> value mgcp_rsp { MGCP.send(mgcp_rsp); }</span><br><span style="color: hsl(120, 100%, 40%);">+       [] MASTER.receive(RSL_Message:?) -> value rsl_msg { RSL.send(rsl_msg); }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_lcls_connhdlr_main(charstring id) runs on LCLS_MSC_ConnHdlr {</span><br><span style="color: hsl(120, 100%, 40%);">+  /* 1) establish the connection between RSL and BSSAP side */</span><br><span style="color: hsl(120, 100%, 40%);">+  var PDU_BSSAP ass_req := f_gen_ass_req();</span><br><span style="color: hsl(120, 100%, 40%);">+     var template PDU_BSSAP ass_compl := f_gen_exp_compl();</span><br><span style="color: hsl(120, 100%, 40%);">+        ass_req.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;</span><br><span style="color: hsl(120, 100%, 40%);">+      f_establish_fully(ass_req, ass_compl);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* 2) notify master that assignment has completed */</span><br><span style="color: hsl(120, 100%, 40%);">+  MASTER.send(LclsCompSync:LCLS_COMP_SYNC_ASS_COMPL);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 3) proxy packets between master component and various ports */</span><br><span style="color: hsl(120, 100%, 40%);">+     while (true) {</span><br><span style="color: hsl(120, 100%, 40%);">+                as_lcls_conn_hdlr_proxy();</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+type function lcls_void_fn(charstring id) runs on LCLS_MSC_ConnHdlr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* first function inside ConnHdlr component; sets g_pars + starts function */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_handler_init(lcls_void_fn fn, charstring id, template (omit) TestHdlrParams pars := omit)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on LCLS_MSC_ConnHdlr {</span><br><span style="color: hsl(120, 100%, 40%);">+      if (isvalue(pars)) {</span><br><span style="color: hsl(120, 100%, 40%);">+          g_pars := valueof(pars);</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+     fn.apply(id);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* function creating the two ConnHdlrs, connecting them + starting them */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_lcls_test_init(TestHdlrParams pars_a, TestHdlrParams pars_b) runs on lcls_test_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+        var charstring id_a := testcasename() & "-A";</span><br><span style="color: hsl(120, 100%, 40%);">+   var charstring id_b := testcasename() & "-B";</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ pars_b.imsi := '002029876543210'H;</span><br><span style="color: hsl(120, 100%, 40%);">+    pars_b.media_nr := 2;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* create and connect the two ConnHandlers */</span><br><span style="color: hsl(120, 100%, 40%);">+ vc_CONN_A := LCLS_MSC_ConnHdlr.create(id_a);</span><br><span style="color: hsl(120, 100%, 40%);">+  f_connect_handler(vc_CONN_A);</span><br><span style="color: hsl(120, 100%, 40%);">+ connect(vc_CONN_A:MASTER, self:CONN_A);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     vc_CONN_B := LCLS_MSC_ConnHdlr.create(id_b);</span><br><span style="color: hsl(120, 100%, 40%);">+  f_connect_handler(vc_CONN_B);</span><br><span style="color: hsl(120, 100%, 40%);">+ connect(vc_CONN_B:MASTER, self:CONN_B);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* start the two components */</span><br><span style="color: hsl(120, 100%, 40%);">+        vc_CONN_A.start(f_handler_init(refers(f_lcls_connhdlr_main), id_a, pars_a));</span><br><span style="color: hsl(120, 100%, 40%);">+  f_sleep(3.0);</span><br><span style="color: hsl(120, 100%, 40%);">+ vc_CONN_B.start(f_handler_init(refers(f_lcls_connhdlr_main), id_b, pars_b));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_lcls_test_fini() runs on lcls_test_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ vc_CONN_A.stop;</span><br><span style="color: hsl(120, 100%, 40%);">+       vc_CONN_B.stop;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* ignore some messages which we're not interested in evaluating (yet) */</span><br><span style="color: hsl(120, 100%, 40%);">+private altstep as_ignore() runs on lcls_test_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+       [] CONN_A.receive(tr_DLCX) { repeat; }</span><br><span style="color: hsl(120, 100%, 40%);">+        [] CONN_B.receive(tr_DLCX) { repeat; }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* fail if any notify is being received */</span><br><span style="color: hsl(120, 100%, 40%);">+private altstep as_fail_on_lcls_notify() runs on lcls_test_CT</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     [] CONN_A.receive(tr_BSSMAP_LclsNotification(?, *)) {</span><br><span style="color: hsl(120, 100%, 40%);">+         setverdict(fail, "Unexpected BSSMAP LCLS Notification");</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     [] CONN_B.receive(tr_BSSMAP_LclsNotification(?, *)) {</span><br><span style="color: hsl(120, 100%, 40%);">+         setverdict(fail, "Unexpected BSSMAP LCLS Notification");</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_wait_fail_notify() runs on lcls_test_CT</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ timer T := 3.0;</span><br><span style="color: hsl(120, 100%, 40%);">+       T.start;</span><br><span style="color: hsl(120, 100%, 40%);">+      alt {</span><br><span style="color: hsl(120, 100%, 40%);">+ [] as_fail_on_lcls_notify();</span><br><span style="color: hsl(120, 100%, 40%);">+  [] T.timeout { }</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_lcls_init(integer nr_bts := 1) runs on lcls_test_CT</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     var default d;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      d := activate(as_ignore());</span><br><span style="color: hsl(120, 100%, 40%);">+   f_init(nr_bts, true);</span><br><span style="color: hsl(120, 100%, 40%);">+ f_sleep(1.0);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Send an ASSIGNMENT REQ with LCLS GCR only, without LCLS CFG or CSC */</span><br><span style="color: hsl(120, 100%, 40%);">+testcase TC_lcls_gcr_only() runs on lcls_test_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+    var TestHdlrParams pars := valueof(t_def_TestHdlrPars);</span><br><span style="color: hsl(120, 100%, 40%);">+       var MSC_ConnHdlr vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   f_lcls_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));</span><br><span style="color: hsl(120, 100%, 40%);">+ pars.lcls.gcr := valueof(ts_GCR('010203'O, '0405'O, '060708090a'O));</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Expect LCLS status to be not reported, as no LCLS config was signalled */</span><br><span style="color: hsl(120, 100%, 40%);">+  pars.lcls.exp_sts := omit;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  f_lcls_test_init(pars, pars);</span><br><span style="color: hsl(120, 100%, 40%);">+ CONN_A.receive(LclsCompSync:LCLS_COMP_SYNC_ASS_COMPL);</span><br><span style="color: hsl(120, 100%, 40%);">+        CONN_B.receive(LclsCompSync:LCLS_COMP_SYNC_ASS_COMPL);</span><br><span style="color: hsl(120, 100%, 40%);">+        f_wait_fail_notify();</span><br><span style="color: hsl(120, 100%, 40%);">+ f_lcls_test_fini();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Send an ASSIGNMENT REQ with LCLS GCR+CFG+CSC; expect connect both-way */</span><br><span style="color: hsl(120, 100%, 40%);">+testcase TC_lcls_gcr_bway_connect() runs on lcls_test_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+     var TestHdlrParams pars_a := valueof(t_def_TestHdlrPars);</span><br><span style="color: hsl(120, 100%, 40%);">+     var TestHdlrParams pars_b;</span><br><span style="color: hsl(120, 100%, 40%);">+    var MSC_ConnHdlr vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+     var MgcpCommand mgcp_cmd;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   f_lcls_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      pars_a.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));</span><br><span style="color: hsl(120, 100%, 40%);">+       pars_a.lcls.gcr := valueof(ts_GCR('010203'O, '0405'O, '060708090a'O));</span><br><span style="color: hsl(120, 100%, 40%);">+        pars_a.lcls.cfg := LCLS_CFG_both_way;</span><br><span style="color: hsl(120, 100%, 40%);">+ pars_a.lcls.csc := LCLS_CSC_connect;</span><br><span style="color: hsl(120, 100%, 40%);">+  pars_b := pars_a;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* first call is not possible to be LS (no second leg yet) */</span><br><span style="color: hsl(120, 100%, 40%);">+ pars_a.lcls.exp_sts := LCLS_STS_not_possible_ls;</span><br><span style="color: hsl(120, 100%, 40%);">+      /* second call should then reuslt in LS */</span><br><span style="color: hsl(120, 100%, 40%);">+    pars_b.lcls.exp_sts := LCLS_STS_locally_switched;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   f_lcls_test_init(pars_a, pars_b);</span><br><span style="color: hsl(120, 100%, 40%);">+     CONN_A.receive(LclsCompSync:LCLS_COMP_SYNC_ASS_COMPL);</span><br><span style="color: hsl(120, 100%, 40%);">+        interleave {</span><br><span style="color: hsl(120, 100%, 40%);">+  [] CONN_A.receive(tr_BSSMAP_LclsNotificationSts(LCLS_STS_not_yet_ls));</span><br><span style="color: hsl(120, 100%, 40%);">+        [] CONN_A.receive(tr_BSSMAP_LclsNotificationSts(LCLS_STS_locally_switched));</span><br><span style="color: hsl(120, 100%, 40%);">+  [] CONN_B.receive(LclsCompSync:LCLS_COMP_SYNC_ASS_COMPL);</span><br><span style="color: hsl(120, 100%, 40%);">+     [] CONN_A.receive(tr_MDCX) -> value mgcp_cmd {</span><br><span style="color: hsl(120, 100%, 40%);">+             CONN_A.send(f_build_mdcx_rsp(mgcp_cmd));</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   f_lcls_test_fini();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Send an ASSIGNMENT REQ with LCLS CFG+CSC enabling LCLS but GCR doesn't match! */</span><br><span style="color: hsl(120, 100%, 40%);">+testcase TC_lcls_gcr_nomatch_bway_connect() runs on lcls_test_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ var TestHdlrParams pars_a := valueof(t_def_TestHdlrPars);</span><br><span style="color: hsl(120, 100%, 40%);">+     var TestHdlrParams pars_b;</span><br><span style="color: hsl(120, 100%, 40%);">+    var MSC_ConnHdlr vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+     var MgcpCommand mgcp_cmd;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   f_lcls_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      pars_a.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));</span><br><span style="color: hsl(120, 100%, 40%);">+       pars_a.lcls.cfg := LCLS_CFG_both_way;</span><br><span style="color: hsl(120, 100%, 40%);">+ pars_a.lcls.csc := LCLS_CSC_connect;</span><br><span style="color: hsl(120, 100%, 40%);">+  pars_a.lcls.exp_sts := LCLS_STS_not_possible_ls;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    pars_b := pars_a;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* first call is not possible to be LS (no second leg yet) */</span><br><span style="color: hsl(120, 100%, 40%);">+ pars_a.lcls.gcr := valueof(ts_GCR('010203'O, '0405'O, '060708090a'O));</span><br><span style="color: hsl(120, 100%, 40%);">+        pars_b.lcls.gcr := valueof(ts_GCR('010203'O, '0405'O, '060708090b'O));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      f_lcls_test_init(pars_a, pars_b);</span><br><span style="color: hsl(120, 100%, 40%);">+     CONN_A.receive(LclsCompSync:LCLS_COMP_SYNC_ASS_COMPL);</span><br><span style="color: hsl(120, 100%, 40%);">+        CONN_B.receive(LclsCompSync:LCLS_COMP_SYNC_ASS_COMPL);</span><br><span style="color: hsl(120, 100%, 40%);">+        f_wait_fail_notify();</span><br><span style="color: hsl(120, 100%, 40%);">+ f_lcls_test_fini();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Send an ASSIGNMENT REQ with LCLS GCR+CFG+CSC; expect no connect */</span><br><span style="color: hsl(120, 100%, 40%);">+testcase TC_lcls_gcr_bway_dont_connect() runs on lcls_test_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+    var TestHdlrParams pars_a := valueof(t_def_TestHdlrPars);</span><br><span style="color: hsl(120, 100%, 40%);">+     var TestHdlrParams pars_b;</span><br><span style="color: hsl(120, 100%, 40%);">+    var MSC_ConnHdlr vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   f_lcls_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      pars_a.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));</span><br><span style="color: hsl(120, 100%, 40%);">+       pars_a.lcls.gcr := valueof(ts_GCR('010203'O, '0405'O, '060708090a'O));</span><br><span style="color: hsl(120, 100%, 40%);">+        pars_a.lcls.cfg := LCLS_CFG_both_way;</span><br><span style="color: hsl(120, 100%, 40%);">+ pars_a.lcls.csc := LCLS_CSC_do_not_connect;</span><br><span style="color: hsl(120, 100%, 40%);">+   pars_b := pars_a;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* first call is not possible to be LS (no second leg yet) */</span><br><span style="color: hsl(120, 100%, 40%);">+ pars_a.lcls.exp_sts := LCLS_STS_not_possible_ls;</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Expect LCLS is *NOT* established */</span><br><span style="color: hsl(120, 100%, 40%);">+        pars_b.lcls.exp_sts := LCLS_STS_not_yet_ls;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_lcls_test_init(pars_a, pars_b);</span><br><span style="color: hsl(120, 100%, 40%);">+     CONN_A.receive(LclsCompSync:LCLS_COMP_SYNC_ASS_COMPL);</span><br><span style="color: hsl(120, 100%, 40%);">+        CONN_B.receive(LclsCompSync:LCLS_COMP_SYNC_ASS_COMPL);</span><br><span style="color: hsl(120, 100%, 40%);">+        CONN_A.receive(tr_BSSMAP_LclsNotificationSts(LCLS_STS_not_yet_ls));</span><br><span style="color: hsl(120, 100%, 40%);">+   f_wait_fail_notify();</span><br><span style="color: hsl(120, 100%, 40%);">+ f_lcls_test_fini();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Send an ASSIGNMENT REQ with LCLS GCR+CFG+CSC; expect no connect */</span><br><span style="color: hsl(120, 100%, 40%);">+testcase TC_lcls_gcr_unsuppported_cfg() runs on lcls_test_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+       var TestHdlrParams pars := valueof(t_def_TestHdlrPars);</span><br><span style="color: hsl(120, 100%, 40%);">+       var MSC_ConnHdlr vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   f_lcls_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));</span><br><span style="color: hsl(120, 100%, 40%);">+ pars.lcls.gcr := valueof(ts_GCR('010203'O, '0405'O, '060708090a'O));</span><br><span style="color: hsl(120, 100%, 40%);">+  pars.lcls.cfg := LCLS_CFG_both_way_and_send_DL;</span><br><span style="color: hsl(120, 100%, 40%);">+       pars.lcls.csc := LCLS_CSC_connect;</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Expect LCLS is *NOT* established with "LCLS_STS_req_lcls_not_supp" */</span><br><span style="color: hsl(120, 100%, 40%);">+    pars.lcls.exp_sts := LCLS_STS_req_lcls_not_supp;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    f_lcls_test_init(pars, pars);</span><br><span style="color: hsl(120, 100%, 40%);">+ CONN_A.receive(LclsCompSync:LCLS_COMP_SYNC_ASS_COMPL);</span><br><span style="color: hsl(120, 100%, 40%);">+        CONN_B.receive(LclsCompSync:LCLS_COMP_SYNC_ASS_COMPL);</span><br><span style="color: hsl(120, 100%, 40%);">+        f_wait_fail_notify();</span><br><span style="color: hsl(120, 100%, 40%);">+ f_lcls_test_fini();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Send an ASSIGNMENT REQ with LCLS GCR+CFG+CSC; expect no connect */</span><br><span style="color: hsl(120, 100%, 40%);">+testcase TC_lcls_gcr_unsuppported_csc() runs on lcls_test_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+       var TestHdlrParams pars_a := valueof(t_def_TestHdlrPars);</span><br><span style="color: hsl(120, 100%, 40%);">+     var TestHdlrParams pars_b;</span><br><span style="color: hsl(120, 100%, 40%);">+    var MSC_ConnHdlr vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   f_lcls_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      pars_a.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));</span><br><span style="color: hsl(120, 100%, 40%);">+       pars_a.lcls.gcr := valueof(ts_GCR('010203'O, '0405'O, '060708090a'O));</span><br><span style="color: hsl(120, 100%, 40%);">+        pars_a.lcls.cfg := LCLS_CFG_both_way;</span><br><span style="color: hsl(120, 100%, 40%);">+ pars_a.lcls.csc := LCLS_CSC_bicast_UL_and_recv_DL_at_handover;</span><br><span style="color: hsl(120, 100%, 40%);">+        pars_b := pars_a;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* first call is not possible to be LS (no second leg yet) */</span><br><span style="color: hsl(120, 100%, 40%);">+ pars_a.lcls.exp_sts := LCLS_STS_not_possible_ls;</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Expect LCLS is *NOT* established */</span><br><span style="color: hsl(120, 100%, 40%);">+        pars_b.lcls.exp_sts := LCLS_STS_not_yet_ls;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_lcls_test_init(pars_a, pars_b);</span><br><span style="color: hsl(120, 100%, 40%);">+     CONN_A.receive(LclsCompSync:LCLS_COMP_SYNC_ASS_COMPL);</span><br><span style="color: hsl(120, 100%, 40%);">+        CONN_B.receive(LclsCompSync:LCLS_COMP_SYNC_ASS_COMPL);</span><br><span style="color: hsl(120, 100%, 40%);">+        CONN_A.receive(tr_BSSMAP_LclsNotificationSts(LCLS_STS_not_yet_ls));</span><br><span style="color: hsl(120, 100%, 40%);">+   f_lcls_test_fini();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Send an ASSIGNMENT REQ with "do not connect" and enable later using LCLS CTRL */</span><br><span style="color: hsl(120, 100%, 40%);">+testcase TC_lcls_gcr_bway_dont_connect_csc() runs on lcls_test_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+  var TestHdlrParams pars_a := valueof(t_def_TestHdlrPars);</span><br><span style="color: hsl(120, 100%, 40%);">+     var TestHdlrParams pars_b;</span><br><span style="color: hsl(120, 100%, 40%);">+    var MSC_ConnHdlr vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+     var MgcpCommand mgcp_cmd;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   f_lcls_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      pars_a.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));</span><br><span style="color: hsl(120, 100%, 40%);">+       pars_a.lcls.gcr := valueof(ts_GCR('010203'O, '0405'O, '060708090a'O));</span><br><span style="color: hsl(120, 100%, 40%);">+        pars_a.lcls.cfg := LCLS_CFG_both_way;</span><br><span style="color: hsl(120, 100%, 40%);">+ pars_a.lcls.csc := LCLS_CSC_do_not_connect;</span><br><span style="color: hsl(120, 100%, 40%);">+   pars_b := pars_a;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* first call is not possible to be LS (no second leg yet) */</span><br><span style="color: hsl(120, 100%, 40%);">+ pars_a.lcls.exp_sts := LCLS_STS_not_possible_ls;</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Expect LCLS is *NOT* established */</span><br><span style="color: hsl(120, 100%, 40%);">+        pars_b.lcls.exp_sts := LCLS_STS_not_yet_ls;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* start call and expect it to be "not yet" LS */</span><br><span style="color: hsl(120, 100%, 40%);">+   f_lcls_test_init(pars_a, pars_b);</span><br><span style="color: hsl(120, 100%, 40%);">+     CONN_A.receive(LclsCompSync:LCLS_COMP_SYNC_ASS_COMPL);</span><br><span style="color: hsl(120, 100%, 40%);">+        CONN_B.receive(LclsCompSync:LCLS_COMP_SYNC_ASS_COMPL);</span><br><span style="color: hsl(120, 100%, 40%);">+        CONN_A.receive(tr_BSSMAP_LclsNotificationSts(LCLS_STS_not_yet_ls));</span><br><span style="color: hsl(120, 100%, 40%);">+   f_sleep(2.0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* send "connect" on A side, expect call to remain in "not yet" */</span><br><span style="color: hsl(120, 100%, 40%);">+        CONN_A.send(ts_BSSMAP_LclsConnCtrl(omit, ts_BSSMAP_IE_LclsCsc(LCLS_CSC_connect)));</span><br><span style="color: hsl(120, 100%, 40%);">+    CONN_A.receive(tr_BSSMAP_LclsConnCtrlAck(tr_BSSMAP_IE_LclsSts(LCLS_STS_not_yet_ls)));</span><br><span style="color: hsl(120, 100%, 40%);">+ f_sleep(2.0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* send "connect" on B side, expect call to go LS, with notify to A side */</span><br><span style="color: hsl(120, 100%, 40%);">+ CONN_B.send(ts_BSSMAP_LclsConnCtrl(omit, ts_BSSMAP_IE_LclsCsc(LCLS_CSC_connect)));</span><br><span style="color: hsl(120, 100%, 40%);">+    interleave {</span><br><span style="color: hsl(120, 100%, 40%);">+  [] CONN_B.receive(tr_BSSMAP_LclsConnCtrlAck(tr_BSSMAP_IE_LclsSts(LCLS_STS_locally_switched)));</span><br><span style="color: hsl(120, 100%, 40%);">+        [] CONN_A.receive(tr_BSSMAP_LclsNotificationSts(LCLS_STS_locally_switched));</span><br><span style="color: hsl(120, 100%, 40%);">+  [] CONN_A.receive(tr_MDCX) -> value mgcp_cmd {</span><br><span style="color: hsl(120, 100%, 40%);">+             CONN_A.send(f_build_mdcx_rsp(mgcp_cmd));</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+     [] CONN_B.receive(tr_MDCX) -> value mgcp_cmd {</span><br><span style="color: hsl(120, 100%, 40%);">+             CONN_B.send(f_build_mdcx_rsp(mgcp_cmd));</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     f_wait_fail_notify();</span><br><span style="color: hsl(120, 100%, 40%);">+ f_lcls_test_fini();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_build_mdcx_rsp(MgcpCommand mdcx) return MgcpResponse</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  var MgcpConnectionId conn_id := f_MgcpCmd_extract_conn_id(mdcx);</span><br><span style="color: hsl(120, 100%, 40%);">+      var SDP_Message sdp_in := mdcx.sdp;</span><br><span style="color: hsl(120, 100%, 40%);">+   var MgcpResponse resp;</span><br><span style="color: hsl(120, 100%, 40%);">+        var SDP_Message sdp_out;</span><br><span style="color: hsl(120, 100%, 40%);">+      var integer rtp_pt := str2int(sdp_in.media_list[0].media_field.fmts[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    sdp_out := valueof(ts_SDP(sdp_in.connection.conn_addr.addr, sdp_in.connection.conn_addr.addr,</span><br><span style="color: hsl(120, 100%, 40%);">+                           "foo", "21", sdp_in.media_list[0].media_field.ports.port_number,</span><br><span style="color: hsl(120, 100%, 40%);">+                                  { int2str(rtp_pt) },</span><br><span style="color: hsl(120, 100%, 40%);">+                                  { valueof(ts_SDP_rtpmap(rtp_pt, "AMR/8000")),</span><br><span style="color: hsl(120, 100%, 40%);">+                                 valueof(ts_SDP_ptime(20)) } ));</span><br><span style="color: hsl(120, 100%, 40%);">+   return valueof(ts_MDCX_ACK(mdcx.line.trans_id, conn_id, sdp_out));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Establish LCLS "connect" followed by a MSC-initiated break */</span><br><span style="color: hsl(120, 100%, 40%);">+testcase TC_lcls_connect_break() runs on lcls_test_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+  var TestHdlrParams pars_a := valueof(t_def_TestHdlrPars);</span><br><span style="color: hsl(120, 100%, 40%);">+     var TestHdlrParams pars_b;</span><br><span style="color: hsl(120, 100%, 40%);">+    var MSC_ConnHdlr vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+     var MgcpCommand mgcp_cmd;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   f_lcls_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      pars_a.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));</span><br><span style="color: hsl(120, 100%, 40%);">+       pars_a.lcls.gcr := valueof(ts_GCR('010203'O, '0405'O, '060708090a'O));</span><br><span style="color: hsl(120, 100%, 40%);">+        pars_a.lcls.cfg := LCLS_CFG_both_way;</span><br><span style="color: hsl(120, 100%, 40%);">+ pars_a.lcls.csc := LCLS_CSC_connect;</span><br><span style="color: hsl(120, 100%, 40%);">+  pars_b := pars_a;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* first call is not possible to be LS (no second leg yet) */</span><br><span style="color: hsl(120, 100%, 40%);">+ pars_a.lcls.exp_sts := LCLS_STS_not_possible_ls;</span><br><span style="color: hsl(120, 100%, 40%);">+      /* second call should then reuslt in LS */</span><br><span style="color: hsl(120, 100%, 40%);">+    pars_b.lcls.exp_sts := LCLS_STS_locally_switched;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Expect LS to be established successfully */</span><br><span style="color: hsl(120, 100%, 40%);">+        f_lcls_test_init(pars_a, pars_b);</span><br><span style="color: hsl(120, 100%, 40%);">+     CONN_A.receive(LclsCompSync:LCLS_COMP_SYNC_ASS_COMPL);</span><br><span style="color: hsl(120, 100%, 40%);">+        interleave {</span><br><span style="color: hsl(120, 100%, 40%);">+  [] CONN_A.receive(tr_BSSMAP_LclsNotificationSts(LCLS_STS_not_yet_ls));</span><br><span style="color: hsl(120, 100%, 40%);">+        [] CONN_A.receive(tr_BSSMAP_LclsNotificationSts(LCLS_STS_locally_switched));</span><br><span style="color: hsl(120, 100%, 40%);">+  [] CONN_B.receive(LclsCompSync:LCLS_COMP_SYNC_ASS_COMPL);</span><br><span style="color: hsl(120, 100%, 40%);">+     [] CONN_A.receive(tr_MDCX) -> value mgcp_cmd {</span><br><span style="color: hsl(120, 100%, 40%);">+             CONN_A.send(f_build_mdcx_rsp(mgcp_cmd));</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+/* not needed, as this MDCX is still handled within MSC_ConnectionHandler</span><br><span style="color: hsl(120, 100%, 40%);">+  [] CONN_B.receive(tr_MDCX) -> value mgcp_cmd {</span><br><span style="color: hsl(120, 100%, 40%);">+             CONN_B.send(f_build_mdcx_rsp(mgcp_cmd));</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+*/</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* request LS release on "A" side; call continues to be locally switched */</span><br><span style="color: hsl(120, 100%, 40%);">+ CONN_A.send(ts_BSSMAP_LclsConnCtrl(omit, ts_BSSMAP_IE_LclsCsc(LCLS_CSC_release_lcls)));</span><br><span style="color: hsl(120, 100%, 40%);">+       CONN_A.receive(tr_BSSMAP_LclsConnCtrlAck(tr_BSSMAP_IE_LclsSts(LCLS_STS_locally_switched)));</span><br><span style="color: hsl(120, 100%, 40%);">+   f_sleep(2.0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* request LS release on "B" side; call LS is released */</span><br><span style="color: hsl(120, 100%, 40%);">+   CONN_B.send(ts_BSSMAP_LclsConnCtrl(omit, ts_BSSMAP_IE_LclsCsc(LCLS_CSC_release_lcls)));</span><br><span style="color: hsl(120, 100%, 40%);">+       interleave {</span><br><span style="color: hsl(120, 100%, 40%);">+  [] CONN_A.receive(tr_MDCX) -> value mgcp_cmd {</span><br><span style="color: hsl(120, 100%, 40%);">+             CONN_A.send(f_build_mdcx_rsp(mgcp_cmd));</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+     [] CONN_B.receive(tr_MDCX) -> value mgcp_cmd {</span><br><span style="color: hsl(120, 100%, 40%);">+             CONN_B.send(f_build_mdcx_rsp(mgcp_cmd));</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+     [] CONN_B.receive(tr_BSSMAP_LclsConnCtrlAck(tr_BSSMAP_IE_LclsSts(LCLS_STS_no_longer_ls)));</span><br><span style="color: hsl(120, 100%, 40%);">+    [] CONN_A.receive(tr_BSSMAP_LclsNotificationSts(LCLS_STS_no_longer_ls));</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   f_lcls_test_fini();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Establish LCLS "connect" followed by a SCCP-level release of one leg */</span><br><span style="color: hsl(120, 100%, 40%);">+testcase TC_lcls_connect_clear() runs on lcls_test_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+       var TestHdlrParams pars_a := valueof(t_def_TestHdlrPars);</span><br><span style="color: hsl(120, 100%, 40%);">+     var TestHdlrParams pars_b;</span><br><span style="color: hsl(120, 100%, 40%);">+    var MSC_ConnHdlr vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+     var MgcpCommand mgcp_cmd;</span><br><span style="color: hsl(120, 100%, 40%);">+     var RSL_Message rsl;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        f_lcls_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      pars_a.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));</span><br><span style="color: hsl(120, 100%, 40%);">+       pars_a.lcls.gcr := valueof(ts_GCR('010203'O, '0405'O, '060708090a'O));</span><br><span style="color: hsl(120, 100%, 40%);">+        pars_a.lcls.cfg := LCLS_CFG_both_way;</span><br><span style="color: hsl(120, 100%, 40%);">+ pars_a.lcls.csc := LCLS_CSC_connect;</span><br><span style="color: hsl(120, 100%, 40%);">+  pars_b := pars_a;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* first call is not possible to be LS (no second leg yet) */</span><br><span style="color: hsl(120, 100%, 40%);">+ pars_a.lcls.exp_sts := LCLS_STS_not_possible_ls;</span><br><span style="color: hsl(120, 100%, 40%);">+      /* second call should then reuslt in LS */</span><br><span style="color: hsl(120, 100%, 40%);">+    pars_b.lcls.exp_sts := LCLS_STS_locally_switched;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Expect LS to be established successfully */</span><br><span style="color: hsl(120, 100%, 40%);">+        f_lcls_test_init(pars_a, pars_b);</span><br><span style="color: hsl(120, 100%, 40%);">+     CONN_A.receive(LclsCompSync:LCLS_COMP_SYNC_ASS_COMPL);</span><br><span style="color: hsl(120, 100%, 40%);">+        interleave {</span><br><span style="color: hsl(120, 100%, 40%);">+  [] CONN_A.receive(tr_BSSMAP_LclsNotificationSts(LCLS_STS_not_yet_ls));</span><br><span style="color: hsl(120, 100%, 40%);">+        [] CONN_A.receive(tr_BSSMAP_LclsNotificationSts(LCLS_STS_locally_switched));</span><br><span style="color: hsl(120, 100%, 40%);">+  [] CONN_B.receive(LclsCompSync:LCLS_COMP_SYNC_ASS_COMPL);</span><br><span style="color: hsl(120, 100%, 40%);">+     [] CONN_A.receive(tr_MDCX) -> value mgcp_cmd {</span><br><span style="color: hsl(120, 100%, 40%);">+             CONN_A.send(f_build_mdcx_rsp(mgcp_cmd));</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Perform hard BSSMAP Clear on "A" side, expect no LS on "B" side */</span><br><span style="color: hsl(120, 100%, 40%);">+     var myBSSMAP_Cause cause_val := GSM0808_CAUSE_CALL_CONTROL;</span><br><span style="color: hsl(120, 100%, 40%);">+   var octetstring l3_rr_chan_rel := '060D00'O;</span><br><span style="color: hsl(120, 100%, 40%);">+  CONN_A.send(ts_BSSMAP_ClearCommand(enum2int(cause_val)));</span><br><span style="color: hsl(120, 100%, 40%);">+     interleave {</span><br><span style="color: hsl(120, 100%, 40%);">+  [] CONN_A.receive(tr_RSL_DATA_REQ(?, tr_RslLinkID_DCCH(0), l3_rr_chan_rel));</span><br><span style="color: hsl(120, 100%, 40%);">+  [] CONN_A.receive(tr_RSL_DEACT_SACCH(?));</span><br><span style="color: hsl(120, 100%, 40%);">+     [] CONN_A.receive(tr_RSL_RF_CHAN_REL(?)) -> value rsl {</span><br><span style="color: hsl(120, 100%, 40%);">+            var RSL_IE_Body ieb;</span><br><span style="color: hsl(120, 100%, 40%);">+          f_rsl_find_ie(rsl, RSL_IE_CHAN_NR, ieb);</span><br><span style="color: hsl(120, 100%, 40%);">+              CONN_A.send(ts_RSL_RF_CHAN_REL_ACK(ieb.chan_nr));</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+     [] CONN_A.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);</span><br><span style="color: hsl(120, 100%, 40%);">+    [] CONN_A.receive(tr_BSSMAP_ClearComplete);</span><br><span style="color: hsl(120, 100%, 40%);">+   [] CONN_B.receive(tr_BSSMAP_LclsNotificationSts(LCLS_STS_not_possible_ls));</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     f_sleep(2.0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       f_lcls_test_fini();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* TODO:</span><br><span style="color: hsl(120, 100%, 40%);">+      * verify IP/Port information in LCLS-triggered MDCX</span><br><span style="color: hsl(120, 100%, 40%);">+   * establish with one side connect, then enable using LCLS CTRL</span><br><span style="color: hsl(120, 100%, 40%);">+        * LCLS CTRL for call that doesn't have LCLS enabled</span><br><span style="color: hsl(120, 100%, 40%);">+       * LCLS IEs without GCR in ASS CMD</span><br><span style="color: hsl(120, 100%, 40%);">+     * GCR updates?</span><br><span style="color: hsl(120, 100%, 40%);">+        * Handover related LCLS bits (after we have inter-BSC HO in OsmoBSC)</span><br><span style="color: hsl(120, 100%, 40%);">+*/</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+control {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     execute( TC_lcls_gcr_only() );</span><br><span style="color: hsl(120, 100%, 40%);">+        execute( TC_lcls_gcr_bway_connect() );</span><br><span style="color: hsl(120, 100%, 40%);">+        execute( TC_lcls_gcr_nomatch_bway_connect() );</span><br><span style="color: hsl(120, 100%, 40%);">+        execute( TC_lcls_gcr_bway_dont_connect() );</span><br><span style="color: hsl(120, 100%, 40%);">+   execute( TC_lcls_gcr_unsuppported_cfg() );</span><br><span style="color: hsl(120, 100%, 40%);">+    execute( TC_lcls_gcr_unsuppported_csc() );</span><br><span style="color: hsl(120, 100%, 40%);">+    execute( TC_lcls_gcr_bway_dont_connect_csc() );</span><br><span style="color: hsl(120, 100%, 40%);">+       execute( TC_lcls_connect_break() );</span><br><span style="color: hsl(120, 100%, 40%);">+   execute( TC_lcls_connect_clear() );</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/bsc/MSC_ConnectionHandler.ttcn b/bsc/MSC_ConnectionHandler.ttcn</span><br><span>index 16a0547..225e86b 100644</span><br><span>--- a/bsc/MSC_ConnectionHandler.ttcn</span><br><span>+++ b/bsc/MSC_ConnectionHandler.ttcn</span><br><span>@@ -356,6 +356,15 @@</span><br><span>        enc_key := key</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+type record TestHdlrParamsLcls {</span><br><span style="color: hsl(120, 100%, 40%);">+     GlobalCallReferenceValue gcr optional,</span><br><span style="color: hsl(120, 100%, 40%);">+        /* LCLS Configuration */</span><br><span style="color: hsl(120, 100%, 40%);">+      BIT4 cfg optional,</span><br><span style="color: hsl(120, 100%, 40%);">+    /* LCLS Connection Status Control */</span><br><span style="color: hsl(120, 100%, 40%);">+  BIT4 csc optional,</span><br><span style="color: hsl(120, 100%, 40%);">+    BIT4 exp_sts optional</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> type record TestHdlrParams {</span><br><span>   OCT1            ra,</span><br><span>  GsmFrameNumber  fn,</span><br><span>@@ -363,7 +372,8 @@</span><br><span>    RslLinkId       link_id,</span><br><span>     integer         media_nr, /* determins MGCP EP, port numbers */</span><br><span>      BSSMAP_IE_SpeechCodecList ass_codec_list optional,</span><br><span style="color: hsl(0, 100%, 40%);">-      TestHdlrEncrParams encr optional</span><br><span style="color: hsl(120, 100%, 40%);">+      TestHdlrEncrParams encr optional,</span><br><span style="color: hsl(120, 100%, 40%);">+     TestHdlrParamsLcls lcls</span><br><span> };</span><br><span> </span><br><span> template (value) TestHdlrParams t_def_TestHdlrPars := {</span><br><span>@@ -373,7 +383,13 @@</span><br><span>  link_id := valueof(ts_RslLinkID_DCCH(0)),</span><br><span>    media_nr := 1,</span><br><span>       ass_codec_list := omit,</span><br><span style="color: hsl(0, 100%, 40%);">- encr := omit</span><br><span style="color: hsl(120, 100%, 40%);">+  encr := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ lcls := {</span><br><span style="color: hsl(120, 100%, 40%);">+             gcr := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+          cfg := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+          csc := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+          exp_sts := omit</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span> }</span><br><span> </span><br><span> function f_create_chan_and_exp() runs on MSC_ConnHdlr {</span><br><span>@@ -711,11 +727,36 @@</span><br><span>        }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* patch an BSSMAP ASS REQ with LCLS related IEs, depending on g_params */</span><br><span style="color: hsl(120, 100%, 40%);">+function f_ass_patch_lcls(inout template (omit) PDU_BSSAP ass_tpl,</span><br><span style="color: hsl(120, 100%, 40%);">+                      inout template PDU_BSSAP ass_cpl) runs on MSC_ConnHdlr {</span><br><span style="color: hsl(120, 100%, 40%);">+    if (istemplatekind(ass_tpl, "omit")) {</span><br><span style="color: hsl(120, 100%, 40%);">+              return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (ispresent(g_pars.lcls.gcr)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             ass_tpl.pdu.bssmap.assignmentRequest.globalCallReference := ts_BSSMAP_IE_GCR(g_pars.lcls.gcr);</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (ispresent(g_pars.lcls.cfg)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             ass_tpl.pdu.bssmap.assignmentRequest.lCLS_Configuration := ts_BSSMAP_IE_LclsCfg(g_pars.lcls.cfg);</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (ispresent(g_pars.lcls.csc)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             ass_tpl.pdu.bssmap.assignmentRequest.lCLS_ConnectionStatusControl := ts_BSSMAP_IE_LclsCsc(g_pars.lcls.csc);</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (ispresent(g_pars.lcls.exp_sts)) {</span><br><span style="color: hsl(120, 100%, 40%);">+         ass_cpl.pdu.bssmap.assignmentComplete.lCLS_BSS_Status := tr_BSSMAP_IE_LclsSts(g_pars.lcls.exp_sts);</span><br><span style="color: hsl(120, 100%, 40%);">+   } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              ass_cpl.pdu.bssmap.assignmentComplete.lCLS_BSS_Status := omit;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* establish a channel fully, expecting an assignment matching 'exp' */</span><br><span> function f_establish_fully(template (omit) PDU_BSSAP ass_tpl, template PDU_BSSAP exp_ass_cpl)</span><br><span> runs on MSC_ConnHdlr {</span><br><span>         f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3");</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+        /* patch in the LCLS related items, as needed */</span><br><span style="color: hsl(120, 100%, 40%);">+      f_ass_patch_lcls(ass_tpl, exp_ass_cpl);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>    f_create_chan_and_exp();</span><br><span>     /* we should now have a COMPL_L3 at the MSC */</span><br><span>       BSSAP.receive(tr_BSSMAP_ComplL3);</span><br><span>diff --git a/library/BSSMAP_Templates.ttcn b/library/BSSMAP_Templates.ttcn</span><br><span>index ad90d66..d92ea61 100644</span><br><span>--- a/library/BSSMAP_Templates.ttcn</span><br><span>+++ b/library/BSSMAP_Templates.ttcn</span><br><span>@@ -1136,6 +1136,18 @@</span><br><span>  }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+template PDU_BSSAP tr_BSSMAP_LclsNotificationSts(BIT4 sts)</span><br><span style="color: hsl(120, 100%, 40%);">+modifies tr_BSSAP_BSSMAP := {</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu := {</span><br><span style="color: hsl(120, 100%, 40%);">+              bssmap := {</span><br><span style="color: hsl(120, 100%, 40%);">+                   lCLS_Notification := {</span><br><span style="color: hsl(120, 100%, 40%);">+                                messageType := '76'O,</span><br><span style="color: hsl(120, 100%, 40%);">+                         lCLS_BSS_Status := tr_BSSMAP_IE_LclsSts(sts),</span><br><span style="color: hsl(120, 100%, 40%);">+                         lCLS_BreakRequest := omit</span><br><span style="color: hsl(120, 100%, 40%);">+                     }</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span> </span><br><span> </span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/9412">change 9412</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/9412"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-ttcn3-hacks </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: Ie6d0b9c38027abf65c7c564fc79b889d013fa6a7 </div>
<div style="display:none"> Gerrit-Change-Number: 9412 </div>
<div style="display:none"> Gerrit-PatchSet: 4 </div>
<div style="display:none"> Gerrit-Owner: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>