<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>