<p>pespin has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/17965">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">library/RLCMAC: Add partial support for EGPRS data block encoding/decoding<br><br>* RlcmacUlBlock and RlcmacDlBlock gain a new union field "egprs_data",<br>  which is chosen when msg contains an egprs data block. Hence one can<br>  use same structure for both gprs/egprs data and simply check<br>  "ischosen(block.data_egprs)" to know whether it contains egprs or gprs<br>  data block.<br>* C++ code in RLCMAC_EncDec.cc takes care of encoding and decoding of<br>  each data header type and exposes a generic ttcn3 struct<br>  "UlMacDataHeader" and "DlMacDataHeader". Decoded header type can be<br>  found in mac_hdr.header_type. This can be used t5ogether with CPS to<br>  get the MCS of the message received. Similarly, the encoder will use the<br>  same field to know how to encode the ttcn3 structure.<br>* In RLCMAC_EncDec.cc order of functions has been ordered to split<br>  between encoding and decoding, and inside these split between Ul and<br>  Dl messages.<br>* Only encoding of UL HeaderType3 and decoding of Dl HeaderType3 is<br>  implemented so far in RLCMAC_EncDec.cc. However, all code is already<br>  arranged and functions prepared (with FIXME fprintf) to easily add the<br>  missing header types once needed.<br>* Actually only the decoding of DL HeaderType3 has been tested to work so far.<br>  Encoding may still be missing to octet-align the data block after the header.<br>  All these wil lbe fixed once a test using them exists.<br><br>Change-Id: I2bc4f877a5e17c57ffa8cf05565dc8593b45aae8<br>---<br>M library/RLCMAC_EncDec.cc<br>M library/RLCMAC_Types.ttcn<br>2 files changed, 1,082 insertions(+), 158 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks refs/changes/65/17965/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/library/RLCMAC_EncDec.cc b/library/RLCMAC_EncDec.cc</span><br><span>index 4ae65b1..777815f 100644</span><br><span>--- a/library/RLCMAC_EncDec.cc</span><br><span>+++ b/library/RLCMAC_EncDec.cc</span><br><span>@@ -1,3 +1,6 @@</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <endian.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #include "RLCMAC_Types.hh"</span><br><span> #include "GSM_Types.hh"</span><br><span> /* Decoding of TS 44.060 GPRS RLC/MAC blocks, portions requiring manual functions</span><br><span>@@ -14,48 +17,341 @@</span><br><span> </span><br><span> namespace RLCMAC__Types {</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-OCTETSTRING enc__RlcmacDlDataBlock(const RlcmacDlDataBlock& si)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        RlcmacDlDataBlock in = si;</span><br><span style="color: hsl(0, 100%, 40%);">-      OCTETSTRING ret_val;</span><br><span style="color: hsl(0, 100%, 40%);">-    TTCN_Buffer ttcn_buffer;</span><br><span style="color: hsl(0, 100%, 40%);">-        int i;</span><br><span style="color: hsl(120, 100%, 40%);">+/////////////////////</span><br><span style="color: hsl(120, 100%, 40%);">+// INTENRAL HELPERS</span><br><span style="color: hsl(120, 100%, 40%);">+/////////////////////</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   /* Fix 'e' bit of initial header based on following blocks */</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!in.blocks().is_bound() ||</span><br><span style="color: hsl(0, 100%, 40%);">-      (in.blocks().size_of() == 1 && !in.blocks()[0].hdr().is_bound()))</span><br><span style="color: hsl(0, 100%, 40%);">-           in.mac__hdr().hdr__ext().e() = true;</span><br><span style="color: hsl(0, 100%, 40%);">-    else</span><br><span style="color: hsl(0, 100%, 40%);">-            in.mac__hdr().hdr__ext().e() = false;</span><br><span style="color: hsl(120, 100%, 40%);">+/* TS 04.60  10.3a.4.1.1 */</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlc_ul_header_egprs_1 {</span><br><span style="color: hsl(120, 100%, 40%);">+#if __BYTE_ORDER == __LITTLE_ENDIAN</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t r:1,</span><br><span style="color: hsl(120, 100%, 40%);">+           si:1,</span><br><span style="color: hsl(120, 100%, 40%);">+                 cv:4,</span><br><span style="color: hsl(120, 100%, 40%);">+                 tfi_hi:2;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t tfi_lo:3,</span><br><span style="color: hsl(120, 100%, 40%);">+              bsn1_hi:5;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t bsn1_lo:6,</span><br><span style="color: hsl(120, 100%, 40%);">+             bsn2_hi:2;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t bsn2_lo:8;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t cps:5,</span><br><span style="color: hsl(120, 100%, 40%);">+                 rsb:1,</span><br><span style="color: hsl(120, 100%, 40%);">+                pi:1,</span><br><span style="color: hsl(120, 100%, 40%);">+                 spare_hi:1;</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t spare_lo:6,</span><br><span style="color: hsl(120, 100%, 40%);">+            dummy:2;</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianess.py) */</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t tfi_hi:2, cv:4, si:1, r:1;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t bsn1_hi:5, tfi_lo:3;</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t bsn2_hi:2, bsn1_lo:6;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t bsn2_lo:8;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t spare_hi:1, pi:1, rsb:1, cps:5;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t dummy:2, spare_lo:6;</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+} __attribute__ ((packed));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   /* use automatic/generated decoder for header */</span><br><span style="color: hsl(0, 100%, 40%);">-        in.mac__hdr().encode(DlMacDataHeader_descr_, ttcn_buffer, TTCN_EncDec::CT_RAW);</span><br><span style="color: hsl(120, 100%, 40%);">+/* TS 04.60  10.3a.4.2.1 */</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlc_ul_header_egprs_2 {</span><br><span style="color: hsl(120, 100%, 40%);">+#if __BYTE_ORDER == __LITTLE_ENDIAN</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t r:1,</span><br><span style="color: hsl(120, 100%, 40%);">+           si:1,</span><br><span style="color: hsl(120, 100%, 40%);">+                 cv:4,</span><br><span style="color: hsl(120, 100%, 40%);">+                 tfi_hi:2;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t tfi_lo:3,</span><br><span style="color: hsl(120, 100%, 40%);">+              bsn1_hi:5;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t bsn1_lo:6,</span><br><span style="color: hsl(120, 100%, 40%);">+             cps_hi:2;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t cps_lo:1,</span><br><span style="color: hsl(120, 100%, 40%);">+              rsb:1,</span><br><span style="color: hsl(120, 100%, 40%);">+                pi:1,</span><br><span style="color: hsl(120, 100%, 40%);">+                 spare_hi:5;</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t spare_lo:5,</span><br><span style="color: hsl(120, 100%, 40%);">+            dummy:3;</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianess.py) */</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t tfi_hi:2, cv:4, si:1, r:1;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t bsn1_hi:5, tfi_lo:3;</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t cps_hi:2, bsn1_lo:6;</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t spare_hi:5, pi:1, rsb:1, cps_lo:1;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t dummy:3, spare_lo:5;</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+} __attribute__ ((packed));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   /* Add LI octets, if any */</span><br><span style="color: hsl(0, 100%, 40%);">-     if (in.blocks().is_bound() &&</span><br><span style="color: hsl(0, 100%, 40%);">-       (in.blocks().size_of() != 1 || in.blocks()[0].hdr().is_bound())) {</span><br><span style="color: hsl(0, 100%, 40%);">-          /* first write LI octets */</span><br><span style="color: hsl(0, 100%, 40%);">-             for (i = 0; i < in.blocks().size_of(); i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        /* fix the 'E' bit in case it is not clear */</span><br><span style="color: hsl(0, 100%, 40%);">-                   if (i < in.blocks().size_of()-1)</span><br><span style="color: hsl(0, 100%, 40%);">-                             in.blocks()[i].hdr()().e() = false;</span><br><span style="color: hsl(0, 100%, 40%);">-                     else</span><br><span style="color: hsl(0, 100%, 40%);">-                            in.blocks()[i].hdr()().e() = true;</span><br><span style="color: hsl(0, 100%, 40%);">-                      in.blocks()[i].hdr()().encode(LlcBlockHdr_descr_, ttcn_buffer, TTCN_EncDec::CT_RAW);</span><br><span style="color: hsl(0, 100%, 40%);">-            }</span><br><span style="color: hsl(120, 100%, 40%);">+/* TS 04.60  10.3a.4.3.1 */</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlc_ul_header_egprs_3 {</span><br><span style="color: hsl(120, 100%, 40%);">+#if __BYTE_ORDER == __LITTLE_ENDIAN</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t r:1,</span><br><span style="color: hsl(120, 100%, 40%);">+           si:1,</span><br><span style="color: hsl(120, 100%, 40%);">+                 cv:4,</span><br><span style="color: hsl(120, 100%, 40%);">+                 tfi_hi:2;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t tfi_lo:3,</span><br><span style="color: hsl(120, 100%, 40%);">+              bsn1_hi:5;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t bsn1_lo:6,</span><br><span style="color: hsl(120, 100%, 40%);">+             cps_hi:2;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t cps_lo:2,</span><br><span style="color: hsl(120, 100%, 40%);">+              spb:2,</span><br><span style="color: hsl(120, 100%, 40%);">+                rsb:1,</span><br><span style="color: hsl(120, 100%, 40%);">+                pi:1,</span><br><span style="color: hsl(120, 100%, 40%);">+                 spare:1,</span><br><span style="color: hsl(120, 100%, 40%);">+              dummy:1;</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianess.py) */</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t tfi_hi:2, cv:4, si:1, r:1;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t bsn1_hi:5, tfi_lo:3;</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t cps_hi:2, bsn1_lo:6;</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t dummy:1, spare:1, pi:1, rsb:1, spb:2, cps_lo:2;</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+} __attribute__ ((packed));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlc_dl_header_egprs_1 {</span><br><span style="color: hsl(120, 100%, 40%);">+#if __BYTE_ORDER == __LITTLE_ENDIAN</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t usf:3,</span><br><span style="color: hsl(120, 100%, 40%);">+                 es_p:2,</span><br><span style="color: hsl(120, 100%, 40%);">+               rrbp:2,</span><br><span style="color: hsl(120, 100%, 40%);">+               tfi_hi:1;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t tfi_lo:4,</span><br><span style="color: hsl(120, 100%, 40%);">+              pr:2,</span><br><span style="color: hsl(120, 100%, 40%);">+                 bsn1_hi:2;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t bsn1_mid:8;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t bsn1_lo:1,</span><br><span style="color: hsl(120, 100%, 40%);">+             bsn2_hi:7;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t bsn2_lo:3,</span><br><span style="color: hsl(120, 100%, 40%);">+             cps:5;</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianess.py) */</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t tfi_hi:1, rrbp:2, es_p:2, usf:3;</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t bsn1_hi:2, pr:2, tfi_lo:4;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t bsn1_mid:8;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t bsn2_hi:7, bsn1_lo:1;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t cps:5, bsn2_lo:3;</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+} __attribute__ ((packed));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlc_dl_header_egprs_2 {</span><br><span style="color: hsl(120, 100%, 40%);">+#if __BYTE_ORDER == __LITTLE_ENDIAN</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t usf:3,</span><br><span style="color: hsl(120, 100%, 40%);">+                 es_p:2,</span><br><span style="color: hsl(120, 100%, 40%);">+               rrbp:2,</span><br><span style="color: hsl(120, 100%, 40%);">+               tfi_hi:1;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t tfi_lo:4,</span><br><span style="color: hsl(120, 100%, 40%);">+              pr:2,</span><br><span style="color: hsl(120, 100%, 40%);">+                 bsn1_hi:2;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t bsn1_mid:8;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t bsn1_lo:1,</span><br><span style="color: hsl(120, 100%, 40%);">+             cps:3,</span><br><span style="color: hsl(120, 100%, 40%);">+                dummy:4;</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianess.py) */</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t tfi_hi:1, rrbp:2, es_p:2, usf:3;</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t bsn1_hi:2, pr:2, tfi_lo:4;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t bsn1_mid:8;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t dummy:4, cps:3, bsn1_lo:1;</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+} __attribute__ ((packed));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlc_dl_header_egprs_3 {</span><br><span style="color: hsl(120, 100%, 40%);">+#if __BYTE_ORDER == __LITTLE_ENDIAN</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t usf:3,</span><br><span style="color: hsl(120, 100%, 40%);">+                 es_p:2,</span><br><span style="color: hsl(120, 100%, 40%);">+               rrbp:2,</span><br><span style="color: hsl(120, 100%, 40%);">+               tfi_hi:1;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t tfi_lo:4,</span><br><span style="color: hsl(120, 100%, 40%);">+              pr:2,</span><br><span style="color: hsl(120, 100%, 40%);">+                 bsn1_hi:2;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t bsn1_mid:8;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t bsn1_lo:1,</span><br><span style="color: hsl(120, 100%, 40%);">+             cps:4,</span><br><span style="color: hsl(120, 100%, 40%);">+                spb:2,</span><br><span style="color: hsl(120, 100%, 40%);">+                dummy:1;</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianess.py) */</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t tfi_hi:1, rrbp:2, es_p:2, usf:3;</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t bsn1_hi:2, pr:2, tfi_lo:4;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t bsn1_mid:8;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t dummy:1, spb:2, cps:4, bsn1_lo:1;</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+} __attribute__ ((packed));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static CodingScheme::enum_type payload_len_2_coding_scheme(size_t payload_len) {</span><br><span style="color: hsl(120, 100%, 40%);">+    switch (payload_len) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case 23:</span><br><span style="color: hsl(120, 100%, 40%);">+              return CodingScheme::CS__1;</span><br><span style="color: hsl(120, 100%, 40%);">+   case 34:</span><br><span style="color: hsl(120, 100%, 40%);">+              return CodingScheme::CS__2;</span><br><span style="color: hsl(120, 100%, 40%);">+   case 40:</span><br><span style="color: hsl(120, 100%, 40%);">+              return CodingScheme::CS__3;</span><br><span style="color: hsl(120, 100%, 40%);">+   case 54:</span><br><span style="color: hsl(120, 100%, 40%);">+              return CodingScheme::CS__4;</span><br><span style="color: hsl(120, 100%, 40%);">+   case 27:</span><br><span style="color: hsl(120, 100%, 40%);">+              return CodingScheme::MCS__1;</span><br><span style="color: hsl(120, 100%, 40%);">+  case 33:</span><br><span style="color: hsl(120, 100%, 40%);">+              return CodingScheme::MCS__2;</span><br><span style="color: hsl(120, 100%, 40%);">+  case 42:</span><br><span style="color: hsl(120, 100%, 40%);">+              return CodingScheme::MCS__3;</span><br><span style="color: hsl(120, 100%, 40%);">+  case 49:</span><br><span style="color: hsl(120, 100%, 40%);">+              return CodingScheme::MCS__4;</span><br><span style="color: hsl(120, 100%, 40%);">+  case 61:</span><br><span style="color: hsl(120, 100%, 40%);">+              return CodingScheme::MCS__5;</span><br><span style="color: hsl(120, 100%, 40%);">+  case 79:</span><br><span style="color: hsl(120, 100%, 40%);">+              return CodingScheme::MCS__6;</span><br><span style="color: hsl(120, 100%, 40%);">+  case 119:</span><br><span style="color: hsl(120, 100%, 40%);">+             return CodingScheme::MCS__7;</span><br><span style="color: hsl(120, 100%, 40%);">+  case 142:</span><br><span style="color: hsl(120, 100%, 40%);">+             return CodingScheme::MCS__8;</span><br><span style="color: hsl(120, 100%, 40%);">+  case 155:</span><br><span style="color: hsl(120, 100%, 40%);">+             return CodingScheme::MCS__9;</span><br><span style="color: hsl(120, 100%, 40%);">+  default:</span><br><span style="color: hsl(120, 100%, 40%);">+              return CodingScheme::CS__1;</span><br><span>  }</span><br><span style="color: hsl(0, 100%, 40%);">-       if (in.blocks().is_bound()) {</span><br><span style="color: hsl(0, 100%, 40%);">-           for (i = 0; i < in.blocks().size_of(); i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        if (!in.blocks()[i].is_bound())</span><br><span style="color: hsl(0, 100%, 40%);">-                         continue;</span><br><span style="color: hsl(0, 100%, 40%);">-                       ttcn_buffer.put_string(in.blocks()[i].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%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       ttcn_buffer.get_string(ret_val);</span><br><span style="color: hsl(0, 100%, 40%);">-        return ret_val;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static unsigned int coding_scheme_2_data_block_len(CodingScheme::enum_type mcs) {</span><br><span style="color: hsl(120, 100%, 40%);">+   switch (mcs) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case CodingScheme::MCS__0:</span><br><span style="color: hsl(120, 100%, 40%);">+            return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     case CodingScheme::MCS__1:</span><br><span style="color: hsl(120, 100%, 40%);">+            return 22;</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__2:</span><br><span style="color: hsl(120, 100%, 40%);">+            return 28;</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__3:</span><br><span style="color: hsl(120, 100%, 40%);">+            return 37;</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__4:</span><br><span style="color: hsl(120, 100%, 40%);">+            return 44;</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__5:</span><br><span style="color: hsl(120, 100%, 40%);">+            return 56;</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__6:</span><br><span style="color: hsl(120, 100%, 40%);">+            return 74;</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__7:</span><br><span style="color: hsl(120, 100%, 40%);">+            return 56;</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__8:</span><br><span style="color: hsl(120, 100%, 40%);">+            return 68;</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__9:</span><br><span style="color: hsl(120, 100%, 40%);">+            return 74;</span><br><span style="color: hsl(120, 100%, 40%);">+    default:</span><br><span style="color: hsl(120, 100%, 40%);">+              return 22; /* MCS1*/</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%);">+static uint8_t bs2uint8(const BITSTRING& bs)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   int len = bs.lengthof();</span><br><span style="color: hsl(120, 100%, 40%);">+      int i;</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t res = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+      for (i = 0; i < len; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                res = res << 1;</span><br><span style="color: hsl(120, 100%, 40%);">+         res |= (bs[i].get_bit() ? 1 : 0);</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     return res;</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%);">+/* determine the number of rlc data blocks and their size / offsets */</span><br><span style="color: hsl(120, 100%, 40%);">+static void</span><br><span style="color: hsl(120, 100%, 40%);">+setup_rlc_mac_priv(CodingScheme::enum_type mcs, EgprsHeaderType::enum_type hdrtype, boolean is_uplink,</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int *n_calls, unsigned int *data_block_bits, unsigned int *data_block_offsets)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    unsigned int nc, dbl = 0, dbo[2] = {0,0};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   dbl = coding_scheme_2_data_block_len(mcs);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  switch (hdrtype) {</span><br><span style="color: hsl(120, 100%, 40%);">+    case EgprsHeaderType::RLCMAC__HDR__TYPE__1:</span><br><span style="color: hsl(120, 100%, 40%);">+           nc = 3;</span><br><span style="color: hsl(120, 100%, 40%);">+               dbo[0] = is_uplink ? 5*8 + 6 : 5*8 + 0;</span><br><span style="color: hsl(120, 100%, 40%);">+               dbo[1] = dbo[0] + dbl * 8 + 2;</span><br><span style="color: hsl(120, 100%, 40%);">+                break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case EgprsHeaderType::RLCMAC__HDR__TYPE__2:</span><br><span style="color: hsl(120, 100%, 40%);">+           nc = 2;</span><br><span style="color: hsl(120, 100%, 40%);">+               dbo[0] = is_uplink ? 4*8 + 5 : 3*8 + 4;</span><br><span style="color: hsl(120, 100%, 40%);">+               break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case EgprsHeaderType::RLCMAC__HDR__TYPE__3:</span><br><span style="color: hsl(120, 100%, 40%);">+           nc = 2;</span><br><span style="color: hsl(120, 100%, 40%);">+               dbo[0] = 3*8 + 7;</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              nc = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+               break;</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%);">+   *n_calls = nc;</span><br><span style="color: hsl(120, 100%, 40%);">+        *data_block_bits = dbl * 8 + 2;</span><br><span style="color: hsl(120, 100%, 40%);">+       data_block_offsets[0] = dbo[0];</span><br><span style="color: hsl(120, 100%, 40%);">+       data_block_offsets[1] = dbo[1];</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%);">+/* bit-shift the entire 'src' of length 'length_bytes' by 'offset_bits'</span><br><span style="color: hsl(120, 100%, 40%);">+ * and store the reuslt to caller-allocated 'buffer'.  The shifting is</span><br><span style="color: hsl(120, 100%, 40%);">+ * done lsb-first. */</span><br><span style="color: hsl(120, 100%, 40%);">+static void clone_aligned_buffer_lsbf(unsigned int offset_bits, unsigned int length_bytes,</span><br><span style="color: hsl(120, 100%, 40%);">+      const uint8_t *src, uint8_t *buffer)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       unsigned int hdr_bytes;</span><br><span style="color: hsl(120, 100%, 40%);">+       unsigned int extra_bits;</span><br><span style="color: hsl(120, 100%, 40%);">+      unsigned int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t c, last_c;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t *dst;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       hdr_bytes = offset_bits / 8;</span><br><span style="color: hsl(120, 100%, 40%);">+  extra_bits = offset_bits % 8;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       fprintf(stderr, "RLMAC: clone: hdr_bytes=%u extra_bits=%u (length_bytes=%u)\n", hdr_bytes, extra_bits, length_bytes);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (extra_bits == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                /* It is aligned already */</span><br><span style="color: hsl(120, 100%, 40%);">+           memcpy(buffer, src + hdr_bytes, length_bytes);</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%);">+   dst = buffer;</span><br><span style="color: hsl(120, 100%, 40%);">+ src = src + hdr_bytes;</span><br><span style="color: hsl(120, 100%, 40%);">+        last_c = *(src++);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  for (i = 0; i < length_bytes; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+               c = src[i];</span><br><span style="color: hsl(120, 100%, 40%);">+           *(dst++) = (last_c >> extra_bits) | (c << (8 - extra_bits));</span><br><span style="color: hsl(120, 100%, 40%);">+              last_c = c;</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%);">+/* obtain an (aligned) EGPRS data block with given bit-offset and</span><br><span style="color: hsl(120, 100%, 40%);">+ * bit-length from the parent buffer */</span><br><span style="color: hsl(120, 100%, 40%);">+static void get_egprs_data_block(const TTCN_Buffer& orig_ttcn_buffer, unsigned int offset_bits,</span><br><span style="color: hsl(120, 100%, 40%);">+       unsigned int length_bits, TTCN_Buffer& dst_ttcn_buffer)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        const unsigned int initial_spare_bits = 6;</span><br><span style="color: hsl(120, 100%, 40%);">+    unsigned char *aligned_buf = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+    size_t min_src_length_bytes = (offset_bits + length_bits + 7) / 8;</span><br><span style="color: hsl(120, 100%, 40%);">+    size_t length_bytes = (initial_spare_bits + length_bits + 7) / 8;</span><br><span style="color: hsl(120, 100%, 40%);">+     size_t accepted_len = length_bytes;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ fprintf(stderr, "RLMAC: trying to allocate %u bytes (orig is %zu bytes long with read pos %zu)\n", length_bytes, orig_ttcn_buffer.get_len(), orig_ttcn_buffer.get_pos());</span><br><span style="color: hsl(120, 100%, 40%);">+   dst_ttcn_buffer.get_end(aligned_buf, accepted_len);</span><br><span style="color: hsl(120, 100%, 40%);">+   fprintf(stderr, "RLMAC: For dst ptr=%p with length=%zu\n", aligned_buf, accepted_len);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (accepted_len < length_bytes) {</span><br><span style="color: hsl(120, 100%, 40%);">+         fprintf(stderr, "RLMAC: ERROR! asked for %zu bytes but got %zu\n", length_bytes, accepted_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%);">+   /* Copy the data out of the tvb to an aligned buffer */</span><br><span style="color: hsl(120, 100%, 40%);">+       clone_aligned_buffer_lsbf(</span><br><span style="color: hsl(120, 100%, 40%);">+            offset_bits - initial_spare_bits, length_bytes,</span><br><span style="color: hsl(120, 100%, 40%);">+               orig_ttcn_buffer.get_data(),</span><br><span style="color: hsl(120, 100%, 40%);">+          aligned_buf);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       fprintf(stderr, "RLMAC: clone_aligned_buffer_lsbf success\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* clear spare bits and move block header bits to the right */</span><br><span style="color: hsl(120, 100%, 40%);">+        aligned_buf[0] = aligned_buf[0] >> initial_spare_bits;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        dst_ttcn_buffer.increase_length(length_bytes);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/////////////////////</span><br><span style="color: hsl(120, 100%, 40%);">+// DECODE</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%);">+/* DECODE DOWNLINK */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> RlcmacDlDataBlock dec__RlcmacDlDataBlock(const OCTETSTRING& stream)</span><br><span> {</span><br><span>    RlcmacDlDataBlock ret_val;</span><br><span>@@ -105,6 +401,534 @@</span><br><span>   return ret_val;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static</span><br><span style="color: hsl(120, 100%, 40%);">+EgprsDlMacDataHeader dec__EgprsDlMacDataHeader_type1(const OCTETSTRING& stream)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      EgprsDlMacDataHeader ret_val;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       fprintf(stderr, "FIXME: Not implemented! %s (%s:%u)\n", __func__, __FILE__, __LINE__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return ret_val;</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%);">+static</span><br><span style="color: hsl(120, 100%, 40%);">+EgprsDlMacDataHeader dec__EgprsDlMacDataHeader_type2(const OCTETSTRING& stream)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  EgprsDlMacDataHeader ret_val;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       fprintf(stderr, "FIXME: Not implemented! %s (%s:%u)\n", __func__, __FILE__, __LINE__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return ret_val;</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%);">+static</span><br><span style="color: hsl(120, 100%, 40%);">+EgprsDlMacDataHeader dec__EgprsDlMacDataHeader_type3(const OCTETSTRING& stream)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  TTCN_Buffer ttcn_buffer(stream);</span><br><span style="color: hsl(120, 100%, 40%);">+      EgprsDlMacDataHeader ret_val;</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct gprs_rlc_dl_header_egprs_3 *egprs3;</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t tmp;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        egprs3 = static_cast<const struct gprs_rlc_dl_header_egprs_3 *></span><br><span style="color: hsl(120, 100%, 40%);">+         ((const void *)ttcn_buffer.get_data());</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     ret_val.header__type() = EgprsHeaderType::RLCMAC__HDR__TYPE__3;</span><br><span style="color: hsl(120, 100%, 40%);">+       ret_val.tfi() = egprs3->tfi_lo << 1 | egprs3->tfi_hi << 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  ret_val.rrbp() = egprs3->rrbp;</span><br><span style="color: hsl(120, 100%, 40%);">+     tmp = egprs3->es_p;</span><br><span style="color: hsl(120, 100%, 40%);">+        ret_val.esp() = BITSTRING(2, &tmp);</span><br><span style="color: hsl(120, 100%, 40%);">+       ret_val.usf() = egprs3->usf;</span><br><span style="color: hsl(120, 100%, 40%);">+       ret_val.bsn1() = egprs3->bsn1_lo << 10 | egprs3->bsn1_mid << 2 | egprs3->bsn1_hi;</span><br><span style="color: hsl(120, 100%, 40%);">+        ret_val.bsn2__offset() = 0; /*TODO: mark optional and not set ? */</span><br><span style="color: hsl(120, 100%, 40%);">+    ret_val.pr() = egprs3->pr;</span><br><span style="color: hsl(120, 100%, 40%);">+ ret_val.spb() = egprs3->spb;</span><br><span style="color: hsl(120, 100%, 40%);">+       ret_val.cps() = egprs3->cps;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     ttcn_buffer.increase_pos(sizeof(*egprs3));</span><br><span style="color: hsl(120, 100%, 40%);">+    return ret_val;</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%);">+static</span><br><span style="color: hsl(120, 100%, 40%);">+RlcmacDlEgprsDataBlock dec__RlcmacDlEgprsDataBlock(const OCTETSTRING& stream, CodingScheme::enum_type mcs)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       RlcmacDlEgprsDataBlock ret_val;</span><br><span style="color: hsl(120, 100%, 40%);">+       TTCN_Buffer ttcn_buffer(stream);</span><br><span style="color: hsl(120, 100%, 40%);">+      TTCN_Buffer aligned_buffer;</span><br><span style="color: hsl(120, 100%, 40%);">+   int num_llc_blocks = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+       unsigned int data_block_bits, data_block_offsets[2];</span><br><span style="color: hsl(120, 100%, 40%);">+  unsigned int num_calls;</span><br><span style="color: hsl(120, 100%, 40%);">+       const uint8_t *ti_e;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        switch (mcs) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case CodingScheme::MCS__0:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__1:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__2:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__3:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__4:</span><br><span style="color: hsl(120, 100%, 40%);">+            ret_val.mac__hdr() = dec__EgprsDlMacDataHeader_type3(stream);</span><br><span style="color: hsl(120, 100%, 40%);">+         break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case CodingScheme::MCS__5:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__6:</span><br><span style="color: hsl(120, 100%, 40%);">+            ret_val.mac__hdr() = dec__EgprsDlMacDataHeader_type2(stream);</span><br><span style="color: hsl(120, 100%, 40%);">+         break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case CodingScheme::MCS__7:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__8:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__9:</span><br><span style="color: hsl(120, 100%, 40%);">+            ret_val.mac__hdr() = dec__EgprsDlMacDataHeader_type1(stream);</span><br><span style="color: hsl(120, 100%, 40%);">+         break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     setup_rlc_mac_priv(mcs, ret_val.mac__hdr().header__type(), false,</span><br><span style="color: hsl(120, 100%, 40%);">+                        &num_calls, &data_block_bits, data_block_offsets);</span><br><span style="color: hsl(120, 100%, 40%);">+ get_egprs_data_block(ttcn_buffer, data_block_offsets[0], data_block_bits, aligned_buffer);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  ti_e = aligned_buffer.get_read_data();</span><br><span style="color: hsl(120, 100%, 40%);">+        ret_val.fbi() = *ti_e & 0x02 ? true : false;</span><br><span style="color: hsl(120, 100%, 40%);">+      ret_val.e() = *ti_e & 0x01 ? true : false;</span><br><span style="color: hsl(120, 100%, 40%);">+        aligned_buffer.increase_pos(1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* optional extension octets, containing LI+E of Llc blocks */</span><br><span style="color: hsl(120, 100%, 40%);">+        if (ret_val.e() == false) {</span><br><span style="color: hsl(120, 100%, 40%);">+           /* extension octet follows, i.e. optional Llc length octets */</span><br><span style="color: hsl(120, 100%, 40%);">+                while (1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   /* decode one more extension octet with LlcBlocHdr inside */</span><br><span style="color: hsl(120, 100%, 40%);">+                  EgprsLlcBlock lb;</span><br><span style="color: hsl(120, 100%, 40%);">+                     lb.hdr()().decode(EgprsLlcBlockHdr_descr_, aligned_buffer, TTCN_EncDec::CT_RAW);</span><br><span style="color: hsl(120, 100%, 40%);">+                      ret_val.blocks()[num_llc_blocks++] = lb;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                    /* if E == '1'B, we can proceed further */</span><br><span style="color: hsl(120, 100%, 40%);">+                    if (lb.hdr()().e() == true)</span><br><span style="color: hsl(120, 100%, 40%);">+                           break;</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%);">+   /* RLC blocks at end */</span><br><span style="color: hsl(120, 100%, 40%);">+       if (ret_val.blocks().is_bound()) {</span><br><span style="color: hsl(120, 100%, 40%);">+            for (int i = 0; i < ret_val.blocks().size_of(); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     unsigned int length = ret_val.blocks()[i].hdr()().length__ind();</span><br><span style="color: hsl(120, 100%, 40%);">+                      if (length > aligned_buffer.get_read_len())</span><br><span style="color: hsl(120, 100%, 40%);">+                                length = aligned_buffer.get_read_len();</span><br><span style="color: hsl(120, 100%, 40%);">+                       ret_val.blocks()[i].payload() = OCTETSTRING(length, aligned_buffer.get_read_data());</span><br><span style="color: hsl(120, 100%, 40%);">+                  aligned_buffer.increase_pos(length);</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 ret_val;</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%);">+RlcmacDlBlock dec__RlcmacDlBlock(const OCTETSTRING& stream)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      RlcmacDlBlock ret_val;</span><br><span style="color: hsl(120, 100%, 40%);">+        size_t stream_len = stream.lengthof();</span><br><span style="color: hsl(120, 100%, 40%);">+        CodingScheme::enum_type mcs = payload_len_2_coding_scheme(stream_len);</span><br><span style="color: hsl(120, 100%, 40%);">+        unsigned char pt;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   switch (mcs) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case CodingScheme::CS__1:</span><br><span style="color: hsl(120, 100%, 40%);">+     case CodingScheme::CS__2:</span><br><span style="color: hsl(120, 100%, 40%);">+     case CodingScheme::CS__3:</span><br><span style="color: hsl(120, 100%, 40%);">+     case CodingScheme::CS__4:</span><br><span style="color: hsl(120, 100%, 40%);">+             pt = stream[0].get_octet() >> 6;</span><br><span style="color: hsl(120, 100%, 40%);">+                if (pt == MacPayloadType::MAC__PT__RLC__DATA)</span><br><span style="color: hsl(120, 100%, 40%);">+                 ret_val.data() = dec__RlcmacDlDataBlock(stream);</span><br><span style="color: hsl(120, 100%, 40%);">+              else</span><br><span style="color: hsl(120, 100%, 40%);">+                  ret_val.ctrl() = dec__RlcmacDlCtrlBlock(stream);</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case CodingScheme::MCS__0:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__1:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__2:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__3:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__4:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__5:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__6:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__7:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__8:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__9:</span><br><span style="color: hsl(120, 100%, 40%);">+            ret_val.data__egprs() = dec__RlcmacDlEgprsDataBlock(stream, mcs);</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     return ret_val;</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%);">+/* DECODE UPLINK */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+RlcmacUlDataBlock dec__RlcmacUlDataBlock(const OCTETSTRING& stream)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       RlcmacUlDataBlock ret_val;</span><br><span style="color: hsl(120, 100%, 40%);">+    TTCN_Buffer ttcn_buffer(stream);</span><br><span style="color: hsl(120, 100%, 40%);">+      int num_llc_blocks = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);</span><br><span style="color: hsl(120, 100%, 40%);">+  TTCN_Logger::log_event_str("==================================\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                           "dec_RlcmacUlDataBlock(): Stream before decoding: ");</span><br><span style="color: hsl(120, 100%, 40%);">+       stream.log();</span><br><span style="color: hsl(120, 100%, 40%);">+ TTCN_Logger::end_event();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* use automatic/generated decoder for header */</span><br><span style="color: hsl(120, 100%, 40%);">+      ret_val.mac__hdr().decode(UlMacDataHeader_descr_, ttcn_buffer, TTCN_EncDec::CT_RAW);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);</span><br><span style="color: hsl(120, 100%, 40%);">+  TTCN_Logger::log_event_str("dec_RlcmacUlDataBlock(): Stream after decoding hdr: ");</span><br><span style="color: hsl(120, 100%, 40%);">+ ttcn_buffer.log();</span><br><span style="color: hsl(120, 100%, 40%);">+    TTCN_Logger::end_event();</span><br><span style="color: hsl(120, 100%, 40%);">+     TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);</span><br><span style="color: hsl(120, 100%, 40%);">+  TTCN_Logger::log_event_str("dec_RlcmacUlDataBlock(): ret_val after decoding hdr: ");</span><br><span style="color: hsl(120, 100%, 40%);">+        ret_val.log();</span><br><span style="color: hsl(120, 100%, 40%);">+        TTCN_Logger::end_event();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Manually decoder remainder of ttcn_buffer, containing optional header octets,</span><br><span style="color: hsl(120, 100%, 40%);">+       * optional tlli, optional pfi and LLC Blocks */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* optional extension octets, containing LI+M+E of Llc blocks */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (ret_val.mac__hdr().e() == false) {</span><br><span style="color: hsl(120, 100%, 40%);">+                /* extension octet follows, i.e. optional Llc length octets */</span><br><span style="color: hsl(120, 100%, 40%);">+                while (1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   /* decode one more extension octet with LlcBlocHdr inside */</span><br><span style="color: hsl(120, 100%, 40%);">+                  LlcBlock lb;</span><br><span style="color: hsl(120, 100%, 40%);">+                  lb.hdr()().decode(LlcBlockHdr_descr_, ttcn_buffer, TTCN_EncDec::CT_RAW);</span><br><span style="color: hsl(120, 100%, 40%);">+                      ret_val.blocks()[num_llc_blocks++] = lb;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                    TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);</span><br><span style="color: hsl(120, 100%, 40%);">+                  TTCN_Logger::log_event_str("dec_RlcmacUlDataBlock(): Stream after decoding ExtOct: ");</span><br><span style="color: hsl(120, 100%, 40%);">+                      ttcn_buffer.log();</span><br><span style="color: hsl(120, 100%, 40%);">+                    TTCN_Logger::end_event();</span><br><span style="color: hsl(120, 100%, 40%);">+                     TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);</span><br><span style="color: hsl(120, 100%, 40%);">+                  TTCN_Logger::log_event_str("dec_RlcmacUlDataBlock(): ret_val after decoding ExtOct: ");</span><br><span style="color: hsl(120, 100%, 40%);">+                     ret_val.log();</span><br><span style="color: hsl(120, 100%, 40%);">+                        TTCN_Logger::end_event();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   /* if E == '1'B, we can proceed further */</span><br><span style="color: hsl(120, 100%, 40%);">+                    if (lb.hdr()().e() == true)</span><br><span style="color: hsl(120, 100%, 40%);">+                           break;</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%);">+   /* parse optional TLLI */</span><br><span style="color: hsl(120, 100%, 40%);">+     if (ret_val.mac__hdr().tlli__ind()) {</span><br><span style="color: hsl(120, 100%, 40%);">+         ret_val.tlli() = OCTETSTRING(4, ttcn_buffer.get_read_data());</span><br><span style="color: hsl(120, 100%, 40%);">+         ttcn_buffer.increase_pos(4);</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+     /* parse optional PFI */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (ret_val.mac__hdr().pfi__ind()) {</span><br><span style="color: hsl(120, 100%, 40%);">+          ret_val.pfi().decode(RlcmacUlDataBlock_pfi_descr_, ttcn_buffer, TTCN_EncDec::CT_RAW);</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%);">+   /* RLC blocks at end */</span><br><span style="color: hsl(120, 100%, 40%);">+       if (ret_val.mac__hdr().e() == true) {</span><br><span style="color: hsl(120, 100%, 40%);">+         LlcBlock lb;</span><br><span style="color: hsl(120, 100%, 40%);">+          unsigned int length = ttcn_buffer.get_read_len();</span><br><span style="color: hsl(120, 100%, 40%);">+             /* LI not present: The Upper Layer PDU that starts with the current RLC data block either</span><br><span style="color: hsl(120, 100%, 40%);">+              * fills the current RLC data block precisely or continues in the following in-sequence RLC</span><br><span style="color: hsl(120, 100%, 40%);">+            * data block */</span><br><span style="color: hsl(120, 100%, 40%);">+              lb.payload() = OCTETSTRING(length, ttcn_buffer.get_read_data());</span><br><span style="color: hsl(120, 100%, 40%);">+              ttcn_buffer.increase_pos(length);</span><br><span style="color: hsl(120, 100%, 40%);">+             ret_val.blocks()[0] = lb;</span><br><span style="color: hsl(120, 100%, 40%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              if (ret_val.blocks().is_bound()) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    for (int i = 0; i < ret_val.blocks().size_of(); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                             unsigned int length = ret_val.blocks()[i].hdr()().length__ind();</span><br><span style="color: hsl(120, 100%, 40%);">+                              if (length > ttcn_buffer.get_read_len())</span><br><span style="color: hsl(120, 100%, 40%);">+                                   length = ttcn_buffer.get_read_len();</span><br><span style="color: hsl(120, 100%, 40%);">+                          ret_val.blocks()[i].payload() = OCTETSTRING(length, ttcn_buffer.get_read_data());</span><br><span style="color: hsl(120, 100%, 40%);">+                             ttcn_buffer.increase_pos(length);</span><br><span style="color: hsl(120, 100%, 40%);">+                     }</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);</span><br><span style="color: hsl(120, 100%, 40%);">+  TTCN_Logger::log_event_str("dec_RlcmacUlDataBlock(): Stream before return: ");</span><br><span style="color: hsl(120, 100%, 40%);">+      ttcn_buffer.log();</span><br><span style="color: hsl(120, 100%, 40%);">+    TTCN_Logger::end_event();</span><br><span style="color: hsl(120, 100%, 40%);">+     TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);</span><br><span style="color: hsl(120, 100%, 40%);">+  TTCN_Logger::log_event_str("dec_RlcmacUlDataBlock(): ret_val before return: ");</span><br><span style="color: hsl(120, 100%, 40%);">+     ret_val.log();</span><br><span style="color: hsl(120, 100%, 40%);">+        TTCN_Logger::end_event();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return ret_val;</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%);">+static</span><br><span style="color: hsl(120, 100%, 40%);">+EgprsUlMacDataHeader dec__EgprsUlMacDataHeader_type1(const OCTETSTRING& stream)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  EgprsUlMacDataHeader ret_val;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       fprintf(stderr, "FIXME: Not implemented! %s (%s:%u)\n", __func__, __FILE__, __LINE__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return ret_val;</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%);">+static</span><br><span style="color: hsl(120, 100%, 40%);">+EgprsUlMacDataHeader dec__EgprsUlMacDataHeader_type2(const OCTETSTRING& stream)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  EgprsUlMacDataHeader ret_val;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       fprintf(stderr, "FIXME: Not implemented! %s (%s:%u)\n", __func__, __FILE__, __LINE__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return ret_val;</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%);">+static</span><br><span style="color: hsl(120, 100%, 40%);">+EgprsUlMacDataHeader dec__EgprsUlMacDataHeader_type3(const OCTETSTRING& stream)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  EgprsUlMacDataHeader ret_val;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       fprintf(stderr, "FIXME: Not implemented! %s (%s:%u)\n", __func__, __FILE__, __LINE__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return ret_val;</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%);">+RlcmacUlEgprsDataBlock dec__RlcmacUlEgprsDataBlock(const OCTETSTRING& stream, CodingScheme::enum_type mcs)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       RlcmacUlEgprsDataBlock ret_val;</span><br><span style="color: hsl(120, 100%, 40%);">+       TTCN_Buffer ttcn_buffer(stream);</span><br><span style="color: hsl(120, 100%, 40%);">+      TTCN_Buffer aligned_buffer;</span><br><span style="color: hsl(120, 100%, 40%);">+   int num_llc_blocks = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+       unsigned int data_block_bits, data_block_offsets[2];</span><br><span style="color: hsl(120, 100%, 40%);">+  unsigned int num_calls;</span><br><span style="color: hsl(120, 100%, 40%);">+       const uint8_t *ti_e;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        switch (mcs) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case CodingScheme::MCS__1:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__2:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__3:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__4:</span><br><span style="color: hsl(120, 100%, 40%);">+            ret_val.mac__hdr() = dec__EgprsUlMacDataHeader_type3(stream);</span><br><span style="color: hsl(120, 100%, 40%);">+         break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case CodingScheme::MCS__5:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__6:</span><br><span style="color: hsl(120, 100%, 40%);">+            ret_val.mac__hdr() = dec__EgprsUlMacDataHeader_type2(stream);</span><br><span style="color: hsl(120, 100%, 40%);">+         break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case CodingScheme::MCS__7:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__8:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__9:</span><br><span style="color: hsl(120, 100%, 40%);">+            ret_val.mac__hdr() = dec__EgprsUlMacDataHeader_type1(stream);</span><br><span style="color: hsl(120, 100%, 40%);">+         break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     setup_rlc_mac_priv(mcs, ret_val.mac__hdr().header__type(), true,</span><br><span style="color: hsl(120, 100%, 40%);">+                         &num_calls, &data_block_bits, data_block_offsets);</span><br><span style="color: hsl(120, 100%, 40%);">+ get_egprs_data_block(ttcn_buffer, data_block_offsets[0], data_block_bits, aligned_buffer);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  ti_e = aligned_buffer.get_read_data();</span><br><span style="color: hsl(120, 100%, 40%);">+        ret_val.tlli__ind() = *ti_e & 0x02 ? true : false;</span><br><span style="color: hsl(120, 100%, 40%);">+        ret_val.e() = *ti_e & 0x01 ? true : false;</span><br><span style="color: hsl(120, 100%, 40%);">+        aligned_buffer.increase_pos(1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Manually decoder remainder of aligned_buffer, containing optional header octets,</span><br><span style="color: hsl(120, 100%, 40%);">+    * optional tlli, optional pfi and LLC Blocks */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* optional extension octets, containing LI+M+E of Llc blocks */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (ret_val.e() == false) {</span><br><span style="color: hsl(120, 100%, 40%);">+           /* extension octet follows, i.e. optional Llc length octets */</span><br><span style="color: hsl(120, 100%, 40%);">+                while (1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   /* decode one more extension octet with LlcBlocHdr inside */</span><br><span style="color: hsl(120, 100%, 40%);">+                  EgprsLlcBlock lb;</span><br><span style="color: hsl(120, 100%, 40%);">+                     lb.hdr()().decode(EgprsLlcBlockHdr_descr_, aligned_buffer, TTCN_EncDec::CT_RAW);</span><br><span style="color: hsl(120, 100%, 40%);">+                      ret_val.blocks()[num_llc_blocks++] = lb;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                    /* if E == '1'B, we can proceed further */</span><br><span style="color: hsl(120, 100%, 40%);">+                    if (lb.hdr()().e() == true)</span><br><span style="color: hsl(120, 100%, 40%);">+                           break;</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%);">+   /* parse optional TLLI */</span><br><span style="color: hsl(120, 100%, 40%);">+     if (ret_val.tlli__ind()) {</span><br><span style="color: hsl(120, 100%, 40%);">+            ret_val.tlli() = OCTETSTRING(4, aligned_buffer.get_read_data());</span><br><span style="color: hsl(120, 100%, 40%);">+              aligned_buffer.increase_pos(4);</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     /* parse optional PFI */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (ret_val.mac__hdr().pfi__ind()) {</span><br><span style="color: hsl(120, 100%, 40%);">+          ret_val.pfi().decode(RlcmacUlDataBlock_pfi_descr_, aligned_buffer, TTCN_EncDec::CT_RAW);</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%);">+   /* RLC blocks at end */</span><br><span style="color: hsl(120, 100%, 40%);">+       if (ret_val.e() == true) {</span><br><span style="color: hsl(120, 100%, 40%);">+            EgprsLlcBlock lb;</span><br><span style="color: hsl(120, 100%, 40%);">+             unsigned int length = aligned_buffer.get_read_len();</span><br><span style="color: hsl(120, 100%, 40%);">+          /* LI not present: The Upper Layer PDU that starts with the current RLC data block either</span><br><span style="color: hsl(120, 100%, 40%);">+              * fills the current RLC data block precisely or continues in the following in-sequence RLC</span><br><span style="color: hsl(120, 100%, 40%);">+            * data block */</span><br><span style="color: hsl(120, 100%, 40%);">+              lb.payload() = OCTETSTRING(length, aligned_buffer.get_read_data());</span><br><span style="color: hsl(120, 100%, 40%);">+           aligned_buffer.increase_pos(length);</span><br><span style="color: hsl(120, 100%, 40%);">+          ret_val.blocks()[0] = lb;</span><br><span style="color: hsl(120, 100%, 40%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              if (ret_val.blocks().is_bound()) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    for (int i = 0; i < ret_val.blocks().size_of(); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                             unsigned int length = ret_val.blocks()[i].hdr()().length__ind();</span><br><span style="color: hsl(120, 100%, 40%);">+                              if (length > aligned_buffer.get_read_len())</span><br><span style="color: hsl(120, 100%, 40%);">+                                        length = aligned_buffer.get_read_len();</span><br><span style="color: hsl(120, 100%, 40%);">+                               ret_val.blocks()[i].payload() = OCTETSTRING(length, aligned_buffer.get_read_data());</span><br><span style="color: hsl(120, 100%, 40%);">+                          aligned_buffer.increase_pos(length);</span><br><span style="color: hsl(120, 100%, 40%);">+                  }</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return ret_val;</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%);">+RlcmacUlBlock dec__RlcmacUlBlock(const OCTETSTRING& stream)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      RlcmacUlBlock ret_val;</span><br><span style="color: hsl(120, 100%, 40%);">+        size_t stream_len = stream.lengthof();</span><br><span style="color: hsl(120, 100%, 40%);">+        CodingScheme::enum_type mcs = payload_len_2_coding_scheme(stream_len);</span><br><span style="color: hsl(120, 100%, 40%);">+        unsigned char pt;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   switch (mcs) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case CodingScheme::CS__1:</span><br><span style="color: hsl(120, 100%, 40%);">+     case CodingScheme::CS__2:</span><br><span style="color: hsl(120, 100%, 40%);">+     case CodingScheme::CS__3:</span><br><span style="color: hsl(120, 100%, 40%);">+     case CodingScheme::CS__4:</span><br><span style="color: hsl(120, 100%, 40%);">+             pt = stream[0].get_octet() >> 6;</span><br><span style="color: hsl(120, 100%, 40%);">+                if (pt == MacPayloadType::MAC__PT__RLC__DATA)</span><br><span style="color: hsl(120, 100%, 40%);">+                 ret_val.data() = dec__RlcmacUlDataBlock(stream);</span><br><span style="color: hsl(120, 100%, 40%);">+              else</span><br><span style="color: hsl(120, 100%, 40%);">+                  ret_val.ctrl() = dec__RlcmacUlCtrlBlock(stream);</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case CodingScheme::MCS__1:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__2:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__3:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__4:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__5:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__6:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__7:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__8:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CodingScheme::MCS__9:</span><br><span style="color: hsl(120, 100%, 40%);">+            ret_val.data__egprs() = dec__RlcmacUlEgprsDataBlock(stream, mcs);</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</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 ret_val;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/////////////////////</span><br><span style="color: hsl(120, 100%, 40%);">+// ENCODE</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%);">+/* ENCODE DOWNLINK */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+OCTETSTRING enc__RlcmacDlDataBlock(const RlcmacDlDataBlock& si)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    RlcmacDlDataBlock in = si;</span><br><span style="color: hsl(120, 100%, 40%);">+    OCTETSTRING ret_val;</span><br><span style="color: hsl(120, 100%, 40%);">+  TTCN_Buffer ttcn_buffer;</span><br><span style="color: hsl(120, 100%, 40%);">+      int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Fix 'e' bit of initial header based on following blocks */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!in.blocks().is_bound() ||</span><br><span style="color: hsl(120, 100%, 40%);">+            (in.blocks().size_of() == 1 && !in.blocks()[0].hdr().is_bound()))</span><br><span style="color: hsl(120, 100%, 40%);">+         in.mac__hdr().hdr__ext().e() = true;</span><br><span style="color: hsl(120, 100%, 40%);">+  else</span><br><span style="color: hsl(120, 100%, 40%);">+          in.mac__hdr().hdr__ext().e() = false;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* use automatic/generated decoder for header */</span><br><span style="color: hsl(120, 100%, 40%);">+      in.mac__hdr().encode(DlMacDataHeader_descr_, ttcn_buffer, TTCN_EncDec::CT_RAW);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Add LI octets, if any */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (in.blocks().is_bound() &&</span><br><span style="color: hsl(120, 100%, 40%);">+     (in.blocks().size_of() != 1 || in.blocks()[0].hdr().is_bound())) {</span><br><span style="color: hsl(120, 100%, 40%);">+                /* first write LI octets */</span><br><span style="color: hsl(120, 100%, 40%);">+           for (i = 0; i < in.blocks().size_of(); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      /* fix the 'E' bit in case it is not clear */</span><br><span style="color: hsl(120, 100%, 40%);">+                 if (i < in.blocks().size_of()-1)</span><br><span style="color: hsl(120, 100%, 40%);">+                           in.blocks()[i].hdr()().e() = false;</span><br><span style="color: hsl(120, 100%, 40%);">+                   else</span><br><span style="color: hsl(120, 100%, 40%);">+                          in.blocks()[i].hdr()().e() = true;</span><br><span style="color: hsl(120, 100%, 40%);">+                    in.blocks()[i].hdr()().encode(LlcBlockHdr_descr_, ttcn_buffer, TTCN_EncDec::CT_RAW);</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 (in.blocks().is_bound()) {</span><br><span style="color: hsl(120, 100%, 40%);">+         for (i = 0; i < in.blocks().size_of(); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      if (!in.blocks()[i].is_bound())</span><br><span style="color: hsl(120, 100%, 40%);">+                               continue;</span><br><span style="color: hsl(120, 100%, 40%);">+                     ttcn_buffer.put_string(in.blocks()[i].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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ttcn_buffer.get_string(ret_val);</span><br><span style="color: hsl(120, 100%, 40%);">+      return ret_val;</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%);">+static</span><br><span style="color: hsl(120, 100%, 40%);">+void enc__RlcmacDlEgprsDataHeader_type1(const EgprsDlMacDataHeader& si, TTCN_Buffer& ttcn_buffer)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    fprintf(stderr, "FIXME: Not implemented! %s (%s:%u)\n", __func__, __FILE__, __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%);">+static</span><br><span style="color: hsl(120, 100%, 40%);">+void enc__RlcmacDlEgprsDataHeader_type2(const EgprsDlMacDataHeader& si, TTCN_Buffer& ttcn_buffer)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   fprintf(stderr, "FIXME: Not implemented! %s (%s:%u)\n", __func__, __FILE__, __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%);">+static</span><br><span style="color: hsl(120, 100%, 40%);">+void enc__RlcmacDlEgprsDataHeader_type3(const EgprsDlMacDataHeader& si, TTCN_Buffer& ttcn_buffer)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   fprintf(stderr, "FIXME: Not implemented! %s (%s:%u)\n", __func__, __FILE__, __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%);">+OCTETSTRING enc__RlcmacDlEgprsDataBlock(const RlcmacDlEgprsDataBlock& si)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       RlcmacDlEgprsDataBlock in = si;</span><br><span style="color: hsl(120, 100%, 40%);">+       OCTETSTRING ret_val;</span><br><span style="color: hsl(120, 100%, 40%);">+  TTCN_Buffer ttcn_buffer;</span><br><span style="color: hsl(120, 100%, 40%);">+      int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Fix 'e' bit of initial header based on following blocks */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!in.blocks().is_bound() ||</span><br><span style="color: hsl(120, 100%, 40%);">+            (in.blocks().size_of() == 1 && !in.blocks()[0].hdr().is_bound()))</span><br><span style="color: hsl(120, 100%, 40%);">+         in.e() = true;</span><br><span style="color: hsl(120, 100%, 40%);">+        else</span><br><span style="color: hsl(120, 100%, 40%);">+          in.e() = false;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     switch (in.mac__hdr().header__type()) {</span><br><span style="color: hsl(120, 100%, 40%);">+       case EgprsHeaderType::RLCMAC__HDR__TYPE__1:</span><br><span style="color: hsl(120, 100%, 40%);">+           enc__RlcmacDlEgprsDataHeader_type1(si.mac__hdr(), ttcn_buffer);</span><br><span style="color: hsl(120, 100%, 40%);">+               break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case EgprsHeaderType::RLCMAC__HDR__TYPE__2:</span><br><span style="color: hsl(120, 100%, 40%);">+           enc__RlcmacDlEgprsDataHeader_type2(si.mac__hdr(), ttcn_buffer);</span><br><span style="color: hsl(120, 100%, 40%);">+               break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case EgprsHeaderType::RLCMAC__HDR__TYPE__3:</span><br><span style="color: hsl(120, 100%, 40%);">+           enc__RlcmacDlEgprsDataHeader_type3(si.mac__hdr(), ttcn_buffer);</span><br><span style="color: hsl(120, 100%, 40%);">+       default:</span><br><span style="color: hsl(120, 100%, 40%);">+              break; /* TODO: error */</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%);">+   /* Add LI octets, if any */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (in.blocks().is_bound() &&</span><br><span style="color: hsl(120, 100%, 40%);">+     (in.blocks().size_of() != 1 || in.blocks()[0].hdr().is_bound())) {</span><br><span style="color: hsl(120, 100%, 40%);">+                /* first write LI octets */</span><br><span style="color: hsl(120, 100%, 40%);">+           for (i = 0; i < in.blocks().size_of(); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      /* fix the 'E' bit in case it is not clear */</span><br><span style="color: hsl(120, 100%, 40%);">+                 if (i < in.blocks().size_of()-1)</span><br><span style="color: hsl(120, 100%, 40%);">+                           in.blocks()[i].hdr()().e() = false;</span><br><span style="color: hsl(120, 100%, 40%);">+                   else</span><br><span style="color: hsl(120, 100%, 40%);">+                          in.blocks()[i].hdr()().e() = true;</span><br><span style="color: hsl(120, 100%, 40%);">+                    in.blocks()[i].hdr()().encode(EgprsLlcBlockHdr_descr_, ttcn_buffer, TTCN_EncDec::CT_RAW);</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 (in.blocks().is_bound()) {</span><br><span style="color: hsl(120, 100%, 40%);">+         for (i = 0; i < in.blocks().size_of(); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      if (!in.blocks()[i].is_bound())</span><br><span style="color: hsl(120, 100%, 40%);">+                               continue;</span><br><span style="color: hsl(120, 100%, 40%);">+                     ttcn_buffer.put_string(in.blocks()[i].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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ttcn_buffer.get_string(ret_val);</span><br><span style="color: hsl(120, 100%, 40%);">+      return ret_val;</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%);">+OCTETSTRING enc__RlcmacDlBlock(const RlcmacDlBlock& si)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  if (si.ischosen(RlcmacDlBlock::ALT_data__egprs))</span><br><span style="color: hsl(120, 100%, 40%);">+              return enc__RlcmacDlEgprsDataBlock(si.data__egprs());</span><br><span style="color: hsl(120, 100%, 40%);">+ else if (si.ischosen(RlcmacDlBlock::ALT_data))</span><br><span style="color: hsl(120, 100%, 40%);">+                return enc__RlcmacDlDataBlock(si.data());</span><br><span style="color: hsl(120, 100%, 40%);">+     else</span><br><span style="color: hsl(120, 100%, 40%);">+          return enc__RlcmacDlCtrlBlock(si.ctrl());</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%);">+/* ENCODE UPLINK */</span><br><span> </span><br><span> OCTETSTRING enc__RlcmacUlDataBlock(const RlcmacUlDataBlock& si)</span><br><span> {</span><br><span>@@ -187,143 +1011,140 @@</span><br><span>       return ret_val;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-RlcmacUlDataBlock dec__RlcmacUlDataBlock(const OCTETSTRING& stream)</span><br><span style="color: hsl(120, 100%, 40%);">+static</span><br><span style="color: hsl(120, 100%, 40%);">+void enc__RlcmacUlEgprsDataHeader_type1(const EgprsUlMacDataHeader& si, TTCN_Buffer& ttcn_buffer)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- RlcmacUlDataBlock ret_val;</span><br><span style="color: hsl(0, 100%, 40%);">-      TTCN_Buffer ttcn_buffer(stream);</span><br><span style="color: hsl(0, 100%, 40%);">-        int num_llc_blocks = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+       fprintf(stderr, "FIXME: Not implemented! %s (%s:%u)\n", __func__, __FILE__, __LINE__);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);</span><br><span style="color: hsl(0, 100%, 40%);">-    TTCN_Logger::log_event_str("==================================\n"</span><br><span style="color: hsl(0, 100%, 40%);">-                             "dec_RlcmacUlDataBlock(): Stream before decoding: ");</span><br><span style="color: hsl(0, 100%, 40%);">- stream.log();</span><br><span style="color: hsl(0, 100%, 40%);">-   TTCN_Logger::end_event();</span><br><span style="color: hsl(120, 100%, 40%);">+static</span><br><span style="color: hsl(120, 100%, 40%);">+void enc__RlcmacUlEgprsDataHeader_type2(const EgprsUlMacDataHeader& si, TTCN_Buffer& ttcn_buffer)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       fprintf(stderr, "FIXME: Not implemented! %s (%s:%u)\n", __func__, __FILE__, __LINE__);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- /* use automatic/generated decoder for header */</span><br><span style="color: hsl(0, 100%, 40%);">-        ret_val.mac__hdr().decode(UlMacDataHeader_descr_, ttcn_buffer, TTCN_EncDec::CT_RAW);</span><br><span style="color: hsl(120, 100%, 40%);">+static</span><br><span style="color: hsl(120, 100%, 40%);">+void enc__RlcmacUlEgprsDataHeader_type3(const EgprsUlMacDataHeader& si, TTCN_Buffer& ttcn_buffer)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gprs_rlc_ul_header_egprs_3 egprs3;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);</span><br><span style="color: hsl(0, 100%, 40%);">-    TTCN_Logger::log_event_str("dec_RlcmacUlDataBlock(): Stream after decoding hdr: ");</span><br><span style="color: hsl(0, 100%, 40%);">-   ttcn_buffer.log();</span><br><span style="color: hsl(0, 100%, 40%);">-      TTCN_Logger::end_event();</span><br><span style="color: hsl(0, 100%, 40%);">-       TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);</span><br><span style="color: hsl(0, 100%, 40%);">-    TTCN_Logger::log_event_str("dec_RlcmacUlDataBlock(): ret_val after decoding hdr: ");</span><br><span style="color: hsl(0, 100%, 40%);">-  ret_val.log();</span><br><span style="color: hsl(0, 100%, 40%);">-  TTCN_Logger::end_event();</span><br><span style="color: hsl(120, 100%, 40%);">+     egprs3.r = bs2uint8(si.r__ri());</span><br><span style="color: hsl(120, 100%, 40%);">+      egprs3.si = bs2uint8(si.foi__si());</span><br><span style="color: hsl(120, 100%, 40%);">+   egprs3.cv = si.countdown();</span><br><span style="color: hsl(120, 100%, 40%);">+   egprs3.tfi_hi = si.tfi() >> 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  egprs3.tfi_lo = si.tfi() >> 1;</span><br><span style="color: hsl(120, 100%, 40%);">+  egprs3.bsn1_hi = si.bsn1() >> 0;</span><br><span style="color: hsl(120, 100%, 40%);">+        egprs3.bsn1_lo = si.bsn1() >> 5;</span><br><span style="color: hsl(120, 100%, 40%);">+        egprs3.cps_hi = si.cps() >> 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  egprs3.cps_lo = si.cps() >> 2;</span><br><span style="color: hsl(120, 100%, 40%);">+  egprs3.spb = bs2uint8(si.spb());</span><br><span style="color: hsl(120, 100%, 40%);">+      egprs3.rsb = bs2uint8(si.spb());</span><br><span style="color: hsl(120, 100%, 40%);">+      egprs3.pi = si.pfi__ind();</span><br><span style="color: hsl(120, 100%, 40%);">+    egprs3.spare = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     egprs3.dummy = 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   /* Manually decoder remainder of ttcn_buffer, containing optional header octets, </span><br><span style="color: hsl(0, 100%, 40%);">-        * optional tlli, optional pfi and LLC Blocks */</span><br><span style="color: hsl(120, 100%, 40%);">+      ttcn_buffer.put_s(sizeof(egprs3), (const unsigned char *)&egprs3);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   /* optional extension octets, containing LI+M+E of Llc blocks */</span><br><span style="color: hsl(0, 100%, 40%);">-        if (ret_val.mac__hdr().e() == false) {</span><br><span style="color: hsl(0, 100%, 40%);">-          /* extension octet follows, i.e. optional Llc length octets */</span><br><span style="color: hsl(0, 100%, 40%);">-          while (1) {</span><br><span style="color: hsl(0, 100%, 40%);">-                     /* decode one more extension octet with LlcBlocHdr inside */</span><br><span style="color: hsl(0, 100%, 40%);">-                    LlcBlock lb;</span><br><span style="color: hsl(0, 100%, 40%);">-                    lb.hdr()().decode(LlcBlockHdr_descr_, ttcn_buffer, TTCN_EncDec::CT_RAW);</span><br><span style="color: hsl(0, 100%, 40%);">-                        ret_val.blocks()[num_llc_blocks++] = lb;</span><br><span style="color: hsl(120, 100%, 40%);">+OCTETSTRING enc__RlcmacUlEgprsDataBlock(const RlcmacUlEgprsDataBlock& si)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    RlcmacUlEgprsDataBlock in = si;</span><br><span style="color: hsl(120, 100%, 40%);">+       OCTETSTRING ret_val;</span><br><span style="color: hsl(120, 100%, 40%);">+  TTCN_Buffer ttcn_buffer;</span><br><span style="color: hsl(120, 100%, 40%);">+      int i;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                      TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);</span><br><span style="color: hsl(0, 100%, 40%);">-                    TTCN_Logger::log_event_str("dec_RlcmacUlDataBlock(): Stream after decoding ExtOct: ");</span><br><span style="color: hsl(0, 100%, 40%);">-                        ttcn_buffer.log();</span><br><span style="color: hsl(0, 100%, 40%);">-                      TTCN_Logger::end_event();</span><br><span style="color: hsl(0, 100%, 40%);">-                       TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);</span><br><span style="color: hsl(0, 100%, 40%);">-                    TTCN_Logger::log_event_str("dec_RlcmacUlDataBlock(): ret_val after decoding ExtOct: ");</span><br><span style="color: hsl(0, 100%, 40%);">-                       ret_val.log();</span><br><span style="color: hsl(0, 100%, 40%);">-                  TTCN_Logger::end_event();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                       /* if E == '1'B, we can proceed further */</span><br><span style="color: hsl(0, 100%, 40%);">-                      if (lb.hdr()().e() == true)</span><br><span style="color: hsl(0, 100%, 40%);">-                             break;</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%);">-       /* parse optional TLLI */</span><br><span style="color: hsl(0, 100%, 40%);">-       if (ret_val.mac__hdr().tlli__ind()) {</span><br><span style="color: hsl(0, 100%, 40%);">-           ret_val.tlli() = OCTETSTRING(4, ttcn_buffer.get_read_data());</span><br><span style="color: hsl(0, 100%, 40%);">-           ttcn_buffer.increase_pos(4);</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-       /* parse optional PFI */</span><br><span style="color: hsl(0, 100%, 40%);">-        if (ret_val.mac__hdr().pfi__ind()) {</span><br><span style="color: hsl(0, 100%, 40%);">-            ret_val.pfi().decode(RlcmacUlDataBlock_pfi_descr_, ttcn_buffer, TTCN_EncDec::CT_RAW);</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%);">-       /* RLC blocks at end */</span><br><span style="color: hsl(0, 100%, 40%);">- if (ret_val.mac__hdr().e() == true) {</span><br><span style="color: hsl(0, 100%, 40%);">-           LlcBlock lb;</span><br><span style="color: hsl(0, 100%, 40%);">-            unsigned int length = ttcn_buffer.get_read_len();</span><br><span style="color: hsl(0, 100%, 40%);">-               /* LI not present: The Upper Layer PDU that starts with the current RLC data block either</span><br><span style="color: hsl(0, 100%, 40%);">-                * fills the current RLC data block precisely or continues in the following in-sequence RLC</span><br><span style="color: hsl(0, 100%, 40%);">-              * data block */</span><br><span style="color: hsl(0, 100%, 40%);">-                lb.payload() = OCTETSTRING(length, ttcn_buffer.get_read_data());</span><br><span style="color: hsl(0, 100%, 40%);">-                ttcn_buffer.increase_pos(length);</span><br><span style="color: hsl(0, 100%, 40%);">-               ret_val.blocks()[0] = lb;</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!in.blocks().is_bound()) {</span><br><span style="color: hsl(120, 100%, 40%);">+                /* we don't have nay blocks: Add length value (zero) */</span><br><span style="color: hsl(120, 100%, 40%);">+           in.e() = false; /* E=0: extension octet follows */</span><br><span style="color: hsl(120, 100%, 40%);">+    } else if (in.blocks().size_of() == 1 && in.blocks()[0].hdr() == OMIT_VALUE) {</span><br><span style="color: hsl(120, 100%, 40%);">+                /* If there's only a single block, and that block has no HDR value defined, */</span><br><span style="color: hsl(120, 100%, 40%);">+            in.e() = true; /* E=0: extension octet follows */</span><br><span>    } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                if (ret_val.blocks().is_bound()) {</span><br><span style="color: hsl(0, 100%, 40%);">-                      for (int i = 0; i < ret_val.blocks().size_of(); i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-                               unsigned int length = ret_val.blocks()[i].hdr()().length__ind();</span><br><span style="color: hsl(0, 100%, 40%);">-                                if (length > ttcn_buffer.get_read_len())</span><br><span style="color: hsl(0, 100%, 40%);">-                                     length = ttcn_buffer.get_read_len();</span><br><span style="color: hsl(0, 100%, 40%);">-                            ret_val.blocks()[i].payload() = OCTETSTRING(length, ttcn_buffer.get_read_data());</span><br><span style="color: hsl(0, 100%, 40%);">-                               ttcn_buffer.increase_pos(length);</span><br><span style="color: hsl(120, 100%, 40%);">+             /* Length value */</span><br><span style="color: hsl(120, 100%, 40%);">+            in.e() = 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%);">+   /* Fix other presence indications */</span><br><span style="color: hsl(120, 100%, 40%);">+  in.tlli__ind() = in.tlli().is_bound() && in.tlli() != OMIT_VALUE;</span><br><span style="color: hsl(120, 100%, 40%);">+     in.mac__hdr().pfi__ind() = in.pfi().is_bound() && in.pfi() != OMIT_VALUE;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   switch (in.mac__hdr().header__type()) {</span><br><span style="color: hsl(120, 100%, 40%);">+       case EgprsHeaderType::RLCMAC__HDR__TYPE__1:</span><br><span style="color: hsl(120, 100%, 40%);">+           enc__RlcmacUlEgprsDataHeader_type1(si.mac__hdr(), ttcn_buffer);</span><br><span style="color: hsl(120, 100%, 40%);">+               break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case EgprsHeaderType::RLCMAC__HDR__TYPE__2:</span><br><span style="color: hsl(120, 100%, 40%);">+           enc__RlcmacUlEgprsDataHeader_type2(si.mac__hdr(), ttcn_buffer);</span><br><span style="color: hsl(120, 100%, 40%);">+               break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case EgprsHeaderType::RLCMAC__HDR__TYPE__3:</span><br><span style="color: hsl(120, 100%, 40%);">+           enc__RlcmacUlEgprsDataHeader_type3(si.mac__hdr(), ttcn_buffer);</span><br><span style="color: hsl(120, 100%, 40%);">+       default:</span><br><span style="color: hsl(120, 100%, 40%);">+              break; /* TODO: error */</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 (in.e() == false) {</span><br><span style="color: hsl(120, 100%, 40%);">+                /* Add LI octets, if any */</span><br><span style="color: hsl(120, 100%, 40%);">+           if (!in.blocks().is_bound()) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        ttcn_buffer.put_c(0x01); /* M=0, E=1 LEN=0 */</span><br><span style="color: hsl(120, 100%, 40%);">+         } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      for (i = 0; i < in.blocks().size_of(); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+#if 0</span><br><span style="color: hsl(120, 100%, 40%);">+                               /* check for penultimate block */</span><br><span style="color: hsl(120, 100%, 40%);">+                             if (i == in.blocks().size_of()-2) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                   /* if last block has no header, no more LI */</span><br><span style="color: hsl(120, 100%, 40%);">+                                 if (in.blocks()[i+1].hdr() == OMIT_VALUE) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                           in.blocks()[i].hdr()().more() = true;</span><br><span style="color: hsl(120, 100%, 40%);">+                                 } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                                              /* header present, we have to encode LI */</span><br><span style="color: hsl(120, 100%, 40%);">+                                            in.blocks()[i].hdr()().more() = false;</span><br><span style="color: hsl(120, 100%, 40%);">+                                                in.blocks()[i].hdr()().length__ind() =</span><br><span style="color: hsl(120, 100%, 40%);">+                                                                in.blocks()[i+1].payload().lengthof();</span><br><span style="color: hsl(120, 100%, 40%);">+                                        }</span><br><span style="color: hsl(120, 100%, 40%);">+                             } else if (i < in.blocks().size_of()-2) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                  /* one of the first blocks, before the penultimate or last */</span><br><span style="color: hsl(120, 100%, 40%);">+                                 in.blocks()[i].hdr()().e() = false; /* LI present */</span><br><span style="color: hsl(120, 100%, 40%);">+                                  /* re-compute length */</span><br><span style="color: hsl(120, 100%, 40%);">+                                       in.blocks()[i].hdr()().length__ind() =</span><br><span style="color: hsl(120, 100%, 40%);">+                                                                in.blocks()[i+1].payload().lengthof();</span><br><span style="color: hsl(120, 100%, 40%);">+                                }</span><br><span style="color: hsl(120, 100%, 40%);">+                             /* Encode LI octet if E=0 */</span><br><span style="color: hsl(120, 100%, 40%);">+                          }</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+                             if (in.blocks()[i].hdr() != OMIT_VALUE) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                     in.blocks()[i].hdr()().encode(EgprsLlcBlockHdr_descr_, ttcn_buffer,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                                   TTCN_EncDec::CT_RAW);</span><br><span style="color: hsl(120, 100%, 40%);">+                         }</span><br><span>                    }</span><br><span>            }</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);</span><br><span style="color: hsl(0, 100%, 40%);">-    TTCN_Logger::log_event_str("dec_RlcmacUlDataBlock(): Stream before return: ");</span><br><span style="color: hsl(0, 100%, 40%);">-        ttcn_buffer.log();</span><br><span style="color: hsl(0, 100%, 40%);">-      TTCN_Logger::end_event();</span><br><span style="color: hsl(0, 100%, 40%);">-       TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);</span><br><span style="color: hsl(0, 100%, 40%);">-    TTCN_Logger::log_event_str("dec_RlcmacUlDataBlock(): ret_val before return: ");</span><br><span style="color: hsl(0, 100%, 40%);">-       ret_val.log();</span><br><span style="color: hsl(0, 100%, 40%);">-  TTCN_Logger::end_event();</span><br><span style="color: hsl(120, 100%, 40%);">+     if (in.tlli__ind()) {</span><br><span style="color: hsl(120, 100%, 40%);">+         ttcn_buffer.put_string(in.tlli());</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ if (in.mac__hdr().pfi__ind()) {</span><br><span style="color: hsl(120, 100%, 40%);">+               in.pfi().encode(RlcmacUlDataBlock_pfi_descr_, ttcn_buffer, TTCN_EncDec::CT_RAW);</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 (in.blocks().is_bound()) {</span><br><span style="color: hsl(120, 100%, 40%);">+         for (i = 0; i < in.blocks().size_of(); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      if (!in.blocks()[i].is_bound())</span><br><span style="color: hsl(120, 100%, 40%);">+                               continue;</span><br><span style="color: hsl(120, 100%, 40%);">+                     ttcn_buffer.put_string(in.blocks()[i].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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ttcn_buffer.get_string(ret_val);</span><br><span>     return ret_val;</span><br><span> }</span><br><span> </span><br><span> OCTETSTRING enc__RlcmacUlBlock(const RlcmacUlBlock& si)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-    if (si.ischosen(RlcmacUlBlock::ALT_data))</span><br><span style="color: hsl(120, 100%, 40%);">+     if (si.ischosen(RlcmacUlBlock::ALT_data__egprs))</span><br><span style="color: hsl(120, 100%, 40%);">+              return enc__RlcmacUlEgprsDataBlock(si.data__egprs());</span><br><span style="color: hsl(120, 100%, 40%);">+ else if (si.ischosen(RlcmacUlBlock::ALT_data))</span><br><span>               return enc__RlcmacUlDataBlock(si.data());</span><br><span>    else</span><br><span>                 return enc__RlcmacUlCtrlBlock(si.ctrl());</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-OCTETSTRING enc__RlcmacDlBlock(const RlcmacDlBlock& si)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  if (si.ischosen(RlcmacDlBlock::ALT_data))</span><br><span style="color: hsl(0, 100%, 40%);">-               return enc__RlcmacDlDataBlock(si.data());</span><br><span style="color: hsl(0, 100%, 40%);">-       else</span><br><span style="color: hsl(0, 100%, 40%);">-            return enc__RlcmacDlCtrlBlock(si.ctrl());</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%);">-RlcmacUlBlock dec__RlcmacUlBlock(const OCTETSTRING& stream)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      RlcmacUlBlock ret_val;</span><br><span style="color: hsl(0, 100%, 40%);">-  unsigned char pt = stream[0].get_octet() >> 6;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    if (pt == MacPayloadType::MAC__PT__RLC__DATA)</span><br><span style="color: hsl(0, 100%, 40%);">-           ret_val.data() = dec__RlcmacUlDataBlock(stream);</span><br><span style="color: hsl(0, 100%, 40%);">-        else</span><br><span style="color: hsl(0, 100%, 40%);">-            ret_val.ctrl() = dec__RlcmacUlCtrlBlock(stream);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        return ret_val;</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%);">-RlcmacDlBlock dec__RlcmacDlBlock(const OCTETSTRING& stream)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        RlcmacDlBlock ret_val;</span><br><span style="color: hsl(0, 100%, 40%);">-  unsigned char pt = stream[0].get_octet() >> 6;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    if (pt == MacPayloadType::MAC__PT__RLC__DATA)</span><br><span style="color: hsl(0, 100%, 40%);">-           ret_val.data() = dec__RlcmacDlDataBlock(stream);</span><br><span style="color: hsl(0, 100%, 40%);">-        else</span><br><span style="color: hsl(0, 100%, 40%);">-            ret_val.ctrl() = dec__RlcmacDlCtrlBlock(stream);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        return ret_val;</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> } // namespace</span><br><span>diff --git a/library/RLCMAC_Types.ttcn b/library/RLCMAC_Types.ttcn</span><br><span>index 97b89da..e5c2464 100644</span><br><span>--- a/library/RLCMAC_Types.ttcn</span><br><span>+++ b/library/RLCMAC_Types.ttcn</span><br><span>@@ -41,11 +41,18 @@</span><br><span>            return 0;</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ type enumerated EgprsHeaderType {</span><br><span style="color: hsl(120, 100%, 40%);">+             RLCMAC_HDR_TYPE_1,</span><br><span style="color: hsl(120, 100%, 40%);">+            RLCMAC_HDR_TYPE_2,</span><br><span style="color: hsl(120, 100%, 40%);">+            RLCMAC_HDR_TYPE_3</span><br><span style="color: hsl(120, 100%, 40%);">+     };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         type enumerated CodingScheme {</span><br><span>               CS_1,</span><br><span>                CS_2,</span><br><span>                CS_3,</span><br><span>                CS_4,</span><br><span style="color: hsl(120, 100%, 40%);">+         MCS_0,</span><br><span>               MCS_1,</span><br><span>               MCS_2,</span><br><span>               MCS_3,</span><br><span>@@ -238,6 +245,52 @@</span><br><span>        external function dec_RlcmacDlDataBlock(in octetstring stream) return RlcmacDlDataBlock;</span><br><span> </span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+      /* a single RLC block / LLC-segment */</span><br><span style="color: hsl(120, 100%, 40%);">+        type record EgprsLlcBlockHdr {</span><br><span style="color: hsl(120, 100%, 40%);">+                uint7_t         length_ind,</span><br><span style="color: hsl(120, 100%, 40%);">+           /* 0 = another extension octet after LLC PDU, 1 = no more extension octets */</span><br><span style="color: hsl(120, 100%, 40%);">+         boolean         e</span><br><span style="color: hsl(120, 100%, 40%);">+     } with {</span><br><span style="color: hsl(120, 100%, 40%);">+              variant (e) "FIELDLENGTH(1)"</span><br><span style="color: hsl(120, 100%, 40%);">+                encode "RAW"</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%);">+  external function enc_EgprsLlcBlockHdr(in EgprsLlcBlockHdr si) return octetstring</span><br><span style="color: hsl(120, 100%, 40%);">+             with { extension "prototype(convert) encode(RAW)" };</span><br><span style="color: hsl(120, 100%, 40%);">+        external function dec_EgprsLlcBlockHdr(in octetstring stream) return EgprsLlcBlockHdr</span><br><span style="color: hsl(120, 100%, 40%);">+         with { extension "prototype(convert) decode(RAW)" };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      type record EgprsLlcBlock {</span><br><span style="color: hsl(120, 100%, 40%);">+           /* Header is only present if LI field was present */</span><br><span style="color: hsl(120, 100%, 40%);">+          EgprsLlcBlockHdr        hdr optional,</span><br><span style="color: hsl(120, 100%, 40%);">+         octetstring             payload</span><br><span style="color: hsl(120, 100%, 40%);">+       } with { variant "" };</span><br><span style="color: hsl(120, 100%, 40%);">+      type record of EgprsLlcBlock EgprsLlcBlocks;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* TS 44.060 10.3a.1.1 EGPRS downlink RLC data block, manual c++ encoder/decoder */</span><br><span style="color: hsl(120, 100%, 40%);">+   type record EgprsDlMacDataHeader {</span><br><span style="color: hsl(120, 100%, 40%);">+            EgprsHeaderType header_type, /* Set internally by decoder */</span><br><span style="color: hsl(120, 100%, 40%);">+          uint5_t         tfi,</span><br><span style="color: hsl(120, 100%, 40%);">+          MacRrbp         rrbp,</span><br><span style="color: hsl(120, 100%, 40%);">+         BIT2            esp,</span><br><span style="color: hsl(120, 100%, 40%);">+          uint3_t         usf,</span><br><span style="color: hsl(120, 100%, 40%);">+          uint14_t        bsn1,</span><br><span style="color: hsl(120, 100%, 40%);">+         uint8_t         bsn2_offset,</span><br><span style="color: hsl(120, 100%, 40%);">+          uint2_t         pr, /* power reduction */</span><br><span style="color: hsl(120, 100%, 40%);">+             uint2_t         spb,</span><br><span style="color: hsl(120, 100%, 40%);">+          uint4_t         cps</span><br><span style="color: hsl(120, 100%, 40%);">+   } with { variant "" };</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Manual C++ Decoder: */</span><br><span style="color: hsl(120, 100%, 40%);">+     type record RlcmacDlEgprsDataBlock {</span><br><span style="color: hsl(120, 100%, 40%);">+          EgprsDlMacDataHeader    mac_hdr,</span><br><span style="color: hsl(120, 100%, 40%);">+              boolean                 fbi,</span><br><span style="color: hsl(120, 100%, 40%);">+          boolean                 e,</span><br><span style="color: hsl(120, 100%, 40%);">+            EgprsLlcBlocks          blocks</span><br><span style="color: hsl(120, 100%, 40%);">+        } with {</span><br><span style="color: hsl(120, 100%, 40%);">+              variant (fbi) "FIELDLENGTH(1)"</span><br><span style="color: hsl(120, 100%, 40%);">+              variant (e) "FIELDLENGTH(1)"</span><br><span style="color: hsl(120, 100%, 40%);">+        };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         /* TS 44.060 10.2.2 */</span><br><span>       type record UlMacDataHeader {</span><br><span>                /* Octet 0 */</span><br><span>@@ -268,6 +321,35 @@</span><br><span>                 variant (m) "FIELDLENGTH(1)"</span><br><span>       };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+        /* TS 44.060 10.3a.1.1 10.3a.4 EGPRS Uplink RLC/MAC header, manual c++ encoder/decoder */</span><br><span style="color: hsl(120, 100%, 40%);">+     type record EgprsUlMacDataHeader {</span><br><span style="color: hsl(120, 100%, 40%);">+            EgprsHeaderType header_type, /* Set internally by decoder */</span><br><span style="color: hsl(120, 100%, 40%);">+          uint5_t         tfi,</span><br><span style="color: hsl(120, 100%, 40%);">+          uint4_t         countdown,</span><br><span style="color: hsl(120, 100%, 40%);">+            BIT1            foi_si,</span><br><span style="color: hsl(120, 100%, 40%);">+               BIT1            r_ri,</span><br><span style="color: hsl(120, 100%, 40%);">+         uint11_t        bsn1,</span><br><span style="color: hsl(120, 100%, 40%);">+         uint4_t         cps,</span><br><span style="color: hsl(120, 100%, 40%);">+          boolean         pfi_ind,</span><br><span style="color: hsl(120, 100%, 40%);">+              BIT1            rsb,</span><br><span style="color: hsl(120, 100%, 40%);">+          BIT2            spb</span><br><span style="color: hsl(120, 100%, 40%);">+   } with {</span><br><span style="color: hsl(120, 100%, 40%);">+              variant (pfi_ind) "FIELDLENGTH(1)"</span><br><span style="color: hsl(120, 100%, 40%);">+  };</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Manual C++ Decoder:  10.3a.2.1 EGPRS Uplink RLC data block */</span><br><span style="color: hsl(120, 100%, 40%);">+      type record RlcmacUlEgprsDataBlock {</span><br><span style="color: hsl(120, 100%, 40%);">+          EgprsUlMacDataHeader    mac_hdr,</span><br><span style="color: hsl(120, 100%, 40%);">+              boolean                 tlli_ind,</span><br><span style="color: hsl(120, 100%, 40%);">+             boolean                 e,</span><br><span style="color: hsl(120, 100%, 40%);">+            /* Octet 3 ... M (optional): manual C++ Decoder */</span><br><span style="color: hsl(120, 100%, 40%);">+            GprsTlli                tlli optional,</span><br><span style="color: hsl(120, 100%, 40%);">+                RlcMacUlPfi             pfi optional,</span><br><span style="color: hsl(120, 100%, 40%);">+         EgprsLlcBlocks          blocks</span><br><span style="color: hsl(120, 100%, 40%);">+        } with {</span><br><span style="color: hsl(120, 100%, 40%);">+              variant (tlli_ind) "FIELDLENGTH(1)"</span><br><span style="color: hsl(120, 100%, 40%);">+         variant (e) "FIELDLENGTH(1)"</span><br><span style="color: hsl(120, 100%, 40%);">+        };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         /* TS 44.060 10.2.2 */</span><br><span>       type record RlcmacUlDataBlock {</span><br><span>              /* MAC header */</span><br><span>@@ -286,11 +368,16 @@</span><br><span> </span><br><span>         type union RlcmacUlBlock {</span><br><span>           RlcmacUlDataBlock       data,</span><br><span style="color: hsl(120, 100%, 40%);">+         RlcmacUlEgprsDataBlock  data_egprs,</span><br><span>          RlcmacUlCtrlBlock       ctrl</span><br><span>         } with {</span><br><span>             variant "TAG(data, mac_hdr.payload_type = MAC_PT_RLC_DATA;</span><br><span style="color: hsl(0, 100%, 40%);">-                      ctrl, mac_hdr.payload_type = MAC_PT_RLCMAC_NO_OPT;</span><br><span style="color: hsl(0, 100%, 40%);">-                      ctrl, mac_hdr.payload_type = MAC_PT_RLCMAC_OPT)"</span><br><span style="color: hsl(120, 100%, 40%);">+                         ctrl, {mac_hdr.payload_type = MAC_PT_RLCMAC_NO_OPT,</span><br><span style="color: hsl(120, 100%, 40%);">+                                  mac_hdr.payload_type = MAC_PT_RLCMAC_OPT};</span><br><span style="color: hsl(120, 100%, 40%);">+                             data_egprs, {mac_hdr.header_type = RLCMAC_HDR_TYPE_1,</span><br><span style="color: hsl(120, 100%, 40%);">+                                      mac_hdr.header_type = RLCMAC_HDR_TYPE_2,</span><br><span style="color: hsl(120, 100%, 40%);">+                                      mac_hdr.header_type = RLCMAC_HDR_TYPE_3}</span><br><span style="color: hsl(120, 100%, 40%);">+                         )"</span><br><span>         };</span><br><span> </span><br><span>       /* as the sub-types (RlcmacDl*Block) are not using the RAW coder, we cannot</span><br><span>@@ -301,11 +388,16 @@</span><br><span> </span><br><span>      type union RlcmacDlBlock {</span><br><span>           RlcmacDlDataBlock       data,</span><br><span style="color: hsl(120, 100%, 40%);">+         RlcmacDlEgprsDataBlock  data_egprs,</span><br><span>          RlcmacDlCtrlBlock       ctrl</span><br><span>         } with {</span><br><span>             variant "TAG(data, mac_hdr.mac_hdr.payload_type = MAC_PT_RLC_DATA;</span><br><span style="color: hsl(0, 100%, 40%);">-                      ctrl, mac_hdr.payload_type = MAC_PT_RLCMAC_NO_OPT;</span><br><span style="color: hsl(0, 100%, 40%);">-                      ctrl, mac_hdr.payload_type = MAC_PT_RLCMAC_OPT)"</span><br><span style="color: hsl(120, 100%, 40%);">+                         ctrl, {mac_hdr.payload_type = MAC_PT_RLCMAC_NO_OPT,</span><br><span style="color: hsl(120, 100%, 40%);">+                                  mac_hdr.payload_type = MAC_PT_RLCMAC_OPT};</span><br><span style="color: hsl(120, 100%, 40%);">+                             data_egprs, {mac_hdr.header_type = RLCMAC_HDR_TYPE_1,</span><br><span style="color: hsl(120, 100%, 40%);">+                                      mac_hdr.header_type = RLCMAC_HDR_TYPE_2,</span><br><span style="color: hsl(120, 100%, 40%);">+                                      mac_hdr.header_type = RLCMAC_HDR_TYPE_3}</span><br><span style="color: hsl(120, 100%, 40%);">+                         )"</span><br><span>         };</span><br><span> </span><br><span>       /* as the sub-types (RlcmacDl*Block) are not using the RAW coder, we cannot</span><br><span>@@ -546,6 +638,15 @@</span><br><span>           }</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ template RlcmacDlBlock tr_RLCMAC_DATA_EGPRS := {</span><br><span style="color: hsl(120, 100%, 40%);">+              data_egprs := {</span><br><span style="color: hsl(120, 100%, 40%);">+                       mac_hdr := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+                 fbi := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+                     e := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+                       blocks := ?</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>  /* Template for Uplink MAC Control Header */</span><br><span>         template UlMacCtrlHeader t_RLCMAC_UlMacCtrlH(template MacPayloadType pt, template boolean retry := false) := {</span><br><span>               payload_type := pt,</span><br><span>@@ -576,8 +677,10 @@</span><br><span>           payload := data</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   /* PTCCH/D (Packet Timing Advance Control Channel) message.</span><br><span style="color: hsl(0, 100%, 40%);">-      * TODO: add a spec. reference to the message format definition. */</span><br><span style="color: hsl(120, 100%, 40%);">+/************************</span><br><span style="color: hsl(120, 100%, 40%);">+ * PTCCH/D (Packet Timing Advance Control Channel) message.</span><br><span style="color: hsl(120, 100%, 40%);">+ * TODO: add a spec. reference to the message format definition.</span><br><span style="color: hsl(120, 100%, 40%);">+ *************************/</span><br><span>   type record PTCCHTimingAdvanceIE {</span><br><span>           BIT1                    spare ('0'B),</span><br><span>                uint7_t                 ta_val</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/17965">change 17965</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/+/17965"/><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: I2bc4f877a5e17c57ffa8cf05565dc8593b45aae8 </div>
<div style="display:none"> Gerrit-Change-Number: 17965 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>