<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/18333">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  laforge: Looks good to me, but someone else must approve
  Vadim Yanitskiy: Looks good to me, approved
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Move all GPRS helper function to its own file and component<br><br>This is a first step towards refactoring of all functions to use MS and<br>Ul/DlTBF objects containing state.<br><br>Change-Id: Ieae27d6e707f79ec2145864ef5cd67ddbbec9314<br>---<br>A pcu/GPRS_Components.ttcn<br>M pcu/PCU_Tests.ttcn<br>M pcu/PCU_selftest.ttcn<br>3 files changed, 623 insertions(+), 571 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/pcu/GPRS_Components.ttcn b/pcu/GPRS_Components.ttcn</span><br><span>new file mode 100644</span><br><span>index 0000000..c3ec440</span><br><span>--- /dev/null</span><br><span>+++ b/pcu/GPRS_Components.ttcn</span><br><span>@@ -0,0 +1,620 @@</span><br><span style="color: hsl(120, 100%, 40%);">+module GPRS_Components {</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Osmocom PCU test suite in TTCN-3, components for GPRS handlng</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2018-2019 Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2019 Vadim Yanitskiy <axilirator@gmail.com></span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2020 by sysmocom s.f.m.c. GmbH <info@sysmocom.de></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%);">+ * SPDX-License-Identifier: GPL-2.0-or-later</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 GSM_RR_Types 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_GMM_SM_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from RLCMAC_CSN1_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from RLCMAC_CSN1_Templates all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from RLCMAC_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from RLCMAC_Templates 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 L3_Templates all;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import from NS_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from BSSGP_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from Osmocom_Gb_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import from BSSGP_Emulation all; /* BssgpConfig */</span><br><span style="color: hsl(120, 100%, 40%);">+import from NS_Emulation all; /* NSConfiguration */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import from UD_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from PCUIF_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from PCUIF_CodecPort all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from PCUIF_Components all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from IPL4asp_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from Native_Functions all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from SGSN_Components all;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+type component MS_BTS_IFACE_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Virtual BTS component */</span><br><span style="color: hsl(120, 100%, 40%);">+   var RAW_PCU_BTS_CT vc_BTS;</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Connection to the BTS component (one for now) */</span><br><span style="color: hsl(120, 100%, 40%);">+   port RAW_PCU_MSG_PT BTS;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Value at which Countdown Procedure starts. Announced by network (GPRS Cell Options as per TS 04.60 Chapter 12.24) */</span><br><span style="color: hsl(120, 100%, 40%);">+       var uint4_t g_bs_cv_max := 4;</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 f_shutdown(charstring file, integer line,</span><br><span style="color: hsl(120, 100%, 40%);">+                    boolean final := false)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Determine if the test case was aborted in the middle */</span><br><span style="color: hsl(120, 100%, 40%);">+    if (not final) {</span><br><span style="color: hsl(120, 100%, 40%);">+              log("Test case ", testcasename(), " aborted at ", file, ":", line);</span><br><span style="color: hsl(120, 100%, 40%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              /* Guard verdict to avoid 'none' */</span><br><span style="color: hsl(120, 100%, 40%);">+           setverdict(pass);</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%);">+   /* Properly shutdown virtual BTS and its clock generator */</span><br><span style="color: hsl(120, 100%, 40%);">+   BTS.send(ts_RAW_PCU_CMD(GENERAL_CMD_SHUTDOWN));</span><br><span style="color: hsl(120, 100%, 40%);">+       vc_BTS.done; /* wait untill it's done */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Shutdown the others and MTC */</span><br><span style="color: hsl(120, 100%, 40%);">+     all component.stop;</span><br><span style="color: hsl(120, 100%, 40%);">+   mtc.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%);">+template AckNackDescription t_AckNackDescription_init := {</span><br><span style="color: hsl(120, 100%, 40%);">+    final_ack := '0'B,</span><br><span style="color: hsl(120, 100%, 40%);">+    starting_seq_nr := 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ receive_block_bitmap := '0000000000000000000000000000000000000000000000000000000000000000'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%);">+function f_rlcmac_dl_block_get_tfi(RlcmacDlBlock dl_block)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT return uint5_t {</span><br><span style="color: hsl(120, 100%, 40%);">+        if (ischosen(dl_block.data)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                return dl_block.data.mac_hdr.hdr_ext.tfi;</span><br><span style="color: hsl(120, 100%, 40%);">+     } else if (ischosen(dl_block.data_egprs)) {</span><br><span style="color: hsl(120, 100%, 40%);">+           return dl_block.data_egprs.mac_hdr.tfi;</span><br><span style="color: hsl(120, 100%, 40%);">+       } else { /* Ctrl block */</span><br><span style="color: hsl(120, 100%, 40%);">+             if (match(dl_block, tr_RLCMAC_UL_PACKET_ASS_GPRS(?, tr_PktUlAssGprsDynamic(tr_DynamicAllocation(?))))) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      return dl_block.ctrl.payload.u.ul_assignment.gprs.dyn_block_alloc.ul_tfi_assignment;</span><br><span style="color: hsl(120, 100%, 40%);">+          }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (match(dl_block, tr_RLCMAC_UL_PACKET_ASS_EGPRS(?, tr_PktUlAssEgprsDynamic(tr_DynamicAllocation(?))))) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    return dl_block.ctrl.payload.u.ul_assignment.egprs.dyn_block_alloc.ul_tfi_assignment;</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%);">+     setverdict(fail, "DlBlock doesn't contain a TFI:", dl_block);</span><br><span style="color: hsl(120, 100%, 40%);">+   f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(120, 100%, 40%);">+      return 0; /* make compiler happy */</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%);">+/* Get the Chan coding command from a dl block containing PACCH UL Assignment */</span><br><span style="color: hsl(120, 100%, 40%);">+function f_rlcmac_dl_block_get_assigned_ul_cs_mcs(RlcmacDlBlock dl_block)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT return CodingScheme {</span><br><span style="color: hsl(120, 100%, 40%);">+  if (match(dl_block, tr_RLCMAC_UL_PACKET_ASS_GPRS(?, tr_PktUlAssGprsDynamic(?)))) {</span><br><span style="color: hsl(120, 100%, 40%);">+            return f_rlcmac_block_ChCodingCommand2cs_mcs(dl_block.ctrl.payload.u.ul_assignment.gprs.ch_coding_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (match(dl_block, tr_RLCMAC_UL_PACKET_ASS_EGPRS(?, tr_PktUlAssEgprsDynamic(?)))) {</span><br><span style="color: hsl(120, 100%, 40%);">+          return f_rlcmac_block_EgprsChCodingCommand2cs_mcs(dl_block.ctrl.payload.u.ul_assignment.egprs.chan_coding_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     setverdict(fail, "DlBlock doesn't contain CS_MCS information:", dl_block);</span><br><span style="color: hsl(120, 100%, 40%);">+      f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(120, 100%, 40%);">+      return CS_1; /* make compiler happy */</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%);">+/* TS 44.060 sec 12.3 Ack/Nack Description */</span><br><span style="color: hsl(120, 100%, 40%);">+function f_acknackdesc_ack_block(inout AckNackDescription desc, RlcmacDlBlock dl_block, BIT1 final_ack := '0'B)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        var uint7_t bsn;</span><br><span style="color: hsl(120, 100%, 40%);">+      var integer i;</span><br><span style="color: hsl(120, 100%, 40%);">+        var integer inc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (ischosen(dl_block.data)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                bsn := dl_block.data.mac_hdr.hdr_ext.bsn;</span><br><span style="color: hsl(120, 100%, 40%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              bsn := dl_block.data_egprs.mac_hdr.bsn1;</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%);">+   inc := bsn - desc.starting_seq_nr + 1;</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Filling hole? */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (bsn < desc.starting_seq_nr) {</span><br><span style="color: hsl(120, 100%, 40%);">+          desc.receive_block_bitmap[lengthof(desc.receive_block_bitmap) - (desc.starting_seq_nr - bsn)] := int2bit(1, 1);</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* SSN is increased, and so RBB values need to be moved */</span><br><span style="color: hsl(120, 100%, 40%);">+    for (i := 0; i < lengthof(desc.receive_block_bitmap) - inc; i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+            desc.receive_block_bitmap[i] := desc.receive_block_bitmap[i + inc];</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     for (i := lengthof(desc.receive_block_bitmap) - inc; i < lengthof(desc.receive_block_bitmap) - 1; i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+              desc.receive_block_bitmap[i] := int2bit(0, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Now we can set current bit and update SSN */</span><br><span style="color: hsl(120, 100%, 40%);">+       desc.starting_seq_nr := bsn + 1;</span><br><span style="color: hsl(120, 100%, 40%);">+      desc.receive_block_bitmap[lengthof(desc.receive_block_bitmap) - 1] := int2bit(1, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Finally update the final_ack bit as requested: */</span><br><span style="color: hsl(120, 100%, 40%);">+  desc.final_ack := final_ack;</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%);">+/* This function can be used to send DATA.cnf in response to the IUT originated DATA.req.</span><br><span style="color: hsl(120, 100%, 40%);">+ * NOTE: it's the responsibility of caller to make sure that pcu_msg contains u.data_req. */</span><br><span style="color: hsl(120, 100%, 40%);">+function f_pcuif_tx_data_cnf(in PCUIF_Message pcu_msg)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+     var PCUIF_Message pcu_msg_cnf := {</span><br><span style="color: hsl(120, 100%, 40%);">+            msg_type := PCU_IF_MSG_DATA_CNF,</span><br><span style="color: hsl(120, 100%, 40%);">+              bts_nr := pcu_msg.bts_nr,</span><br><span style="color: hsl(120, 100%, 40%);">+             spare := pcu_msg.spare,</span><br><span style="color: hsl(120, 100%, 40%);">+               u := { data_cnf := pcu_msg.u.data_req }</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%);">+  /* PCU wants DATA.cnf containing basically everything that was in DATA.req,</span><br><span style="color: hsl(120, 100%, 40%);">+    * but PCU_IF_SAPI_PCH is a special case - paging group shall be excluded. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (pcu_msg.u.data_req.sapi == PCU_IF_SAPI_PCH) {</span><br><span style="color: hsl(120, 100%, 40%);">+             pcu_msg_cnf.u.data_cnf.data := substr(pcu_msg.u.data_req.data, 3,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                   pcu_msg.u.data_req.len - 3);</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%);">+   BTS.send(pcu_msg_cnf);</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 f_pcuif_rx_imm_ass(out GsmRrMessage rr_imm_ass,</span><br><span style="color: hsl(120, 100%, 40%);">+                     template PCUIF_Sapi sapi := PCU_IF_SAPI_AGCH,</span><br><span style="color: hsl(120, 100%, 40%);">+                         template GsmRrMessage t_imm_ass := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+                         uint8_t bts_nr := 0)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT return boolean {</span><br><span style="color: hsl(120, 100%, 40%);">+    var PCUIF_Message pcu_msg;</span><br><span style="color: hsl(120, 100%, 40%);">+    var octetstring data;</span><br><span style="color: hsl(120, 100%, 40%);">+ timer T;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    T.start(2.0);</span><br><span style="color: hsl(120, 100%, 40%);">+ alt {</span><br><span style="color: hsl(120, 100%, 40%);">+ [] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := bts_nr, trx_nr := 0, ts_nr := 0,</span><br><span style="color: hsl(120, 100%, 40%);">+                                    sapi := sapi, data := ?)) -> value pcu_msg {</span><br><span style="color: hsl(120, 100%, 40%);">+              /* On PCH the payload is prefixed with paging group (3 octets): skip it.</span><br><span style="color: hsl(120, 100%, 40%);">+               * TODO: add an additional template parameter, so we can match it. */</span><br><span style="color: hsl(120, 100%, 40%);">+         if (pcu_msg.u.data_req.sapi == PCU_IF_SAPI_PCH) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     data := substr(pcu_msg.u.data_req.data, 3, pcu_msg.u.data_req.len - 3);</span><br><span style="color: hsl(120, 100%, 40%);">+               } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      data := pcu_msg.u.data_req.data;</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%);">+           rr_imm_ass := dec_GsmRrMessage(data);</span><br><span style="color: hsl(120, 100%, 40%);">+         if (not match(rr_imm_ass, t_imm_ass)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       /* Not for us? Wait for more. */</span><br><span style="color: hsl(120, 100%, 40%);">+                      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%);">+           log("Rx Immediate Assignment: ", rr_imm_ass);</span><br><span style="color: hsl(120, 100%, 40%);">+               setverdict(pass);</span><br><span style="color: hsl(120, 100%, 40%);">+             return true;</span><br><span style="color: hsl(120, 100%, 40%);">+          }</span><br><span style="color: hsl(120, 100%, 40%);">+     [] BTS.receive { repeat; }</span><br><span style="color: hsl(120, 100%, 40%);">+    [] T.timeout {</span><br><span style="color: hsl(120, 100%, 40%);">+                setverdict(fail, "Timeout waiting for Immediate Assignment");</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%);">+   return false;</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%);">+/* One phase packet access (see 3GPP TS 44.018, table 9.1.8.1) */</span><br><span style="color: hsl(120, 100%, 40%);">+const BIT8 chan_req_def := '01111000'B;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Establish an Uplink TBF by sending RACH.ind towards the PCU */</span><br><span style="color: hsl(120, 100%, 40%);">+function f_establish_tbf(out GsmRrMessage rr_imm_ass, uint8_t bts_nr := 0,</span><br><span style="color: hsl(120, 100%, 40%);">+                        uint16_t ra := bit2int(chan_req_def),</span><br><span style="color: hsl(120, 100%, 40%);">+                         uint8_t is_11bit := 0,</span><br><span style="color: hsl(120, 100%, 40%);">+                        PCUIF_BurstType burst_type := BURST_TYPE_0,</span><br><span style="color: hsl(120, 100%, 40%);">+                   TimingAdvance ta := 0)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT return boolean {</span><br><span style="color: hsl(120, 100%, 40%);">+     var uint32_t fn;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* FIXME: ask the BTS component to give us the current TDMA fn */</span><br><span style="color: hsl(120, 100%, 40%);">+     fn := 1337 + ta;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Send RACH.ind */</span><br><span style="color: hsl(120, 100%, 40%);">+   log("Sending RACH.ind on fn=", fn, " with RA=", ra, ", TA=", ta);</span><br><span style="color: hsl(120, 100%, 40%);">+       BTS.send(ts_PCUIF_RACH_IND(bts_nr := bts_nr, trx_nr := 0, ts_nr := 0,</span><br><span style="color: hsl(120, 100%, 40%);">+                            ra := ra, is_11bit := is_11bit,</span><br><span style="color: hsl(120, 100%, 40%);">+                               burst_type := burst_type,</span><br><span style="color: hsl(120, 100%, 40%);">+                             fn := fn, arfcn := 871,</span><br><span style="color: hsl(120, 100%, 40%);">+                               qta := ta * 4));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 3GPP TS 44.018, table 9.1.8.1, note 2b: Request Reference shall be set to 127</span><br><span style="color: hsl(120, 100%, 40%);">+       * when Immediate Assignment is triggered by EGPRS Packet Channel Request. Here</span><br><span style="color: hsl(120, 100%, 40%);">+        * we assume that 11 bit RA always contains EGPRS Packet Channel Request. */</span><br><span style="color: hsl(120, 100%, 40%);">+  if (is_11bit != 0) { ra := 127; }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Expect Immediate (TBF) Assignment on TS0/AGCH */</span><br><span style="color: hsl(120, 100%, 40%);">+   return f_pcuif_rx_imm_ass(rr_imm_ass, PCU_IF_SAPI_AGCH,</span><br><span style="color: hsl(120, 100%, 40%);">+                                 tr_IMM_TBF_ASS(false, ra, fn),</span><br><span style="color: hsl(120, 100%, 40%);">+                                bts_nr := bts_nr);</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 f_imm_ass_verify_ul_tbf_ass(in GsmRrMessage rr_imm_ass, out PacketUlAssign ul_tbf_ass, template PacketUlAssign ul_ass := tr_PacketUlDynAssign)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Make sure we received an UL TBF Assignment */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (match(rr_imm_ass, tr_IMM_TBF_ASS(dl := false, rest := tr_IaRestOctets_ULAss(ul_ass)))) {</span><br><span style="color: hsl(120, 100%, 40%);">+          ul_tbf_ass := rr_imm_ass.payload.imm_ass.rest_octets.hh.pa.uldl.ass.ul;</span><br><span style="color: hsl(120, 100%, 40%);">+               log("Rx Uplink TBF assignment: ", ul_tbf_ass);</span><br><span style="color: hsl(120, 100%, 40%);">+              setverdict(pass);</span><br><span style="color: hsl(120, 100%, 40%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              setverdict(fail, "Failed to match UL TBF Assignment");</span><br><span style="color: hsl(120, 100%, 40%);">+              f_shutdown(__BFILE__, __LINE__);</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%);">+function f_imm_ass_verify_dl_tbf_ass(in GsmRrMessage rr_imm_ass, out PacketDlAssign dl_tbf_ass)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Make sure we received a DL TBF Assignment */</span><br><span style="color: hsl(120, 100%, 40%);">+       if (match(rr_imm_ass, tr_IMM_TBF_ASS(dl := true, rest := tr_IaRestOctets_DLAss(?)))) {</span><br><span style="color: hsl(120, 100%, 40%);">+                dl_tbf_ass := rr_imm_ass.payload.imm_ass.rest_octets.hh.pa.uldl.ass.dl;</span><br><span style="color: hsl(120, 100%, 40%);">+               log("Rx Downlink TBF assignment: ", dl_tbf_ass);</span><br><span style="color: hsl(120, 100%, 40%);">+            setverdict(pass);</span><br><span style="color: hsl(120, 100%, 40%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              setverdict(fail, "Failed to match DL TBF Assignment");</span><br><span style="color: hsl(120, 100%, 40%);">+              f_shutdown(__BFILE__, __LINE__);</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%);">+/* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */</span><br><span style="color: hsl(120, 100%, 40%);">+function f_pcuif_tx_data_ind(octetstring data, int16_t lqual_cb := 0, uint32_t fn := 0)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+  var template RAW_PCU_EventParam ev_param := {tdma_fn := ? };</span><br><span style="color: hsl(120, 100%, 40%);">+  BTS.send(ts_PCUIF_DATA_IND(bts_nr := 0, trx_nr := 0, ts_nr := 7, block_nr := 0,</span><br><span style="color: hsl(120, 100%, 40%);">+                                  sapi := PCU_IF_SAPI_PDTCH, data := data,</span><br><span style="color: hsl(120, 100%, 40%);">+                              fn := fn, arfcn := 871, lqual_cb := lqual_cb));</span><br><span style="color: hsl(120, 100%, 40%);">+    if (fn != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                ev_param := {tdma_fn := fn };</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+     BTS.receive(tr_RAW_PCU_EV(TDMA_EV_PDTCH_BLOCK_SENT, ev_param));</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%);">+/* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */</span><br><span style="color: hsl(120, 100%, 40%);">+function f_pcuif_rx_data_req(out PCUIF_Message pcu_msg)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+     BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,</span><br><span style="color: hsl(120, 100%, 40%);">+                                 sapi := PCU_IF_SAPI_PDTCH, fn := 0,</span><br><span style="color: hsl(120, 100%, 40%);">+                           arfcn := 871, block_nr := 0));</span><br><span style="color: hsl(120, 100%, 40%);">+      BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,</span><br><span style="color: hsl(120, 100%, 40%);">+                                 sapi := PCU_IF_SAPI_PDTCH)) -> value pcu_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%);">+/* Expect an Immediate Assignment (paging) from PCU on PCUIF on specified sapi.  */</span><br><span style="color: hsl(120, 100%, 40%);">+function f_pcuif_rx_pch_imm_tbf_ass(out GsmRrMessage rr_imm_ass)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ var PCUIF_Message pcu_msg;</span><br><span style="color: hsl(120, 100%, 40%);">+    var octetstring macblock;</span><br><span style="color: hsl(120, 100%, 40%);">+     BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 0,</span><br><span style="color: hsl(120, 100%, 40%);">+                                 sapi := PCU_IF_SAPI_PCH)) -> value pcu_msg;</span><br><span style="color: hsl(120, 100%, 40%);">+  /* First 3 bytes contain paging group: */</span><br><span style="color: hsl(120, 100%, 40%);">+     macblock := substr(pcu_msg.u.data_req.data, 3, pcu_msg.u.data_req.len - 3);</span><br><span style="color: hsl(120, 100%, 40%);">+   rr_imm_ass := dec_GsmRrMessage(macblock);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (not match(rr_imm_ass, tr_IMM_TBF_ASS())) {</span><br><span style="color: hsl(120, 100%, 40%);">+                setverdict(fail, "Failed to match Immediate Assignment: ", rr_imm_ass);</span><br><span style="color: hsl(120, 100%, 40%);">+             f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+     f_pcuif_tx_data_cnf(pcu_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%);">+/* Expect a Paging Request Type 1 from PCU on PCUIF on specified sapi.  */</span><br><span style="color: hsl(120, 100%, 40%);">+function f_pcuif_rx_pch_pag_req1(template MobileIdentityV mi1 := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+                            template integer pag_group := ?)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT return GsmRrMessage {</span><br><span style="color: hsl(120, 100%, 40%);">+      var GsmRrMessage rr_pag_req1;</span><br><span style="color: hsl(120, 100%, 40%);">+ var PCUIF_Message pcu_msg;</span><br><span style="color: hsl(120, 100%, 40%);">+    var octetstring imsi_suff_octstr;</span><br><span style="color: hsl(120, 100%, 40%);">+     var integer pag_group_rx;</span><br><span style="color: hsl(120, 100%, 40%);">+     var octetstring macblock;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 0,</span><br><span style="color: hsl(120, 100%, 40%);">+                                 sapi := PCU_IF_SAPI_PCH)) -> value pcu_msg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* First 3 bytes contain IMSI suffix to calculate paging group: */</span><br><span style="color: hsl(120, 100%, 40%);">+    imsi_suff_octstr := substr(pcu_msg.u.data_req.data, 0, 3);</span><br><span style="color: hsl(120, 100%, 40%);">+    pag_group_rx := str2int(oct2char(imsi_suff_octstr[0])) * 100 +</span><br><span style="color: hsl(120, 100%, 40%);">+                        str2int(oct2char(imsi_suff_octstr[1])) * 10 +</span><br><span style="color: hsl(120, 100%, 40%);">+                 str2int(oct2char(imsi_suff_octstr[2]));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Make sure we've got RR Paging Request Type 1 for a given MI */</span><br><span style="color: hsl(120, 100%, 40%);">+ macblock := substr(pcu_msg.u.data_req.data, 3, pcu_msg.u.data_req.len - 3);</span><br><span style="color: hsl(120, 100%, 40%);">+   rr_pag_req1 := dec_GsmRrMessage(macblock);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (not match(rr_pag_req1, tr_PAG_REQ1(tr_MI_LV(mi1)))) {</span><br><span style="color: hsl(120, 100%, 40%);">+             setverdict(fail, "Failed to match Paging Request Type 1: ", rr_pag_req1);</span><br><span style="color: hsl(120, 100%, 40%);">+           f_shutdown(__BFILE__, __LINE__);</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%);">+   /* Make sure that received paging froup matches the expected one */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (not match(pag_group_rx, pag_group)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             setverdict(fail, "Paging group", pag_group_rx, " does not match expected ", pag_group);</span><br><span style="color: hsl(120, 100%, 40%);">+           f_shutdown(__BFILE__, __LINE__);</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_pcuif_tx_data_cnf(pcu_msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ return rr_pag_req1;</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 one rlcmac UL block adding necessary extra padding at the end.</span><br><span style="color: hsl(120, 100%, 40%);">+ * returns length of extra padding added at the end, in octets.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  FIXME: Only supports CS-1 so far.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+function f_tx_rlcmac_ul_block(template (value) RlcmacUlBlock ul_data, int16_t lqual_cb := 0, uint32_t fn := 0)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT return integer {</span><br><span style="color: hsl(120, 100%, 40%);">+       var octetstring data;</span><br><span style="color: hsl(120, 100%, 40%);">+ var integer padding_len;</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Encode the payload of DATA.ind */</span><br><span style="color: hsl(120, 100%, 40%);">+  data := enc_RlcmacUlBlock(valueof(ul_data));</span><br><span style="color: hsl(120, 100%, 40%);">+  padding_len := 23 - lengthof(data);</span><br><span style="color: hsl(120, 100%, 40%);">+   data := f_pad_oct(data, 23, '00'O); /* CS-1 */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */</span><br><span style="color: hsl(120, 100%, 40%);">+      f_pcuif_tx_data_ind(data, lqual_cb, fn);</span><br><span style="color: hsl(120, 100%, 40%);">+      return padding_len;</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 f_tx_rlcmac_ul_n_blocks(uint5_t tfi, inout uint14_t bsn, integer num_blocks := 1, template (omit) GprsTlli tlli := omit)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT return octetstring {</span><br><span style="color: hsl(120, 100%, 40%);">+     var octetstring total_payload := ''O;</span><br><span style="color: hsl(120, 100%, 40%);">+ var template (value) RlcmacUlBlock ul_data := t_RLCMAC_UL_DATA(</span><br><span style="color: hsl(120, 100%, 40%);">+               tfi := tfi,</span><br><span style="color: hsl(120, 100%, 40%);">+           cv := 15, /* num UL blocks to be sent (to be overridden in loop) */</span><br><span style="color: hsl(120, 100%, 40%);">+           bsn := 0, /* To be generated in loop */</span><br><span style="color: hsl(120, 100%, 40%);">+               blocks := { /* To be generated in loop */ });</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (not istemplatekind(tlli, "omit")) {</span><br><span style="color: hsl(120, 100%, 40%);">+             ul_data.data.mac_hdr.tlli_ind := true;</span><br><span style="color: hsl(120, 100%, 40%);">+                ul_data.data.tlli := tlli;</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%);">+   for (var integer i := 0; i < num_blocks; i := i + 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+             var integer padding_len;</span><br><span style="color: hsl(120, 100%, 40%);">+              var octetstring payload := f_rnd_octstring(10);</span><br><span style="color: hsl(120, 100%, 40%);">+               /* Prepare a new UL block (CV, random payload) */</span><br><span style="color: hsl(120, 100%, 40%);">+             var integer cv := num_blocks - i - 1;</span><br><span style="color: hsl(120, 100%, 40%);">+         if (cv > g_bs_cv_max) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    cv := 15;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             ul_data.data.mac_hdr.countdown := cv;</span><br><span style="color: hsl(120, 100%, 40%);">+         ul_data.data.mac_hdr.bsn := bsn + i;</span><br><span style="color: hsl(120, 100%, 40%);">+          ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(payload)) };</span><br><span style="color: hsl(120, 100%, 40%);">+               padding_len := f_tx_rlcmac_ul_block(ul_data);</span><br><span style="color: hsl(120, 100%, 40%);">+         total_payload := total_payload & payload & f_pad_oct(''O, padding_len, '00'O);</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     bsn := valueof(ul_data.data.mac_hdr.bsn) + 1; /* update bsn to point to next one */</span><br><span style="color: hsl(120, 100%, 40%);">+   return total_payload;</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 f_rx_rlcmac_dl_block(out RlcmacDlBlock dl_block, out uint32_t dl_fn, template (present) CodingScheme exp_cs_mcs := ?)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ var PCUIF_Message pcu_msg;</span><br><span style="color: hsl(120, 100%, 40%);">+    f_pcuif_rx_data_req(pcu_msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ dl_block := dec_RlcmacDlBlock(pcu_msg.u.data_req.data);</span><br><span style="color: hsl(120, 100%, 40%);">+       dl_fn := pcu_msg.u.data_req.fn;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     var integer len := lengthof(pcu_msg.u.data_req.data);</span><br><span style="color: hsl(120, 100%, 40%);">+ var CodingScheme cs_mcs := f_rlcmac_block_len2cs_mcs(len)</span><br><span style="color: hsl(120, 100%, 40%);">+     if (not match(f_rlcmac_block_len2cs_mcs(len), exp_cs_mcs)) {</span><br><span style="color: hsl(120, 100%, 40%);">+          setverdict(fail, "Failed to match Coding Scheme exp ", exp_cs_mcs, " vs ", cs_mcs, " (", len, ")");</span><br><span style="color: hsl(120, 100%, 40%);">+           f_shutdown(__BFILE__, __LINE__);</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%);">+function f_rx_rlcmac_dl_block_exp_ack_nack(out RlcmacDlBlock dl_block, out uint32_t poll_fn)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+       var uint32_t dl_fn;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_rx_rlcmac_dl_block(dl_block, dl_fn);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK(ul_tfi := ?, tlli := ?))) {</span><br><span style="color: hsl(120, 100%, 40%);">+             setverdict(fail, "Failed to match Packet Uplink ACK / NACK");</span><br><span style="color: hsl(120, 100%, 40%);">+               f_shutdown(__BFILE__, __LINE__);</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%);">+   poll_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);</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 f_rx_rlcmac_dl_block_exp_dummy(out RlcmacDlBlock dl_block)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+     var uint32_t dl_fn;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_rx_rlcmac_dl_block(dl_block, dl_fn);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (not match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {</span><br><span style="color: hsl(120, 100%, 40%);">+            setverdict(fail, "Failed to match Packet DUMMY DL");</span><br><span style="color: hsl(120, 100%, 40%);">+                f_shutdown(__BFILE__, __LINE__);</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%);">+function f_rx_rlcmac_dl_block_exp_pkt_ass(out RlcmacDlBlock dl_block, out uint32_t poll_fn)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+        var uint32_t dl_fn;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_rx_rlcmac_dl_block(dl_block, dl_fn);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (not match(dl_block, tr_RLCMAC_DL_PACKET_ASS())) {</span><br><span style="color: hsl(120, 100%, 40%);">+         setverdict(fail, "Failed to match Packet Downlink Assignment");</span><br><span style="color: hsl(120, 100%, 40%);">+             f_shutdown(__BFILE__, __LINE__);</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%);">+   poll_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);</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 f_rx_rlcmac_dl_block_exp_pkt_ul_ass(out RlcmacDlBlock dl_block, out uint32_t poll_fn)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+        var uint32_t dl_fn;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        f_rx_rlcmac_dl_block(dl_block, dl_fn);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (not match(dl_block, tr_RLCMAC_UL_PACKET_ASS())) {</span><br><span style="color: hsl(120, 100%, 40%);">+                setverdict(fail, "Failed to match Packet Uplink Assignment");</span><br><span style="color: hsl(120, 100%, 40%);">+           f_shutdown(__BFILE__, __LINE__);</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%);">+ poll_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);</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 f_rx_rlcmac_dl_block_exp_pkt_dl_ass(out RlcmacDlBlock dl_block, out uint32_t poll_fn)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+        var uint32_t dl_fn;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        f_rx_rlcmac_dl_block(dl_block, dl_fn);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (not match(dl_block, tr_RLCMAC_DL_PACKET_ASS())) {</span><br><span style="color: hsl(120, 100%, 40%);">+                setverdict(fail, "Failed to match Packet Downlink Assignment");</span><br><span style="color: hsl(120, 100%, 40%);">+         f_shutdown(__BFILE__, __LINE__);</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%);">+ poll_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);</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%);">+function f_rx_rlcmac_dl_block_exp_pkt_pag_req(out RlcmacDlBlock dl_block)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+     var uint32_t dl_fn;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_rx_rlcmac_dl_block(dl_block, dl_fn);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (not match(dl_block, tr_RLCMAC_PACKET_PAG_REQ())) {</span><br><span style="color: hsl(120, 100%, 40%);">+                setverdict(fail, "Failed to match Packet Paging Request: ", dl_block, " vs ", tr_RLCMAC_PACKET_PAG_REQ());</span><br><span style="color: hsl(120, 100%, 40%);">+                f_shutdown(__BFILE__, __LINE__);</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%);">+/* This function does what could probably be done with templates */</span><br><span style="color: hsl(120, 100%, 40%);">+function f_rlcmac_dl_block_verify_data_gprs(in RlcmacDlDataBlock data_block,</span><br><span style="color: hsl(120, 100%, 40%);">+                                         template (present) octetstring data := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+                                     template (present) uint7_t exp_bsn := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+                                      template (present) CodingScheme exp_cs := ?)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+   if (not match(data_block.mac_hdr.hdr_ext.bsn, exp_bsn)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             setverdict(fail, "DL block BSN doesn't match: ",</span><br><span style="color: hsl(120, 100%, 40%);">+                           data_block.mac_hdr.hdr_ext.bsn, " vs exp ", exp_bsn);</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%);">+   if (lengthof(data_block.blocks) < 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+             setverdict(fail, "DL block has no LLC payload: ", data_block);</span><br><span style="color: hsl(120, 100%, 40%);">+              f_shutdown(__BFILE__, __LINE__);</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%);">+   if (not match(data_block.blocks[0].payload, data)) {</span><br><span style="color: hsl(120, 100%, 40%);">+          setverdict(fail, "Failed to match content of LLC payload in DL Block: ",</span><br><span style="color: hsl(120, 100%, 40%);">+                       data_block.blocks[0].payload, " vs ", data);</span><br><span style="color: hsl(120, 100%, 40%);">+             f_shutdown(__BFILE__, __LINE__);</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%);">+   /* Check next data blocks contain dummy frames */</span><br><span style="color: hsl(120, 100%, 40%);">+     if (lengthof(data_block.blocks) > 1 and substr(data_block.blocks[1].payload, 0, 3) != '43C001'O) {</span><br><span style="color: hsl(120, 100%, 40%);">+         setverdict(fail, "Second data payload is not a dummy frame: ",</span><br><span style="color: hsl(120, 100%, 40%);">+                         data_block.blocks[1].payload);</span><br><span style="color: hsl(120, 100%, 40%);">+             f_shutdown(__BFILE__, __LINE__);</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: check exp_cs */</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%);">+/* This function does what could probably be done with templates */</span><br><span style="color: hsl(120, 100%, 40%);">+function f_rlcmac_dl_block_verify_data_egprs(in RlcmacDlEgprsDataBlock data_block,</span><br><span style="color: hsl(120, 100%, 40%);">+                                             template (present) octetstring data := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+                                             template (present) uint14_t exp_bsn := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+                                             template (present) CodingScheme exp_cs := ?)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+  if (not match(data_block.mac_hdr.bsn1, exp_bsn)) {</span><br><span style="color: hsl(120, 100%, 40%);">+            setverdict(fail, "DL block BSN doesn't match: ",</span><br><span style="color: hsl(120, 100%, 40%);">+                           data_block.mac_hdr.bsn1, " vs exp ", exp_bsn);</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%);">+   if (lengthof(data_block.blocks) < 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+             setverdict(fail, "DL block has no LLC payload: ", data_block);</span><br><span style="color: hsl(120, 100%, 40%);">+              f_shutdown(__BFILE__, __LINE__);</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%);">+   if (not match(data_block.blocks[0].payload, data)) {</span><br><span style="color: hsl(120, 100%, 40%);">+          setverdict(fail, "Failed to match content of LLC payload in DL Block: ",</span><br><span style="color: hsl(120, 100%, 40%);">+                       data_block.blocks[0].payload, " vs ", data);</span><br><span style="color: hsl(120, 100%, 40%);">+             f_shutdown(__BFILE__, __LINE__);</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%);">+   /* Check next data blocks contain dummy frames */</span><br><span style="color: hsl(120, 100%, 40%);">+     if (lengthof(data_block.blocks) > 1 and substr(data_block.blocks[1].payload, 0, 3) != '43C001'O) {</span><br><span style="color: hsl(120, 100%, 40%);">+         setverdict(fail, "Second data payload is not a dummy frame: ",</span><br><span style="color: hsl(120, 100%, 40%);">+                         data_block.blocks[1].payload);</span><br><span style="color: hsl(120, 100%, 40%);">+             f_shutdown(__BFILE__, __LINE__);</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: Check exp_cs. In the case of EGPRS, first check mac_hdr.header_type and then decode CPS = exp_cs based on mac_hdr.header_type.</span><br><span style="color: hsl(120, 100%, 40%);">+               See wireshark's egprs_Header_type1_coding_puncturing_scheme_to_mcs. */</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%);">+/* High level (task specific) helper for receiving and matching GPRS/EGPRS data blocks */</span><br><span style="color: hsl(120, 100%, 40%);">+function f_rx_rlcmac_dl_block_exp_data(out RlcmacDlBlock dl_block, out uint32_t dl_fn,</span><br><span style="color: hsl(120, 100%, 40%);">+                                   template (present) octetstring data := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+                                     template (present) uint7_t exp_bsn := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+                                      template (present) CodingScheme exp_cs := ?)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+        /* FIXME: ideally we should use an alt statement with timeout here, rather than</span><br><span style="color: hsl(120, 100%, 40%);">+        * having +100500 layers of abstraction. This would facilitate developing the</span><br><span style="color: hsl(120, 100%, 40%);">+  * multi-TBF/-TRX/-BTS tests, where you cannot expect that the first received</span><br><span style="color: hsl(120, 100%, 40%);">+  * block is exactly what you need. */</span><br><span style="color: hsl(120, 100%, 40%);">+ f_rx_rlcmac_dl_block(dl_block, dl_fn);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Make sure it's either GPRS or EGPRS data block */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (not match(dl_block, tr_RLCMAC_DATA)) {</span><br><span style="color: hsl(120, 100%, 40%);">+            setverdict(fail, "Failed to match DL DATA: ", dl_block, " vs ", tr_RLCMAC_DATA);</span><br><span style="color: hsl(120, 100%, 40%);">+          f_shutdown(__BFILE__, __LINE__);</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%);">+   if (ischosen(dl_block.data_egprs)) {</span><br><span style="color: hsl(120, 100%, 40%);">+          f_rlcmac_dl_block_verify_data_egprs(dl_block.data_egprs, data, exp_bsn, exp_cs);</span><br><span style="color: hsl(120, 100%, 40%);">+      } else if (ischosen(dl_block.data)) {</span><br><span style="color: hsl(120, 100%, 40%);">+         f_rlcmac_dl_block_verify_data_gprs(dl_block.data, data, exp_bsn, exp_cs);</span><br><span style="color: hsl(120, 100%, 40%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              /* Should not happen, but the caller may theoretically give us a template for CTRL */</span><br><span style="color: hsl(120, 100%, 40%);">+         setverdict(fail, "DL block is neither GPRS nor EGPRS data block: ", dl_block);</span><br><span style="color: hsl(120, 100%, 40%);">+              f_shutdown(__BFILE__, __LINE__);</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%);">+function f_dl_block_ack_fn(in RlcmacDlBlock dl_block, uint32_t dl_fn)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT return uint32_t {</span><br><span style="color: hsl(120, 100%, 40%);">+      var boolean rrbp_valid;</span><br><span style="color: hsl(120, 100%, 40%);">+       var MacRrbp rrbp;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* The argument must be either a GPRS or EGPRS data block */</span><br><span style="color: hsl(120, 100%, 40%);">+  if (ischosen(dl_block.data_egprs)) {</span><br><span style="color: hsl(120, 100%, 40%);">+          rrbp_valid := true; /* always valid */</span><br><span style="color: hsl(120, 100%, 40%);">+                rrbp := dl_block.data_egprs.mac_hdr.rrbp;</span><br><span style="color: hsl(120, 100%, 40%);">+     } else if (ischosen(dl_block.data)) {</span><br><span style="color: hsl(120, 100%, 40%);">+         rrbp_valid := dl_block.data.mac_hdr.mac_hdr.rrbp_valid;</span><br><span style="color: hsl(120, 100%, 40%);">+               rrbp := dl_block.data.mac_hdr.mac_hdr.rrbp;</span><br><span style="color: hsl(120, 100%, 40%);">+   } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              rrbp_valid := dl_block.ctrl.mac_hdr.rrbp_valid;</span><br><span style="color: hsl(120, 100%, 40%);">+               rrbp := dl_block.ctrl.mac_hdr.rrbp;</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%);">+   /* Make sure that the given block really needs to be ACKnowledged */</span><br><span style="color: hsl(120, 100%, 40%);">+  if (not rrbp_valid) {</span><br><span style="color: hsl(120, 100%, 40%);">+         setverdict(fail, "DL block shall not be ACKnowledged, field RRBP is not valid");</span><br><span style="color: hsl(120, 100%, 40%);">+            f_shutdown(__BFILE__, __LINE__);</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%);">+   return f_rrbp_ack_fn(dl_fn, rrbp);</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 f_pkt_paging_match_tmsi(in PacketPagingReq req, template GsmTmsi tmsi)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on MS_BTS_IFACE_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+   if (not match(req.repeated_pageinfo.cs.tmsi, tmsi)) {</span><br><span style="color: hsl(120, 100%, 40%);">+         setverdict(fail, "Mobile Identity (TMSI/P-TMSI) mismatch: ",</span><br><span style="color: hsl(120, 100%, 40%);">+                           "expected: ", tmsi, "got: ", req.repeated_pageinfo.cs.tmsi);</span><br><span style="color: hsl(120, 100%, 40%);">+           f_shutdown(__BFILE__, __LINE__);</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/pcu/PCU_Tests.ttcn b/pcu/PCU_Tests.ttcn</span><br><span>index 43ed7c5..5193369 100644</span><br><span>--- a/pcu/PCU_Tests.ttcn</span><br><span>+++ b/pcu/PCU_Tests.ttcn</span><br><span>@@ -49,6 +49,7 @@</span><br><span> import from IPL4asp_Types all;</span><br><span> import from Native_Functions all;</span><br><span> import from SGSN_Components all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from GPRS_Components all;</span><br><span> </span><br><span> modulepar {</span><br><span>   charstring mp_pcu_sock_path := PCU_SOCK_DEFAULT;</span><br><span>@@ -100,14 +101,10 @@</span><br><span>     uint8_t high</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-type component RAW_PCU_Test_CT extends bssgp_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+type component RAW_PCU_Test_CT extends bssgp_CT, MS_BTS_IFACE_CT {</span><br><span>   /* PCU interface abstraction component */</span><br><span>    var RAW_PCUIF_CT vc_PCUIF;</span><br><span style="color: hsl(0, 100%, 40%);">-      /* Virtual BTS component */</span><br><span style="color: hsl(0, 100%, 40%);">-     var RAW_PCU_BTS_CT vc_BTS;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  /* Connection to the BTS component (one for now) */</span><br><span style="color: hsl(0, 100%, 40%);">-     port RAW_PCU_MSG_PT BTS;</span><br><span>     /* Connection to the PCUIF component */</span><br><span>      port RAW_PCU_MSG_PT PCUIF;</span><br><span>   /* VTY connection to the PCU */</span><br><span>@@ -136,9 +133,6 @@</span><br><span>        var uint8_t g_mcs_max_dl := 9;</span><br><span>       var uint8_t g_mcs_max_ul := 9;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      /* Value at which Countdown Procedure starts. Announced by network (GPRS Cell Options as per TS 04.60 Chapter 12.24) */</span><br><span style="color: hsl(0, 100%, 40%);">- var uint4_t g_bs_cv_max := 4;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>        var boolean g_egprs_only := false;</span><br><span>   var boolean g_force_two_phase_access := false;</span><br><span> </span><br><span>@@ -227,560 +221,6 @@</span><br><span>   BTS.receive(tr_RAW_PCU_EV(BTS_EV_SI13_NEGO));</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-private function f_shutdown(charstring file, integer line,</span><br><span style="color: hsl(0, 100%, 40%);">-                            boolean final := false)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT {</span><br><span style="color: hsl(0, 100%, 40%);">-    /* Determine if the test case was aborted in the middle */</span><br><span style="color: hsl(0, 100%, 40%);">-      if (not final) {</span><br><span style="color: hsl(0, 100%, 40%);">-                log("Test case ", testcasename(), " aborted at ", file, ":", line);</span><br><span style="color: hsl(0, 100%, 40%);">-       } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                /* Guard verdict to avoid 'none' */</span><br><span style="color: hsl(0, 100%, 40%);">-             setverdict(pass);</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* Properly shutdown virtual BTS and its clock generator */</span><br><span style="color: hsl(0, 100%, 40%);">-     BTS.send(ts_RAW_PCU_CMD(GENERAL_CMD_SHUTDOWN));</span><br><span style="color: hsl(0, 100%, 40%);">- vc_BTS.done; /* wait untill it's done */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    /* Shutdown the others and MTC */</span><br><span style="color: hsl(0, 100%, 40%);">-       all component.stop;</span><br><span style="color: hsl(0, 100%, 40%);">-     mtc.stop;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-template AckNackDescription t_AckNackDescription_init := {</span><br><span style="color: hsl(0, 100%, 40%);">-    final_ack := '0'B,</span><br><span style="color: hsl(0, 100%, 40%);">-      starting_seq_nr := 0,</span><br><span style="color: hsl(0, 100%, 40%);">-   receive_block_bitmap := '0000000000000000000000000000000000000000000000000000000000000000'B</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-private function f_rlcmac_dl_block_get_tfi(RlcmacDlBlock dl_block)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT return uint5_t {</span><br><span style="color: hsl(0, 100%, 40%);">-  if (ischosen(dl_block.data)) {</span><br><span style="color: hsl(0, 100%, 40%);">-          return dl_block.data.mac_hdr.hdr_ext.tfi;</span><br><span style="color: hsl(0, 100%, 40%);">-       } else if (ischosen(dl_block.data_egprs)) {</span><br><span style="color: hsl(0, 100%, 40%);">-             return dl_block.data_egprs.mac_hdr.tfi;</span><br><span style="color: hsl(0, 100%, 40%);">- } else { /* Ctrl block */</span><br><span style="color: hsl(0, 100%, 40%);">-               if (match(dl_block, tr_RLCMAC_UL_PACKET_ASS_GPRS(?, tr_PktUlAssGprsDynamic(tr_DynamicAllocation(?))))) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        return dl_block.ctrl.payload.u.ul_assignment.gprs.dyn_block_alloc.ul_tfi_assignment;</span><br><span style="color: hsl(0, 100%, 40%);">-            }</span><br><span style="color: hsl(0, 100%, 40%);">-               if (match(dl_block, tr_RLCMAC_UL_PACKET_ASS_EGPRS(?, tr_PktUlAssEgprsDynamic(tr_DynamicAllocation(?))))) {</span><br><span style="color: hsl(0, 100%, 40%);">-                      return dl_block.ctrl.payload.u.ul_assignment.egprs.dyn_block_alloc.ul_tfi_assignment;</span><br><span style="color: hsl(0, 100%, 40%);">-           }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-       setverdict(fail, "DlBlock doesn't contain a TFI:", dl_block);</span><br><span style="color: hsl(0, 100%, 40%);">-     f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(0, 100%, 40%);">-        return 0; /* make compiler happy */</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Get the Chan coding command from a dl block containing PACCH UL Assignment */</span><br><span style="color: hsl(0, 100%, 40%);">-private function f_rlcmac_dl_block_get_assigned_ul_cs_mcs(RlcmacDlBlock dl_block)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT return CodingScheme {</span><br><span style="color: hsl(0, 100%, 40%);">-      if (match(dl_block, tr_RLCMAC_UL_PACKET_ASS_GPRS(?, tr_PktUlAssGprsDynamic(?)))) {</span><br><span style="color: hsl(0, 100%, 40%);">-              return f_rlcmac_block_ChCodingCommand2cs_mcs(dl_block.ctrl.payload.u.ul_assignment.gprs.ch_coding_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-       if (match(dl_block, tr_RLCMAC_UL_PACKET_ASS_EGPRS(?, tr_PktUlAssEgprsDynamic(?)))) {</span><br><span style="color: hsl(0, 100%, 40%);">-            return f_rlcmac_block_EgprsChCodingCommand2cs_mcs(dl_block.ctrl.payload.u.ul_assignment.egprs.chan_coding_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-       setverdict(fail, "DlBlock doesn't contain CS_MCS information:", dl_block);</span><br><span style="color: hsl(0, 100%, 40%);">-        f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(0, 100%, 40%);">-        return CS_1; /* make compiler happy */</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* TS 44.060 sec 12.3 Ack/Nack Description */</span><br><span style="color: hsl(0, 100%, 40%);">-private function f_acknackdesc_ack_block(inout AckNackDescription desc, RlcmacDlBlock dl_block, BIT1 final_ack := '0'B)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    var uint7_t bsn;</span><br><span style="color: hsl(0, 100%, 40%);">-        var integer i;</span><br><span style="color: hsl(0, 100%, 40%);">-  var integer inc;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        if (ischosen(dl_block.data)) {</span><br><span style="color: hsl(0, 100%, 40%);">-          bsn := dl_block.data.mac_hdr.hdr_ext.bsn;</span><br><span style="color: hsl(0, 100%, 40%);">-       } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                bsn := dl_block.data_egprs.mac_hdr.bsn1;</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       inc := bsn - desc.starting_seq_nr + 1;</span><br><span style="color: hsl(0, 100%, 40%);">-  /* Filling hole? */</span><br><span style="color: hsl(0, 100%, 40%);">-     if (bsn < desc.starting_seq_nr) {</span><br><span style="color: hsl(0, 100%, 40%);">-            desc.receive_block_bitmap[lengthof(desc.receive_block_bitmap) - (desc.starting_seq_nr - bsn)] := int2bit(1, 1);</span><br><span style="color: hsl(0, 100%, 40%);">-         return;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* SSN is increased, and so RBB values need to be moved */</span><br><span style="color: hsl(0, 100%, 40%);">-      for (i := 0; i < lengthof(desc.receive_block_bitmap) - inc; i := i+1) {</span><br><span style="color: hsl(0, 100%, 40%);">-              desc.receive_block_bitmap[i] := desc.receive_block_bitmap[i + inc];</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-       for (i := lengthof(desc.receive_block_bitmap) - inc; i < lengthof(desc.receive_block_bitmap) - 1; i := i+1) {</span><br><span style="color: hsl(0, 100%, 40%);">-                desc.receive_block_bitmap[i] := int2bit(0, 1);</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-       /* Now we can set current bit and update SSN */</span><br><span style="color: hsl(0, 100%, 40%);">- desc.starting_seq_nr := bsn + 1;</span><br><span style="color: hsl(0, 100%, 40%);">-        desc.receive_block_bitmap[lengthof(desc.receive_block_bitmap) - 1] := int2bit(1, 1);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    /* Finally update the final_ack bit as requested: */</span><br><span style="color: hsl(0, 100%, 40%);">-    desc.final_ack := final_ack;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* This function can be used to send DATA.cnf in response to the IUT originated DATA.req.</span><br><span style="color: hsl(0, 100%, 40%);">- * NOTE: it's the responsibility of caller to make sure that pcu_msg contains u.data_req. */</span><br><span style="color: hsl(0, 100%, 40%);">-private function f_pcuif_tx_data_cnf(in PCUIF_Message pcu_msg)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT {</span><br><span style="color: hsl(0, 100%, 40%);">-   var PCUIF_Message pcu_msg_cnf := {</span><br><span style="color: hsl(0, 100%, 40%);">-              msg_type := PCU_IF_MSG_DATA_CNF,</span><br><span style="color: hsl(0, 100%, 40%);">-                bts_nr := pcu_msg.bts_nr,</span><br><span style="color: hsl(0, 100%, 40%);">-               spare := pcu_msg.spare,</span><br><span style="color: hsl(0, 100%, 40%);">-         u := { data_cnf := pcu_msg.u.data_req }</span><br><span style="color: hsl(0, 100%, 40%);">- };</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      /* PCU wants DATA.cnf containing basically everything that was in DATA.req,</span><br><span style="color: hsl(0, 100%, 40%);">-      * but PCU_IF_SAPI_PCH is a special case - paging group shall be excluded. */</span><br><span style="color: hsl(0, 100%, 40%);">-   if (pcu_msg.u.data_req.sapi == PCU_IF_SAPI_PCH) {</span><br><span style="color: hsl(0, 100%, 40%);">-               pcu_msg_cnf.u.data_cnf.data := substr(pcu_msg.u.data_req.data, 3,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                     pcu_msg.u.data_req.len - 3);</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       BTS.send(pcu_msg_cnf);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-private function f_pcuif_rx_imm_ass(out GsmRrMessage rr_imm_ass,</span><br><span style="color: hsl(0, 100%, 40%);">-                             template PCUIF_Sapi sapi := PCU_IF_SAPI_AGCH,</span><br><span style="color: hsl(0, 100%, 40%);">-                                   template GsmRrMessage t_imm_ass := ?,</span><br><span style="color: hsl(0, 100%, 40%);">-                                   uint8_t bts_nr := 0)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT return boolean {</span><br><span style="color: hsl(0, 100%, 40%);">-        var PCUIF_Message pcu_msg;</span><br><span style="color: hsl(0, 100%, 40%);">-      var octetstring data;</span><br><span style="color: hsl(0, 100%, 40%);">-   timer T;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        T.start(2.0);</span><br><span style="color: hsl(0, 100%, 40%);">-   alt {</span><br><span style="color: hsl(0, 100%, 40%);">-   [] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := bts_nr, trx_nr := 0, ts_nr := 0,</span><br><span style="color: hsl(0, 100%, 40%);">-                                      sapi := sapi, data := ?)) -> value pcu_msg {</span><br><span style="color: hsl(0, 100%, 40%);">-                /* On PCH the payload is prefixed with paging group (3 octets): skip it.</span><br><span style="color: hsl(0, 100%, 40%);">-                 * TODO: add an additional template parameter, so we can match it. */</span><br><span style="color: hsl(0, 100%, 40%);">-           if (pcu_msg.u.data_req.sapi == PCU_IF_SAPI_PCH) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       data := substr(pcu_msg.u.data_req.data, 3, pcu_msg.u.data_req.len - 3);</span><br><span style="color: hsl(0, 100%, 40%);">-         } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                        data := pcu_msg.u.data_req.data;</span><br><span style="color: hsl(0, 100%, 40%);">-                }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               rr_imm_ass := dec_GsmRrMessage(data);</span><br><span style="color: hsl(0, 100%, 40%);">-           if (not match(rr_imm_ass, t_imm_ass)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 /* Not for us? Wait for more. */</span><br><span style="color: hsl(0, 100%, 40%);">-                        repeat;</span><br><span style="color: hsl(0, 100%, 40%);">-         }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               log("Rx Immediate Assignment: ", rr_imm_ass);</span><br><span style="color: hsl(0, 100%, 40%);">-         setverdict(pass);</span><br><span style="color: hsl(0, 100%, 40%);">-               return true;</span><br><span style="color: hsl(0, 100%, 40%);">-            }</span><br><span style="color: hsl(0, 100%, 40%);">-       [] BTS.receive { repeat; }</span><br><span style="color: hsl(0, 100%, 40%);">-      [] T.timeout {</span><br><span style="color: hsl(0, 100%, 40%);">-          setverdict(fail, "Timeout waiting for Immediate Assignment");</span><br><span style="color: hsl(0, 100%, 40%);">-         }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return false;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* One phase packet access (see 3GPP TS 44.018, table 9.1.8.1) */</span><br><span style="color: hsl(0, 100%, 40%);">-private const BIT8 chan_req_def := '01111000'B;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Establish an Uplink TBF by sending RACH.ind towards the PCU */</span><br><span style="color: hsl(0, 100%, 40%);">-private function f_establish_tbf(out GsmRrMessage rr_imm_ass, uint8_t bts_nr := 0,</span><br><span style="color: hsl(0, 100%, 40%);">-                                uint16_t ra := bit2int(chan_req_def),</span><br><span style="color: hsl(0, 100%, 40%);">-                           uint8_t is_11bit := 0,</span><br><span style="color: hsl(0, 100%, 40%);">-                          PCUIF_BurstType burst_type := BURST_TYPE_0,</span><br><span style="color: hsl(0, 100%, 40%);">-                             TimingAdvance ta := 0)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT return boolean {</span><br><span style="color: hsl(0, 100%, 40%);">- var uint32_t fn;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* FIXME: ask the BTS component to give us the current TDMA fn */</span><br><span style="color: hsl(0, 100%, 40%);">-       fn := 1337 + ta;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* Send RACH.ind */</span><br><span style="color: hsl(0, 100%, 40%);">-     log("Sending RACH.ind on fn=", fn, " with RA=", ra, ", TA=", ta);</span><br><span style="color: hsl(0, 100%, 40%);">- BTS.send(ts_PCUIF_RACH_IND(bts_nr := bts_nr, trx_nr := 0, ts_nr := 0,</span><br><span style="color: hsl(0, 100%, 40%);">-                              ra := ra, is_11bit := is_11bit,</span><br><span style="color: hsl(0, 100%, 40%);">-                                 burst_type := burst_type,</span><br><span style="color: hsl(0, 100%, 40%);">-                               fn := fn, arfcn := 871,</span><br><span style="color: hsl(0, 100%, 40%);">-                                 qta := ta * 4));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* 3GPP TS 44.018, table 9.1.8.1, note 2b: Request Reference shall be set to 127</span><br><span style="color: hsl(0, 100%, 40%);">-         * when Immediate Assignment is triggered by EGPRS Packet Channel Request. Here</span><br><span style="color: hsl(0, 100%, 40%);">-  * we assume that 11 bit RA always contains EGPRS Packet Channel Request. */</span><br><span style="color: hsl(0, 100%, 40%);">-    if (is_11bit != 0) { ra := 127; }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* Expect Immediate (TBF) Assignment on TS0/AGCH */</span><br><span style="color: hsl(0, 100%, 40%);">-     return f_pcuif_rx_imm_ass(rr_imm_ass, PCU_IF_SAPI_AGCH,</span><br><span style="color: hsl(0, 100%, 40%);">-                           tr_IMM_TBF_ASS(false, ra, fn),</span><br><span style="color: hsl(0, 100%, 40%);">-                                  bts_nr := bts_nr);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-private function f_imm_ass_verify_ul_tbf_ass(in GsmRrMessage rr_imm_ass, out PacketUlAssign ul_tbf_ass, template PacketUlAssign ul_ass := tr_PacketUlDynAssign)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT {</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   /* Make sure we received an UL TBF Assignment */</span><br><span style="color: hsl(0, 100%, 40%);">-        if (match(rr_imm_ass, tr_IMM_TBF_ASS(dl := false, rest := tr_IaRestOctets_ULAss(ul_ass)))) {</span><br><span style="color: hsl(0, 100%, 40%);">-            ul_tbf_ass := rr_imm_ass.payload.imm_ass.rest_octets.hh.pa.uldl.ass.ul;</span><br><span style="color: hsl(0, 100%, 40%);">-         log("Rx Uplink TBF assignment: ", ul_tbf_ass);</span><br><span style="color: hsl(0, 100%, 40%);">-                setverdict(pass);</span><br><span style="color: hsl(0, 100%, 40%);">-       } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                setverdict(fail, "Failed to match UL TBF Assignment");</span><br><span style="color: hsl(0, 100%, 40%);">-                f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-private function f_imm_ass_verify_dl_tbf_ass(in GsmRrMessage rr_imm_ass, out PacketDlAssign dl_tbf_ass)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT {</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      /* Make sure we received a DL TBF Assignment */</span><br><span style="color: hsl(0, 100%, 40%);">- if (match(rr_imm_ass, tr_IMM_TBF_ASS(dl := true, rest := tr_IaRestOctets_DLAss(?)))) {</span><br><span style="color: hsl(0, 100%, 40%);">-          dl_tbf_ass := rr_imm_ass.payload.imm_ass.rest_octets.hh.pa.uldl.ass.dl;</span><br><span style="color: hsl(0, 100%, 40%);">-         log("Rx Downlink TBF assignment: ", dl_tbf_ass);</span><br><span style="color: hsl(0, 100%, 40%);">-              setverdict(pass);</span><br><span style="color: hsl(0, 100%, 40%);">-       } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                setverdict(fail, "Failed to match DL TBF Assignment");</span><br><span style="color: hsl(0, 100%, 40%);">-                f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */</span><br><span style="color: hsl(0, 100%, 40%);">-function f_pcuif_tx_data_ind(octetstring data, int16_t lqual_cb := 0, uint32_t fn := 0)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT {</span><br><span style="color: hsl(0, 100%, 40%);">-      var template RAW_PCU_EventParam ev_param := {tdma_fn := ? };</span><br><span style="color: hsl(0, 100%, 40%);">-    BTS.send(ts_PCUIF_DATA_IND(bts_nr := 0, trx_nr := 0, ts_nr := 7, block_nr := 0,</span><br><span style="color: hsl(0, 100%, 40%);">-                            sapi := PCU_IF_SAPI_PDTCH, data := data,</span><br><span style="color: hsl(0, 100%, 40%);">-                                fn := fn, arfcn := 871, lqual_cb := lqual_cb));</span><br><span style="color: hsl(0, 100%, 40%);">-      if (fn != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-          ev_param := {tdma_fn := fn };</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-       BTS.receive(tr_RAW_PCU_EV(TDMA_EV_PDTCH_BLOCK_SENT, ev_param));</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */</span><br><span style="color: hsl(0, 100%, 40%);">-private function f_pcuif_rx_data_req(out PCUIF_Message pcu_msg)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT {</span><br><span style="color: hsl(0, 100%, 40%);">- BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,</span><br><span style="color: hsl(0, 100%, 40%);">-                           sapi := PCU_IF_SAPI_PDTCH, fn := 0,</span><br><span style="color: hsl(0, 100%, 40%);">-                             arfcn := 871, block_nr := 0));</span><br><span style="color: hsl(0, 100%, 40%);">-        BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,</span><br><span style="color: hsl(0, 100%, 40%);">-                                   sapi := PCU_IF_SAPI_PDTCH)) -> value pcu_msg;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Expect an Immediate Assignment (paging) from PCU on PCUIF on specified sapi.  */</span><br><span style="color: hsl(0, 100%, 40%);">-private function f_pcuif_rx_pch_imm_tbf_ass(out GsmRrMessage rr_imm_ass)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT {</span><br><span style="color: hsl(0, 100%, 40%);">-     var PCUIF_Message pcu_msg;</span><br><span style="color: hsl(0, 100%, 40%);">-      var octetstring macblock;</span><br><span style="color: hsl(0, 100%, 40%);">-       BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 0,</span><br><span style="color: hsl(0, 100%, 40%);">-                                   sapi := PCU_IF_SAPI_PCH)) -> value pcu_msg;</span><br><span style="color: hsl(0, 100%, 40%);">-    /* First 3 bytes contain paging group: */</span><br><span style="color: hsl(0, 100%, 40%);">-       macblock := substr(pcu_msg.u.data_req.data, 3, pcu_msg.u.data_req.len - 3);</span><br><span style="color: hsl(0, 100%, 40%);">-     rr_imm_ass := dec_GsmRrMessage(macblock);</span><br><span style="color: hsl(0, 100%, 40%);">-       if (not match(rr_imm_ass, tr_IMM_TBF_ASS())) {</span><br><span style="color: hsl(0, 100%, 40%);">-          setverdict(fail, "Failed to match Immediate Assignment: ", rr_imm_ass);</span><br><span style="color: hsl(0, 100%, 40%);">-               f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-       f_pcuif_tx_data_cnf(pcu_msg);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Expect a Paging Request Type 1 from PCU on PCUIF on specified sapi.  */</span><br><span style="color: hsl(0, 100%, 40%);">-private function f_pcuif_rx_pch_pag_req1(template MobileIdentityV mi1 := ?,</span><br><span style="color: hsl(0, 100%, 40%);">-                                      template integer pag_group := ?)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT return GsmRrMessage {</span><br><span style="color: hsl(0, 100%, 40%);">-  var GsmRrMessage rr_pag_req1;</span><br><span style="color: hsl(0, 100%, 40%);">-   var PCUIF_Message pcu_msg;</span><br><span style="color: hsl(0, 100%, 40%);">-      var octetstring imsi_suff_octstr;</span><br><span style="color: hsl(0, 100%, 40%);">-       var integer pag_group_rx;</span><br><span style="color: hsl(0, 100%, 40%);">-       var octetstring macblock;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 0,</span><br><span style="color: hsl(0, 100%, 40%);">-                                   sapi := PCU_IF_SAPI_PCH)) -> value pcu_msg;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    /* First 3 bytes contain IMSI suffix to calculate paging group: */</span><br><span style="color: hsl(0, 100%, 40%);">-      imsi_suff_octstr := substr(pcu_msg.u.data_req.data, 0, 3);</span><br><span style="color: hsl(0, 100%, 40%);">-      pag_group_rx := str2int(oct2char(imsi_suff_octstr[0])) * 100 +</span><br><span style="color: hsl(0, 100%, 40%);">-                  str2int(oct2char(imsi_suff_octstr[1])) * 10 +</span><br><span style="color: hsl(0, 100%, 40%);">-                   str2int(oct2char(imsi_suff_octstr[2]));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Make sure we've got RR Paging Request Type 1 for a given MI */</span><br><span style="color: hsl(0, 100%, 40%);">-   macblock := substr(pcu_msg.u.data_req.data, 3, pcu_msg.u.data_req.len - 3);</span><br><span style="color: hsl(0, 100%, 40%);">-     rr_pag_req1 := dec_GsmRrMessage(macblock);</span><br><span style="color: hsl(0, 100%, 40%);">-      if (not match(rr_pag_req1, tr_PAG_REQ1(tr_MI_LV(mi1)))) {</span><br><span style="color: hsl(0, 100%, 40%);">-               setverdict(fail, "Failed to match Paging Request Type 1: ", rr_pag_req1);</span><br><span style="color: hsl(0, 100%, 40%);">-             f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* Make sure that received paging froup matches the expected one */</span><br><span style="color: hsl(0, 100%, 40%);">-     if (not match(pag_group_rx, pag_group)) {</span><br><span style="color: hsl(0, 100%, 40%);">-               setverdict(fail, "Paging group", pag_group_rx, " does not match expected ", pag_group);</span><br><span style="color: hsl(0, 100%, 40%);">-             f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       f_pcuif_tx_data_cnf(pcu_msg);</span><br><span style="color: hsl(0, 100%, 40%);">-   return rr_pag_req1;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Send one rlcmac UL block adding necessary extra padding at the end.</span><br><span style="color: hsl(0, 100%, 40%);">- * returns length of extra padding added at the end, in octets.</span><br><span style="color: hsl(0, 100%, 40%);">- *  FIXME: Only supports CS-1 so far.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-private function f_tx_rlcmac_ul_block(template (value) RlcmacUlBlock ul_data, int16_t lqual_cb := 0, uint32_t fn := 0)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT return integer {</span><br><span style="color: hsl(0, 100%, 40%);">- var octetstring data;</span><br><span style="color: hsl(0, 100%, 40%);">-   var integer padding_len;</span><br><span style="color: hsl(0, 100%, 40%);">-        /* Encode the payload of DATA.ind */</span><br><span style="color: hsl(0, 100%, 40%);">-    data := enc_RlcmacUlBlock(valueof(ul_data));</span><br><span style="color: hsl(0, 100%, 40%);">-    padding_len := 23 - lengthof(data);</span><br><span style="color: hsl(0, 100%, 40%);">-     data := f_pad_oct(data, 23, '00'O); /* CS-1 */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */</span><br><span style="color: hsl(0, 100%, 40%);">-        f_pcuif_tx_data_ind(data, lqual_cb, fn);</span><br><span style="color: hsl(0, 100%, 40%);">-        return padding_len;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-private function f_tx_rlcmac_ul_n_blocks(uint5_t tfi, inout uint14_t bsn, integer num_blocks := 1, template (omit) GprsTlli tlli := omit)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT return octetstring {</span><br><span style="color: hsl(0, 100%, 40%);">-       var octetstring total_payload := ''O;</span><br><span style="color: hsl(0, 100%, 40%);">-   var template (value) RlcmacUlBlock ul_data := t_RLCMAC_UL_DATA(</span><br><span style="color: hsl(0, 100%, 40%);">-         tfi := tfi,</span><br><span style="color: hsl(0, 100%, 40%);">-             cv := 15, /* num UL blocks to be sent (to be overridden in loop) */</span><br><span style="color: hsl(0, 100%, 40%);">-             bsn := 0, /* To be generated in loop */</span><br><span style="color: hsl(0, 100%, 40%);">-         blocks := { /* To be generated in loop */ });</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   if (not istemplatekind(tlli, "omit")) {</span><br><span style="color: hsl(0, 100%, 40%);">-               ul_data.data.mac_hdr.tlli_ind := true;</span><br><span style="color: hsl(0, 100%, 40%);">-          ul_data.data.tlli := tlli;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       for (var integer i := 0; i < num_blocks; i := i + 1) {</span><br><span style="color: hsl(0, 100%, 40%);">-               var integer padding_len;</span><br><span style="color: hsl(0, 100%, 40%);">-                var octetstring payload := f_rnd_octstring(10);</span><br><span style="color: hsl(0, 100%, 40%);">-         /* Prepare a new UL block (CV, random payload) */</span><br><span style="color: hsl(0, 100%, 40%);">-               var integer cv := num_blocks - i - 1;</span><br><span style="color: hsl(0, 100%, 40%);">-           if (cv > g_bs_cv_max) {</span><br><span style="color: hsl(0, 100%, 40%);">-                      cv := 15;</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-               ul_data.data.mac_hdr.countdown := cv;</span><br><span style="color: hsl(0, 100%, 40%);">-           ul_data.data.mac_hdr.bsn := bsn + i;</span><br><span style="color: hsl(0, 100%, 40%);">-            ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(payload)) };</span><br><span style="color: hsl(0, 100%, 40%);">-         padding_len := f_tx_rlcmac_ul_block(ul_data);</span><br><span style="color: hsl(0, 100%, 40%);">-           total_payload := total_payload & payload & f_pad_oct(''O, padding_len, '00'O);</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-       bsn := valueof(ul_data.data.mac_hdr.bsn) + 1; /* update bsn to point to next one */</span><br><span style="color: hsl(0, 100%, 40%);">-     return total_payload;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-private function f_rx_rlcmac_dl_block(out RlcmacDlBlock dl_block, out uint32_t dl_fn, template (present) CodingScheme exp_cs_mcs := ?)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT {</span><br><span style="color: hsl(0, 100%, 40%);">-   var PCUIF_Message pcu_msg;</span><br><span style="color: hsl(0, 100%, 40%);">-      f_pcuif_rx_data_req(pcu_msg);</span><br><span style="color: hsl(0, 100%, 40%);">-   dl_block := dec_RlcmacDlBlock(pcu_msg.u.data_req.data);</span><br><span style="color: hsl(0, 100%, 40%);">- dl_fn := pcu_msg.u.data_req.fn;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- var integer len := lengthof(pcu_msg.u.data_req.data);</span><br><span style="color: hsl(0, 100%, 40%);">-   var CodingScheme cs_mcs := f_rlcmac_block_len2cs_mcs(len)</span><br><span style="color: hsl(0, 100%, 40%);">-       if (not match(f_rlcmac_block_len2cs_mcs(len), exp_cs_mcs)) {</span><br><span style="color: hsl(0, 100%, 40%);">-            setverdict(fail, "Failed to match Coding Scheme exp ", exp_cs_mcs, " vs ", cs_mcs, " (", len, ")");</span><br><span style="color: hsl(0, 100%, 40%);">-             f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-private function f_rx_rlcmac_dl_block_exp_ack_nack(out RlcmacDlBlock dl_block, out uint32_t poll_fn)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT {</span><br><span style="color: hsl(0, 100%, 40%);">- var uint32_t dl_fn;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     f_rx_rlcmac_dl_block(dl_block, dl_fn);</span><br><span style="color: hsl(0, 100%, 40%);">-  if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK(ul_tfi := ?, tlli := ?))) {</span><br><span style="color: hsl(0, 100%, 40%);">-               setverdict(fail, "Failed to match Packet Uplink ACK / NACK");</span><br><span style="color: hsl(0, 100%, 40%);">-         f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       poll_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-private function f_rx_rlcmac_dl_block_exp_dummy(out RlcmacDlBlock dl_block)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT {</span><br><span style="color: hsl(0, 100%, 40%);">-       var uint32_t dl_fn;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     f_rx_rlcmac_dl_block(dl_block, dl_fn);</span><br><span style="color: hsl(0, 100%, 40%);">-  if (not match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {</span><br><span style="color: hsl(0, 100%, 40%);">-              setverdict(fail, "Failed to match Packet DUMMY DL");</span><br><span style="color: hsl(0, 100%, 40%);">-          f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-private function f_rx_rlcmac_dl_block_exp_pkt_ass(out RlcmacDlBlock dl_block, out uint32_t poll_fn)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT {</span><br><span style="color: hsl(0, 100%, 40%);">-  var uint32_t dl_fn;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     f_rx_rlcmac_dl_block(dl_block, dl_fn);</span><br><span style="color: hsl(0, 100%, 40%);">-  if (not match(dl_block, tr_RLCMAC_DL_PACKET_ASS())) {</span><br><span style="color: hsl(0, 100%, 40%);">-           setverdict(fail, "Failed to match Packet Downlink Assignment");</span><br><span style="color: hsl(0, 100%, 40%);">-               f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       poll_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-private function f_rx_rlcmac_dl_block_exp_pkt_ul_ass(out RlcmacDlBlock dl_block, out uint32_t poll_fn)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT {</span><br><span style="color: hsl(0, 100%, 40%);">-        var uint32_t dl_fn;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        f_rx_rlcmac_dl_block(dl_block, dl_fn);</span><br><span style="color: hsl(0, 100%, 40%);">-        if (not match(dl_block, tr_RLCMAC_UL_PACKET_ASS())) {</span><br><span style="color: hsl(0, 100%, 40%);">-                setverdict(fail, "Failed to match Packet Uplink Assignment");</span><br><span style="color: hsl(0, 100%, 40%);">-               f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       poll_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-private function f_rx_rlcmac_dl_block_exp_pkt_dl_ass(out RlcmacDlBlock dl_block, out uint32_t poll_fn)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT {</span><br><span style="color: hsl(0, 100%, 40%);">-        var uint32_t dl_fn;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        f_rx_rlcmac_dl_block(dl_block, dl_fn);</span><br><span style="color: hsl(0, 100%, 40%);">-        if (not match(dl_block, tr_RLCMAC_DL_PACKET_ASS())) {</span><br><span style="color: hsl(0, 100%, 40%);">-                setverdict(fail, "Failed to match Packet Downlink Assignment");</span><br><span style="color: hsl(0, 100%, 40%);">-             f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       poll_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-private function f_rx_rlcmac_dl_block_exp_pkt_pag_req(out RlcmacDlBlock dl_block)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT {</span><br><span style="color: hsl(0, 100%, 40%);">- var uint32_t dl_fn;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     f_rx_rlcmac_dl_block(dl_block, dl_fn);</span><br><span style="color: hsl(0, 100%, 40%);">-  if (not match(dl_block, tr_RLCMAC_PACKET_PAG_REQ())) {</span><br><span style="color: hsl(0, 100%, 40%);">-          setverdict(fail, "Failed to match Packet Paging Request: ", dl_block, " vs ", tr_RLCMAC_PACKET_PAG_REQ());</span><br><span style="color: hsl(0, 100%, 40%);">-          f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* This function does what could probably be done with templates */</span><br><span style="color: hsl(0, 100%, 40%);">-private function f_rlcmac_dl_block_verify_data_gprs(in RlcmacDlDataBlock data_block,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                   template (present) octetstring data := ?,</span><br><span style="color: hsl(0, 100%, 40%);">-                                               template (present) uint7_t exp_bsn := ?,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                template (present) CodingScheme exp_cs := ?)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT {</span><br><span style="color: hsl(0, 100%, 40%);">-       if (not match(data_block.mac_hdr.hdr_ext.bsn, exp_bsn)) {</span><br><span style="color: hsl(0, 100%, 40%);">-               setverdict(fail, "DL block BSN doesn't match: ",</span><br><span style="color: hsl(0, 100%, 40%);">-                     data_block.mac_hdr.hdr_ext.bsn, " vs exp ", exp_bsn);</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (lengthof(data_block.blocks) < 1) {</span><br><span style="color: hsl(0, 100%, 40%);">-               setverdict(fail, "DL block has no LLC payload: ", data_block);</span><br><span style="color: hsl(0, 100%, 40%);">-                f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (not match(data_block.blocks[0].payload, data)) {</span><br><span style="color: hsl(0, 100%, 40%);">-            setverdict(fail, "Failed to match content of LLC payload in DL Block: ",</span><br><span style="color: hsl(0, 100%, 40%);">-                         data_block.blocks[0].payload, " vs ", data);</span><br><span style="color: hsl(0, 100%, 40%);">-               f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* Check next data blocks contain dummy frames */</span><br><span style="color: hsl(0, 100%, 40%);">-       if (lengthof(data_block.blocks) > 1 and substr(data_block.blocks[1].payload, 0, 3) != '43C001'O) {</span><br><span style="color: hsl(0, 100%, 40%);">-           setverdict(fail, "Second data payload is not a dummy frame: ",</span><br><span style="color: hsl(0, 100%, 40%);">-                           data_block.blocks[1].payload);</span><br><span style="color: hsl(0, 100%, 40%);">-               f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* TODO: check exp_cs */</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* This function does what could probably be done with templates */</span><br><span style="color: hsl(0, 100%, 40%);">-private function f_rlcmac_dl_block_verify_data_egprs(in RlcmacDlEgprsDataBlock data_block,</span><br><span style="color: hsl(0, 100%, 40%);">-                                               template (present) octetstring data := ?,</span><br><span style="color: hsl(0, 100%, 40%);">-                                               template (present) uint14_t exp_bsn := ?,</span><br><span style="color: hsl(0, 100%, 40%);">-                                               template (present) CodingScheme exp_cs := ?)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT {</span><br><span style="color: hsl(0, 100%, 40%);">-      if (not match(data_block.mac_hdr.bsn1, exp_bsn)) {</span><br><span style="color: hsl(0, 100%, 40%);">-              setverdict(fail, "DL block BSN doesn't match: ",</span><br><span style="color: hsl(0, 100%, 40%);">-                     data_block.mac_hdr.bsn1, " vs exp ", exp_bsn);</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (lengthof(data_block.blocks) < 1) {</span><br><span style="color: hsl(0, 100%, 40%);">-               setverdict(fail, "DL block has no LLC payload: ", data_block);</span><br><span style="color: hsl(0, 100%, 40%);">-                f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (not match(data_block.blocks[0].payload, data)) {</span><br><span style="color: hsl(0, 100%, 40%);">-            setverdict(fail, "Failed to match content of LLC payload in DL Block: ",</span><br><span style="color: hsl(0, 100%, 40%);">-                         data_block.blocks[0].payload, " vs ", data);</span><br><span style="color: hsl(0, 100%, 40%);">-               f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* Check next data blocks contain dummy frames */</span><br><span style="color: hsl(0, 100%, 40%);">-       if (lengthof(data_block.blocks) > 1 and substr(data_block.blocks[1].payload, 0, 3) != '43C001'O) {</span><br><span style="color: hsl(0, 100%, 40%);">-           setverdict(fail, "Second data payload is not a dummy frame: ",</span><br><span style="color: hsl(0, 100%, 40%);">-                           data_block.blocks[1].payload);</span><br><span style="color: hsl(0, 100%, 40%);">-               f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* TODO: Check exp_cs. In the case of EGPRS, first check mac_hdr.header_type and then decode CPS = exp_cs based on mac_hdr.header_type.</span><br><span style="color: hsl(0, 100%, 40%);">-         See wireshark's egprs_Header_type1_coding_puncturing_scheme_to_mcs. */</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* High level (task specific) helper for receiving and matching GPRS/EGPRS data blocks */</span><br><span style="color: hsl(0, 100%, 40%);">-private function f_rx_rlcmac_dl_block_exp_data(out RlcmacDlBlock dl_block, out uint32_t dl_fn,</span><br><span style="color: hsl(0, 100%, 40%);">-                                             template (present) octetstring data := ?,</span><br><span style="color: hsl(0, 100%, 40%);">-                                               template (present) uint7_t exp_bsn := ?,</span><br><span style="color: hsl(0, 100%, 40%);">-                                        template (present) CodingScheme exp_cs := ?)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT {</span><br><span style="color: hsl(0, 100%, 40%);">-    /* FIXME: ideally we should use an alt statement with timeout here, rather than</span><br><span style="color: hsl(0, 100%, 40%);">-  * having +100500 layers of abstraction. This would facilitate developing the</span><br><span style="color: hsl(0, 100%, 40%);">-    * multi-TBF/-TRX/-BTS tests, where you cannot expect that the first received</span><br><span style="color: hsl(0, 100%, 40%);">-    * block is exactly what you need. */</span><br><span style="color: hsl(0, 100%, 40%);">-   f_rx_rlcmac_dl_block(dl_block, dl_fn);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  /* Make sure it's either GPRS or EGPRS data block */</span><br><span style="color: hsl(0, 100%, 40%);">-        if (not match(dl_block, tr_RLCMAC_DATA)) {</span><br><span style="color: hsl(0, 100%, 40%);">-              setverdict(fail, "Failed to match DL DATA: ", dl_block, " vs ", tr_RLCMAC_DATA);</span><br><span style="color: hsl(0, 100%, 40%);">-            f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (ischosen(dl_block.data_egprs)) {</span><br><span style="color: hsl(0, 100%, 40%);">-            f_rlcmac_dl_block_verify_data_egprs(dl_block.data_egprs, data, exp_bsn, exp_cs);</span><br><span style="color: hsl(0, 100%, 40%);">-        } else if (ischosen(dl_block.data)) {</span><br><span style="color: hsl(0, 100%, 40%);">-           f_rlcmac_dl_block_verify_data_gprs(dl_block.data, data, exp_bsn, exp_cs);</span><br><span style="color: hsl(0, 100%, 40%);">-       } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                /* Should not happen, but the caller may theoretically give us a template for CTRL */</span><br><span style="color: hsl(0, 100%, 40%);">-           setverdict(fail, "DL block is neither GPRS nor EGPRS data block: ", dl_block);</span><br><span style="color: hsl(0, 100%, 40%);">-                f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-private function f_dl_block_ack_fn(in RlcmacDlBlock dl_block, uint32_t dl_fn)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT return uint32_t {</span><br><span style="color: hsl(0, 100%, 40%);">-        var boolean rrbp_valid;</span><br><span style="color: hsl(0, 100%, 40%);">- var MacRrbp rrbp;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* The argument must be either a GPRS or EGPRS data block */</span><br><span style="color: hsl(0, 100%, 40%);">-    if (ischosen(dl_block.data_egprs)) {</span><br><span style="color: hsl(0, 100%, 40%);">-            rrbp_valid := true; /* always valid */</span><br><span style="color: hsl(0, 100%, 40%);">-          rrbp := dl_block.data_egprs.mac_hdr.rrbp;</span><br><span style="color: hsl(0, 100%, 40%);">-       } else if (ischosen(dl_block.data)) {</span><br><span style="color: hsl(0, 100%, 40%);">-           rrbp_valid := dl_block.data.mac_hdr.mac_hdr.rrbp_valid;</span><br><span style="color: hsl(0, 100%, 40%);">-         rrbp := dl_block.data.mac_hdr.mac_hdr.rrbp;</span><br><span style="color: hsl(0, 100%, 40%);">-     } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                rrbp_valid := dl_block.ctrl.mac_hdr.rrbp_valid;</span><br><span style="color: hsl(0, 100%, 40%);">-         rrbp := dl_block.ctrl.mac_hdr.rrbp;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* Make sure that the given block really needs to be ACKnowledged */</span><br><span style="color: hsl(0, 100%, 40%);">-    if (not rrbp_valid) {</span><br><span style="color: hsl(0, 100%, 40%);">-           setverdict(fail, "DL block shall not be ACKnowledged, field RRBP is not valid");</span><br><span style="color: hsl(0, 100%, 40%);">-              f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return f_rrbp_ack_fn(dl_fn, rrbp);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> testcase TC_pcuif_suspend() runs on RAW_PCU_Test_CT {</span><br><span>         var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.cell_id.ra_id);</span><br><span>     var GprsTlli tlli := 'FFFFFFFF'O;</span><br><span>@@ -2038,15 +1478,6 @@</span><br><span>   }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-private function f_pkt_paging_match_tmsi(in PacketPagingReq req, template GsmTmsi tmsi)</span><br><span style="color: hsl(0, 100%, 40%);">-runs on RAW_PCU_Test_CT {</span><br><span style="color: hsl(0, 100%, 40%);">-      if (not match(req.repeated_pageinfo.cs.tmsi, tmsi)) {</span><br><span style="color: hsl(0, 100%, 40%);">-           setverdict(fail, "Mobile Identity (TMSI/P-TMSI) mismatch: ",</span><br><span style="color: hsl(0, 100%, 40%);">-                     "expected: ", tmsi, "got: ", req.repeated_pageinfo.cs.tmsi);</span><br><span style="color: hsl(0, 100%, 40%);">-             f_shutdown(__BFILE__, __LINE__);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* Test CS paging over the BTS<->PCU socket.</span><br><span>  * When a (class B or C, not A) MS has an active TBF (or is on the PDCH), the MS can not react on CS paging over CCCH.</span><br><span>  * Paging should be send on the PACCH.</span><br><span>diff --git a/pcu/PCU_selftest.ttcn b/pcu/PCU_selftest.ttcn</span><br><span>index 15cdd80..70138bf 100644</span><br><span>--- a/pcu/PCU_selftest.ttcn</span><br><span>+++ b/pcu/PCU_selftest.ttcn</span><br><span>@@ -25,6 +25,7 @@</span><br><span> import from RLCMAC_CSN1_Types all;</span><br><span> import from RLCMAC_Types all;</span><br><span> import from RLCMAC_Templates all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from GPRS_Components all;</span><br><span> import from PCU_Tests all;</span><br><span> </span><br><span> type component dummy_CT extends BSSGP_Client_CT {</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/18333">change 18333</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/c/osmo-ttcn3-hacks/+/18333"/><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-Change-Id: Ieae27d6e707f79ec2145864ef5cd67ddbbec9314 </div>
<div style="display:none"> Gerrit-Change-Number: 18333 </div>
<div style="display:none"> Gerrit-PatchSet: 6 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: Vadim Yanitskiy <axilirator@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>