<p>pespin has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-pcu/+/18351">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Get rid of class GprsCodingScheme<br><br>We have same kind of object splitted into two layers, in coding_scheme<br>and gprs_coding_scheme. Let's merge them together and get rid of the<br>class, which is not really useful because it's only a set of functions<br>operating on one enum value.<br><br>This change also fixes gcc 10.1.0 error about memseting a complex type<br>in rlc.h init().<br><br>Change-Id: Ie9ce2144ba9e8dbba9704d4e0000a2929e3e41df<br>---<br>M src/Makefile.am<br>M src/bts.h<br>M src/coding_scheme.c<br>M src/coding_scheme.h<br>M src/decoding.cpp<br>M src/decoding.h<br>M src/encoding.cpp<br>M src/encoding.h<br>M src/gprs_bssgp_pcu.cpp<br>D src/gprs_coding_scheme.cpp<br>D src/gprs_coding_scheme.h<br>M src/gprs_ms.cpp<br>M src/gprs_ms.h<br>M src/pcu_main.cpp<br>M src/pcu_vty_functions.cpp<br>M src/pdch.cpp<br>M src/pdch.h<br>M src/rlc.cpp<br>M src/rlc.h<br>M src/tbf.cpp<br>M src/tbf.h<br>M src/tbf_dl.cpp<br>M src/tbf_dl.h<br>M src/tbf_ul.cpp<br>M tests/edge/EdgeTest.cpp<br>M tests/tbf/TbfTest.cpp<br>26 files changed, 530 insertions(+), 669 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/51/18351/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/Makefile.am b/src/Makefile.am</span><br><span>index 54c6f1b..ece372d 100644</span><br><span>--- a/src/Makefile.am</span><br><span>+++ b/src/Makefile.am</span><br><span>@@ -68,7 +68,6 @@</span><br><span>      osmobts_sock.cpp \</span><br><span>   gprs_codel.c \</span><br><span>       coding_scheme.c \</span><br><span style="color: hsl(0, 100%, 40%);">-       gprs_coding_scheme.cpp \</span><br><span>     egprs_rlc_compression.cpp \</span><br><span>  gprs_rlcmac_sched.cpp</span><br><span> </span><br><span>@@ -104,7 +103,6 @@</span><br><span>      pcu_utils.h \</span><br><span>        cxx_linuxlist.h \</span><br><span>    gprs_codel.h \</span><br><span style="color: hsl(0, 100%, 40%);">-  gprs_coding_scheme.h \</span><br><span>       coding_scheme.h \</span><br><span>    egprs_rlc_compression.h \</span><br><span>    wireshark_compat.h</span><br><span>diff --git a/src/bts.h b/src/bts.h</span><br><span>index 15dd482..9986bdc 100644</span><br><span>--- a/src/bts.h</span><br><span>+++ b/src/bts.h</span><br><span>@@ -37,7 +37,7 @@</span><br><span> #include "sba.h"</span><br><span> #include "tbf.h"</span><br><span> #include "gprs_ms_storage.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "gprs_coding_scheme.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "coding_scheme.h"</span><br><span> #include <cxx_linuxlist.h></span><br><span> #endif</span><br><span> </span><br><span>diff --git a/src/coding_scheme.c b/src/coding_scheme.c</span><br><span>index eaa4953..9848432 100644</span><br><span>--- a/src/coding_scheme.c</span><br><span>+++ b/src/coding_scheme.c</span><br><span>@@ -42,6 +42,56 @@</span><br><span>         { 0, NULL }</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+enum Family {</span><br><span style="color: hsl(120, 100%, 40%);">+  FAMILY_INVALID,</span><br><span style="color: hsl(120, 100%, 40%);">+       FAMILY_A,</span><br><span style="color: hsl(120, 100%, 40%);">+     FAMILY_B,</span><br><span style="color: hsl(120, 100%, 40%);">+     FAMILY_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%);">+static struct {</span><br><span style="color: hsl(120, 100%, 40%);">+      struct {</span><br><span style="color: hsl(120, 100%, 40%);">+              uint8_t bytes;</span><br><span style="color: hsl(120, 100%, 40%);">+                uint8_t ext_bits;</span><br><span style="color: hsl(120, 100%, 40%);">+             uint8_t data_header_bits;</span><br><span style="color: hsl(120, 100%, 40%);">+     } uplink, downlink;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t data_bytes;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t optional_padding_bits;</span><br><span style="color: hsl(120, 100%, 40%);">+        enum HeaderType data_hdr;</span><br><span style="color: hsl(120, 100%, 40%);">+     enum Family family;</span><br><span style="color: hsl(120, 100%, 40%);">+} mcs_info[NUM_SCHEMES] = {</span><br><span style="color: hsl(120, 100%, 40%);">+      {{0, 0},   {0, 0},    0,  0,</span><br><span style="color: hsl(120, 100%, 40%);">+          HEADER_INVALID, FAMILY_INVALID},</span><br><span style="color: hsl(120, 100%, 40%);">+      {{23, 0},  {23, 0},  20,  0,</span><br><span style="color: hsl(120, 100%, 40%);">+          HEADER_GPRS_DATA, FAMILY_INVALID},</span><br><span style="color: hsl(120, 100%, 40%);">+    {{33, 7},  {33, 7},  30,  0,</span><br><span style="color: hsl(120, 100%, 40%);">+          HEADER_GPRS_DATA, FAMILY_INVALID},</span><br><span style="color: hsl(120, 100%, 40%);">+    {{39, 3},  {39, 3},  36,  0,</span><br><span style="color: hsl(120, 100%, 40%);">+          HEADER_GPRS_DATA, FAMILY_INVALID},</span><br><span style="color: hsl(120, 100%, 40%);">+    {{53, 7},  {53, 7},  50,  0,</span><br><span style="color: hsl(120, 100%, 40%);">+          HEADER_GPRS_DATA, FAMILY_INVALID},</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  {{26, 1},  {26, 1},  22,  0,</span><br><span style="color: hsl(120, 100%, 40%);">+          HEADER_EGPRS_DATA_TYPE_3, FAMILY_C},</span><br><span style="color: hsl(120, 100%, 40%);">+  {{32, 1},  {32, 1},  28,  0,</span><br><span style="color: hsl(120, 100%, 40%);">+          HEADER_EGPRS_DATA_TYPE_3, FAMILY_B},</span><br><span style="color: hsl(120, 100%, 40%);">+  {{41, 1},  {41, 1},  37, 48,</span><br><span style="color: hsl(120, 100%, 40%);">+          HEADER_EGPRS_DATA_TYPE_3, FAMILY_A},</span><br><span style="color: hsl(120, 100%, 40%);">+  {{48, 1},  {48, 1},  44,  0,</span><br><span style="color: hsl(120, 100%, 40%);">+          HEADER_EGPRS_DATA_TYPE_3, FAMILY_C},</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        {{60, 7},  {59, 6},  56,  0,</span><br><span style="color: hsl(120, 100%, 40%);">+          HEADER_EGPRS_DATA_TYPE_2, FAMILY_B},</span><br><span style="color: hsl(120, 100%, 40%);">+  {{78, 7},  {77, 6},  74, 48,</span><br><span style="color: hsl(120, 100%, 40%);">+          HEADER_EGPRS_DATA_TYPE_2, FAMILY_A},</span><br><span style="color: hsl(120, 100%, 40%);">+  {{118, 2}, {117, 4}, 56,  0,</span><br><span style="color: hsl(120, 100%, 40%);">+          HEADER_EGPRS_DATA_TYPE_1, FAMILY_B},</span><br><span style="color: hsl(120, 100%, 40%);">+  {{142, 2}, {141, 4}, 68,  0,</span><br><span style="color: hsl(120, 100%, 40%);">+          HEADER_EGPRS_DATA_TYPE_1, FAMILY_A},</span><br><span style="color: hsl(120, 100%, 40%);">+  {{154, 2}, {153, 4}, 74,  0,</span><br><span style="color: hsl(120, 100%, 40%);">+          HEADER_EGPRS_DATA_TYPE_1, FAMILY_A},</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> const char *mcs_name(enum CodingScheme val) {</span><br><span>  return get_value_string(mcs_names, val);</span><br><span> }</span><br><span>@@ -77,6 +127,194 @@</span><br><span>         return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+enum CodingScheme mcs_get_by_size_ul(unsigned size)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    switch (size) {</span><br><span style="color: hsl(120, 100%, 40%);">+               case 23: return CS1;</span><br><span style="color: hsl(120, 100%, 40%);">+          case 27: return MCS1;</span><br><span style="color: hsl(120, 100%, 40%);">+         case 33: return MCS2;</span><br><span style="color: hsl(120, 100%, 40%);">+         case 34: return CS2;</span><br><span style="color: hsl(120, 100%, 40%);">+          case 40: return CS3;</span><br><span style="color: hsl(120, 100%, 40%);">+          case 42: return MCS3;</span><br><span style="color: hsl(120, 100%, 40%);">+         case 49: return MCS4;</span><br><span style="color: hsl(120, 100%, 40%);">+         case 54: return CS4;</span><br><span style="color: hsl(120, 100%, 40%);">+          case 61: return MCS5;</span><br><span style="color: hsl(120, 100%, 40%);">+         case 79: return MCS6;</span><br><span style="color: hsl(120, 100%, 40%);">+         case 119: return MCS7;</span><br><span style="color: hsl(120, 100%, 40%);">+                case 143: return MCS8;</span><br><span style="color: hsl(120, 100%, 40%);">+                case 155: return MCS9;</span><br><span style="color: hsl(120, 100%, 40%);">+                default: return UNKNOWN;</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%);">+enum CodingScheme mcs_get_gprs_by_num(unsigned num)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        if (num < 1 || num > 4)</span><br><span style="color: hsl(120, 100%, 40%);">+         return UNKNOWN;</span><br><span style="color: hsl(120, 100%, 40%);">+       return CS1 + (num - 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%);">+enum CodingScheme mcs_get_egprs_by_num(unsigned num)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ if (num < 1 || num > 9)</span><br><span style="color: hsl(120, 100%, 40%);">+         return UNKNOWN;</span><br><span style="color: hsl(120, 100%, 40%);">+       return MCS1 + (num - 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%);">+bool mcs_is_valid(enum CodingScheme cs)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     return UNKNOWN <= cs && cs <= MCS9;</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%);">+bool mcs_is_compat_kind(enum CodingScheme cs, enum mcs_kind mode)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  switch (mode) {</span><br><span style="color: hsl(120, 100%, 40%);">+       case GPRS: return mcs_is_gprs(cs);</span><br><span style="color: hsl(120, 100%, 40%);">+    case EGPRS_GMSK: return mcs_is_edge_gmsk(cs);</span><br><span style="color: hsl(120, 100%, 40%);">+ case EGPRS: return mcs_is_edge(cs);</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return false;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+bool mcs_is_compat(enum CodingScheme cs, enum CodingScheme o)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  return (mcs_is_gprs(cs) && mcs_is_gprs(o)) || (mcs_is_edge(cs) && mcs_is_edge(o));</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%);">+uint8_t mcs_size_ul(enum CodingScheme cs)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return mcs_info[cs].uplink.bytes + (mcs_spare_bits_ul(cs) ? 1 : 0);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t mcs_size_dl(enum CodingScheme cs)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        return mcs_info[cs].downlink.bytes + (mcs_spare_bits_dl(cs) ? 1 : 0);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t mcs_used_size_ul(enum CodingScheme cs)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ if (mcs_info[cs].data_hdr == HEADER_GPRS_DATA)</span><br><span style="color: hsl(120, 100%, 40%);">+                return mcs_info[cs].uplink.bytes;</span><br><span style="color: hsl(120, 100%, 40%);">+     else</span><br><span style="color: hsl(120, 100%, 40%);">+          return mcs_size_ul(cs);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t mcs_used_size_dl(enum CodingScheme cs)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       if (mcs_info[cs].data_hdr == HEADER_GPRS_DATA)</span><br><span style="color: hsl(120, 100%, 40%);">+                return mcs_info[cs].downlink.bytes;</span><br><span style="color: hsl(120, 100%, 40%);">+   else</span><br><span style="color: hsl(120, 100%, 40%);">+          return mcs_size_dl(cs);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t mcs_max_bytes_ul(enum CodingScheme cs)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       return mcs_info[cs].uplink.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%);">+uint8_t mcs_max_bytes_dl(enum CodingScheme cs)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     return mcs_info[cs].downlink.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%);">+uint8_t mcs_spare_bits_ul(enum CodingScheme cs)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  return mcs_info[cs].uplink.ext_bits;</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%);">+uint8_t mcs_spare_bits_dl(enum CodingScheme cs)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+return mcs_info[cs].downlink.ext_bits;</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%);">+uint8_t mcs_max_data_block_bytes(enum CodingScheme cs)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return mcs_info[cs].data_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%);">+uint8_t mcs_opt_padding_bits(enum CodingScheme cs)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   return mcs_info[cs].optional_padding_bits;</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%);">+void mcs_inc_kind(enum CodingScheme *cs, enum mcs_kind mode)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!mcs_is_compat_kind(*cs, mode))</span><br><span style="color: hsl(120, 100%, 40%);">+           /* This should not happen. TODO: Use assert? */</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%);">+     enum CodingScheme new_cs = *cs + 1;</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!mcs_is_compat_kind(new_cs, mode))</span><br><span style="color: hsl(120, 100%, 40%);">+                /* Clipping, do not change the value */</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%);">+     *cs = new_cs;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void mcs_dec_kind(enum CodingScheme *cs, enum mcs_kind mode)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!mcs_is_compat_kind(*cs, mode))</span><br><span style="color: hsl(120, 100%, 40%);">+           /* This should not happen. TODO: Use assert? */</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%);">+     enum CodingScheme new_cs = *cs - 1;</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!mcs_is_compat_kind(new_cs, mode))</span><br><span style="color: hsl(120, 100%, 40%);">+                /* Clipping, do not change the value */</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%);">+     *cs = new_cs;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void mcs_inc(enum CodingScheme *cs)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    if (mcs_is_gprs(*cs) && *cs == CS4)</span><br><span style="color: hsl(120, 100%, 40%);">+           return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (mcs_is_edge(*cs) && *cs == MCS9)</span><br><span style="color: hsl(120, 100%, 40%);">+          return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!mcs_is_valid(*cs))</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%);">+     *cs = *cs + 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%);">+void mcs_dec(enum CodingScheme *cs)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   if (mcs_is_gprs(*cs) && *cs == CS1)</span><br><span style="color: hsl(120, 100%, 40%);">+           return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (mcs_is_edge(*cs) && *cs == MCS1)</span><br><span style="color: hsl(120, 100%, 40%);">+          return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!mcs_is_valid(*cs))</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%);">+     *cs = *cs - 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%);">+bool mcs_is_family_compat(enum CodingScheme cs, enum CodingScheme o)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  if (cs == o)</span><br><span style="color: hsl(120, 100%, 40%);">+          return true;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if (mcs_info[cs].family == FAMILY_INVALID)</span><br><span style="color: hsl(120, 100%, 40%);">+            return false;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       return mcs_info[cs].family == mcs_info[o].family;</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%);">+void mcs_dec_to_single_block(enum CodingScheme *cs, bool *needStuffing)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    switch (*cs) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case MCS7: *needStuffing = false; *cs = MCS5; break;</span><br><span style="color: hsl(120, 100%, 40%);">+  case MCS8: *needStuffing =  true; *cs = MCS6; break;</span><br><span style="color: hsl(120, 100%, 40%);">+  case MCS9: *needStuffing = false; *cs = MCS6; break;</span><br><span style="color: hsl(120, 100%, 40%);">+  default:   *needStuffing = false; 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> static struct {</span><br><span>    struct {</span><br><span>             uint8_t data_header_bits;</span><br><span>@@ -93,6 +331,11 @@</span><br><span>      { { 3 * 8 + 7 }, { 3 * 8 + 7 }, 2, 1, "EGPRS_DATA_TYPE3" },</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+enum HeaderType mcs_header_type(enum CodingScheme mcs)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    return mcs_info[mcs].data_hdr;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> uint8_t num_data_blocks(enum HeaderType ht)</span><br><span> {</span><br><span>      OSMO_ASSERT(ht < NUM_HEADER_TYPES);</span><br><span>diff --git a/src/coding_scheme.h b/src/coding_scheme.h</span><br><span>index 24db86d..8800f0c 100644</span><br><span>--- a/src/coding_scheme.h</span><br><span>+++ b/src/coding_scheme.h</span><br><span>@@ -21,6 +21,8 @@</span><br><span> </span><br><span> #include <osmocom/core/utils.h></span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdbool.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> enum CodingScheme {</span><br><span>    UNKNOWN,</span><br><span>     /* GPRS Coding Schemes: */</span><br><span>@@ -30,6 +32,15 @@</span><br><span>      NUM_SCHEMES</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+enum mcs_kind {</span><br><span style="color: hsl(120, 100%, 40%);">+        GPRS,</span><br><span style="color: hsl(120, 100%, 40%);">+ EGPRS_GMSK,</span><br><span style="color: hsl(120, 100%, 40%);">+   EGPRS,</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%);">+#define EGPRS_ARQ1            0x0</span><br><span style="color: hsl(120, 100%, 40%);">+#define EGPRS_ARQ2            0x1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> extern const struct value_string mcs_names[];</span><br><span> const char *mcs_name(enum CodingScheme val);</span><br><span> enum CodingScheme get_retx_mcs(enum CodingScheme initial_mcs, enum CodingScheme commanded_mcs, bool resegment_bit);</span><br><span>@@ -40,6 +51,32 @@</span><br><span> </span><br><span> uint8_t mcs_chan_code(enum CodingScheme cs);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+enum CodingScheme mcs_get_by_size_ul(unsigned size);</span><br><span style="color: hsl(120, 100%, 40%);">+enum CodingScheme mcs_get_gprs_by_num(unsigned num);</span><br><span style="color: hsl(120, 100%, 40%);">+enum CodingScheme mcs_get_egprs_by_num(unsigned num);</span><br><span style="color: hsl(120, 100%, 40%);">+bool mcs_is_valid(enum CodingScheme cs);</span><br><span style="color: hsl(120, 100%, 40%);">+bool mcs_is_compat(enum CodingScheme cs, enum CodingScheme o);</span><br><span style="color: hsl(120, 100%, 40%);">+bool mcs_is_compat_kind(enum CodingScheme cs, enum mcs_kind mode);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t mcs_size_ul(enum CodingScheme cs);</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t mcs_size_dl(enum CodingScheme cs);</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t mcs_used_size_ul(enum CodingScheme cs);</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t mcs_used_size_dl(enum CodingScheme cs);</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t mcs_max_bytes_ul(enum CodingScheme cs);</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t mcs_max_bytes_dl(enum CodingScheme cs);</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t mcs_spare_bits_ul(enum CodingScheme cs);</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t mcs_spare_bits_dl(enum CodingScheme cs);</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t mcs_max_data_block_bytes(enum CodingScheme cs);</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t mcs_opt_padding_bits(enum CodingScheme cs);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void mcs_inc_kind(enum CodingScheme *cs, enum mcs_kind mode);</span><br><span style="color: hsl(120, 100%, 40%);">+void mcs_dec_kind(enum CodingScheme *cs, enum mcs_kind mode);</span><br><span style="color: hsl(120, 100%, 40%);">+void mcs_inc(enum CodingScheme *cs);</span><br><span style="color: hsl(120, 100%, 40%);">+void mcs_dec(enum CodingScheme *cs);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+bool mcs_is_family_compat(enum CodingScheme cs, enum CodingScheme o);</span><br><span style="color: hsl(120, 100%, 40%);">+void mcs_dec_to_single_block(enum CodingScheme *cs, bool *needStuffing);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> enum HeaderType {</span><br><span>     HEADER_INVALID,</span><br><span>      HEADER_GPRS_CONTROL,</span><br><span>@@ -50,17 +87,11 @@</span><br><span>   NUM_HEADER_TYPES</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-enum HeaderType headerTypeData(enum CodingScheme mcs);</span><br><span style="color: hsl(120, 100%, 40%);">+enum HeaderType mcs_header_type(enum CodingScheme mcs);</span><br><span> </span><br><span> uint8_t num_data_blocks(enum HeaderType ht);</span><br><span> uint8_t num_data_header_bits_UL(enum HeaderType ht);</span><br><span> uint8_t num_data_header_bits_DL(enum HeaderType ht);</span><br><span> uint8_t num_data_block_header_bits(enum HeaderType ht);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-enum mcs_kind {</span><br><span style="color: hsl(0, 100%, 40%);">-     GPRS,</span><br><span style="color: hsl(0, 100%, 40%);">-   EGPRS_GMSK,</span><br><span style="color: hsl(0, 100%, 40%);">-     EGPRS,</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> const char *mode_name(enum mcs_kind val);</span><br><span>diff --git a/src/decoding.cpp b/src/decoding.cpp</span><br><span>index 99a17dc..7b9ae06 100644</span><br><span>--- a/src/decoding.cpp</span><br><span>+++ b/src/decoding.cpp</span><br><span>@@ -189,7 +189,7 @@</span><br><span> }</span><br><span> </span><br><span> int Decoding::rlc_data_from_ul_data(</span><br><span style="color: hsl(0, 100%, 40%);">-       const struct gprs_rlc_data_block_info *rdbi, GprsCodingScheme cs,</span><br><span style="color: hsl(120, 100%, 40%);">+     const struct gprs_rlc_data_block_info *rdbi, CodingScheme cs,</span><br><span>        const uint8_t *data, RlcData *chunks, unsigned int chunks_size,</span><br><span>      uint32_t *tlli)</span><br><span> {</span><br><span>@@ -351,10 +351,10 @@</span><br><span> }</span><br><span> </span><br><span> int Decoding::rlc_parse_ul_data_header(struct gprs_rlc_data_info *rlc,</span><br><span style="color: hsl(0, 100%, 40%);">- const uint8_t *data, GprsCodingScheme cs)</span><br><span style="color: hsl(120, 100%, 40%);">+     const uint8_t *data, CodingScheme cs)</span><br><span> {</span><br><span>   unsigned int cur_bit = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       switch(cs.headerTypeData()) {</span><br><span style="color: hsl(120, 100%, 40%);">+ switch(mcs_header_type(cs)) {</span><br><span>        case HEADER_GPRS_DATA :</span><br><span>              cur_bit = rlc_parse_ul_data_header_gprs(rlc, data, cs);</span><br><span>              break;</span><br><span>@@ -380,7 +380,7 @@</span><br><span> int Decoding::rlc_parse_ul_data_header_egprs_type_3(</span><br><span>         struct gprs_rlc_data_info *rlc,</span><br><span>      const uint8_t *data,</span><br><span style="color: hsl(0, 100%, 40%);">-    const GprsCodingScheme &cs)</span><br><span style="color: hsl(120, 100%, 40%);">+       const CodingScheme &cs)</span><br><span> {</span><br><span>     int punct, punct2, with_padding, cps;</span><br><span>        unsigned int e_ti_header, offs, cur_bit = 0;</span><br><span>@@ -414,7 +414,7 @@</span><br><span>   rlc->block_info[0].ti  = !!(e_ti_header & 0x02);</span><br><span>      cur_bit += 2;</span><br><span>        /* skip data area */</span><br><span style="color: hsl(0, 100%, 40%);">-    cur_bit += cs.maxDataBlockBytes() * 8;</span><br><span style="color: hsl(120, 100%, 40%);">+        cur_bit += mcs_max_data_block_bytes(cs) * 8;</span><br><span> </span><br><span>     return cur_bit;</span><br><span> }</span><br><span>@@ -422,7 +422,7 @@</span><br><span> int Decoding::rlc_parse_ul_data_header_egprs_type_2(</span><br><span>   struct gprs_rlc_data_info *rlc,</span><br><span>      const uint8_t *data,</span><br><span style="color: hsl(0, 100%, 40%);">-    const GprsCodingScheme &cs)</span><br><span style="color: hsl(120, 100%, 40%);">+       const CodingScheme &cs)</span><br><span> {</span><br><span>     const struct gprs_rlc_ul_header_egprs_2 *egprs2;</span><br><span>     unsigned int e_ti_header, offs, cur_bit = 0;</span><br><span>@@ -458,14 +458,14 @@</span><br><span>         cur_bit += 2;</span><br><span> </span><br><span>    /* skip data area */</span><br><span style="color: hsl(0, 100%, 40%);">-    cur_bit += cs.maxDataBlockBytes() * 8;</span><br><span style="color: hsl(120, 100%, 40%);">+        cur_bit += mcs_max_data_block_bytes(cs) * 8;</span><br><span> </span><br><span>     return cur_bit;</span><br><span> }</span><br><span> </span><br><span> int Decoding::rlc_parse_ul_data_header_egprs_type_1(</span><br><span>     struct gprs_rlc_data_info *rlc,</span><br><span style="color: hsl(0, 100%, 40%);">- const uint8_t *data, const GprsCodingScheme &cs)</span><br><span style="color: hsl(120, 100%, 40%);">+  const uint8_t *data, const CodingScheme &cs)</span><br><span> {</span><br><span>        struct gprs_rlc_ul_header_egprs_1 *egprs1;</span><br><span>   unsigned int e_ti_header, cur_bit = 0, offs;</span><br><span>@@ -517,13 +517,13 @@</span><br><span>         rlc->block_info[1].ti  = !!(e_ti_header & 0x02);</span><br><span>      cur_bit += 2;</span><br><span>        /* skip data area */</span><br><span style="color: hsl(0, 100%, 40%);">-    cur_bit += cs.maxDataBlockBytes() * 8;</span><br><span style="color: hsl(120, 100%, 40%);">+        cur_bit += mcs_max_data_block_bytes(cs) * 8;</span><br><span> </span><br><span>     return cur_bit;</span><br><span> }</span><br><span> </span><br><span> int Decoding::rlc_parse_ul_data_header_gprs(struct gprs_rlc_data_info *rlc,</span><br><span style="color: hsl(0, 100%, 40%);">- const uint8_t *data, const GprsCodingScheme &cs)</span><br><span style="color: hsl(120, 100%, 40%);">+  const uint8_t *data, const CodingScheme &cs)</span><br><span> {</span><br><span>        const struct rlc_ul_header *gprs;</span><br><span>    unsigned int cur_bit = 0;</span><br><span>@@ -547,7 +547,7 @@</span><br><span>      rlc->block_info[0].spb = 0;</span><br><span>       cur_bit += rlc->data_offs_bits[0];</span><br><span>        /* skip data area */</span><br><span style="color: hsl(0, 100%, 40%);">-    cur_bit += cs.maxDataBlockBytes() * 8;</span><br><span style="color: hsl(120, 100%, 40%);">+        cur_bit += mcs_max_data_block_bytes(cs) * 8;</span><br><span> </span><br><span>     return cur_bit;</span><br><span> }</span><br><span>diff --git a/src/decoding.h b/src/decoding.h</span><br><span>index cadb80c..695c4b4 100644</span><br><span>--- a/src/decoding.h</span><br><span>+++ b/src/decoding.h</span><br><span>@@ -40,7 +40,7 @@</span><br><span> </span><br><span>    static int rlc_data_from_ul_data(</span><br><span>            const struct gprs_rlc_data_block_info *rdbi,</span><br><span style="color: hsl(0, 100%, 40%);">-            GprsCodingScheme cs, const uint8_t *data, RlcData *chunks,</span><br><span style="color: hsl(120, 100%, 40%);">+            CodingScheme cs, const uint8_t *data, RlcData *chunks,</span><br><span>               unsigned int chunks_size, uint32_t *tlli);</span><br><span>   static uint8_t get_ms_class_by_capability(MS_Radio_Access_capability_t *cap);</span><br><span>        static uint8_t get_egprs_ms_class_by_capability(MS_Radio_Access_capability_t *cap);</span><br><span>@@ -50,21 +50,21 @@</span><br><span>    static int rlc_parse_ul_data_header_egprs_type_3(</span><br><span>            struct gprs_rlc_data_info *rlc,</span><br><span>              const uint8_t *data,</span><br><span style="color: hsl(0, 100%, 40%);">-            const GprsCodingScheme &cs);</span><br><span style="color: hsl(120, 100%, 40%);">+              const CodingScheme &cs);</span><br><span>         static int rlc_parse_ul_data_header_egprs_type_2(</span><br><span>            struct gprs_rlc_data_info *rlc,</span><br><span>              const uint8_t *data,</span><br><span style="color: hsl(0, 100%, 40%);">-            const GprsCodingScheme &cs);</span><br><span style="color: hsl(120, 100%, 40%);">+              const CodingScheme &cs);</span><br><span>         static int rlc_parse_ul_data_header_egprs_type_1(</span><br><span>            struct gprs_rlc_data_info *rlc,</span><br><span>              const uint8_t *data,</span><br><span style="color: hsl(0, 100%, 40%);">-            const GprsCodingScheme &cs);</span><br><span style="color: hsl(120, 100%, 40%);">+              const CodingScheme &cs);</span><br><span>         static int rlc_parse_ul_data_header_gprs(</span><br><span>            struct gprs_rlc_data_info *rlc,</span><br><span>              const uint8_t *data,</span><br><span style="color: hsl(0, 100%, 40%);">-            const GprsCodingScheme &cs);</span><br><span style="color: hsl(120, 100%, 40%);">+              const CodingScheme &cs);</span><br><span>         static int rlc_parse_ul_data_header(struct gprs_rlc_data_info *rlc,</span><br><span style="color: hsl(0, 100%, 40%);">-             const uint8_t *data, GprsCodingScheme cs);</span><br><span style="color: hsl(120, 100%, 40%);">+            const uint8_t *data, CodingScheme cs);</span><br><span>       static unsigned int rlc_copy_to_aligned_buffer(</span><br><span>              const struct gprs_rlc_data_info *rlc,</span><br><span>                unsigned int data_block_idx,</span><br><span>diff --git a/src/encoding.cpp b/src/encoding.cpp</span><br><span>index a4a14dd..619f2ec 100644</span><br><span>--- a/src/encoding.cpp</span><br><span>+++ b/src/encoding.cpp</span><br><span>@@ -1107,11 +1107,11 @@</span><br><span>  struct gprs_rlc_dl_header_egprs_3 *egprs3;</span><br><span>   struct rlc_dl_header *gprs;</span><br><span>  unsigned int e_fbi_header;</span><br><span style="color: hsl(0, 100%, 40%);">-      GprsCodingScheme cs = rlc->cs;</span><br><span style="color: hsl(120, 100%, 40%);">+     CodingScheme cs = rlc->cs;</span><br><span>        unsigned int offs;</span><br><span>   unsigned int bsn_delta;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     switch(cs.headerTypeData()) {</span><br><span style="color: hsl(120, 100%, 40%);">+ switch(mcs_header_type(cs)) {</span><br><span>        case HEADER_GPRS_DATA:</span><br><span>               gprs = static_cast<struct rlc_dl_header *></span><br><span>                     ((void *)data);</span><br><span>@@ -1595,7 +1595,7 @@</span><br><span>  * \return the state of the rlc/mac like if there is more space for another chunk</span><br><span>  */</span><br><span> Encoding::AppendResult Encoding::rlc_data_to_dl_append(</span><br><span style="color: hsl(0, 100%, 40%);">-  struct gprs_rlc_data_block_info *rdbi, GprsCodingScheme cs,</span><br><span style="color: hsl(120, 100%, 40%);">+   struct gprs_rlc_data_block_info *rdbi, CodingScheme cs,</span><br><span>      gprs_llc *llc, int *offset, int *num_chunks,</span><br><span>         uint8_t *data_block, bool is_final, int *count_payload)</span><br><span> {</span><br><span>diff --git a/src/encoding.h b/src/encoding.h</span><br><span>index 2365f07..33290c1 100644</span><br><span>--- a/src/encoding.h</span><br><span>+++ b/src/encoding.h</span><br><span>@@ -21,9 +21,10 @@</span><br><span> #pragma once</span><br><span> </span><br><span> #include <stdint.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <gprs_coding_scheme.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> extern "C" {</span><br><span> #include <osmocom/gsm/l1sap.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include "coding_scheme.h"</span><br><span> #include "gsm_rlcmac.h"</span><br><span> }</span><br><span> </span><br><span>@@ -99,7 +100,7 @@</span><br><span>    };</span><br><span> </span><br><span>       static AppendResult rlc_data_to_dl_append(</span><br><span style="color: hsl(0, 100%, 40%);">-              struct gprs_rlc_data_block_info *rdbi, GprsCodingScheme cs,</span><br><span style="color: hsl(120, 100%, 40%);">+           struct gprs_rlc_data_block_info *rdbi, CodingScheme cs,</span><br><span>              gprs_llc *llc, int *offset, int *num_chunks,</span><br><span>                 uint8_t *data, bool is_final, int *count_payload);</span><br><span> };</span><br><span>diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp</span><br><span>index b8e746a..9e293a8 100644</span><br><span>--- a/src/gprs_bssgp_pcu.cpp</span><br><span>+++ b/src/gprs_bssgp_pcu.cpp</span><br><span>@@ -24,7 +24,7 @@</span><br><span> #include <gprs_debug.h></span><br><span> #include <bts.h></span><br><span> #include <tbf.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <gprs_coding_scheme.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <coding_scheme.h></span><br><span> #include <pdch.h></span><br><span> #include <decoding.h></span><br><span> </span><br><span>@@ -639,9 +639,9 @@</span><br><span>    return num_pdch;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static uint32_t gprs_bssgp_max_leak_rate(GprsCodingScheme cs, int num_pdch)</span><br><span style="color: hsl(120, 100%, 40%);">+static uint32_t gprs_bssgp_max_leak_rate(CodingScheme cs, int num_pdch)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      int bytes_per_rlc_block = cs.maxDataBlockBytes() * num_data_blocks(cs.headerTypeData());</span><br><span style="color: hsl(120, 100%, 40%);">+      int bytes_per_rlc_block = mcs_max_data_block_bytes(cs) * num_data_blocks(mcs_header_type(cs));</span><br><span> </span><br><span>   /* n byte payload per 20ms */</span><br><span>        return bytes_per_rlc_block * (1000 / 20) * num_pdch;</span><br><span>@@ -717,7 +717,7 @@</span><br><span>   return rate;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static GprsCodingScheme max_coding_scheme_dl(struct gprs_rlcmac_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+static CodingScheme max_coding_scheme_dl(struct gprs_rlcmac_bts *bts)</span><br><span> {</span><br><span>   int num;</span><br><span> </span><br><span>@@ -733,7 +733,7 @@</span><br><span>                   num = 9;</span><br><span>             }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-           return GprsCodingScheme::getEgprsByNum(num);</span><br><span style="color: hsl(120, 100%, 40%);">+          return mcs_get_egprs_by_num(num);</span><br><span>    }</span><br><span> </span><br><span>        if (!bts->cs_adj_enabled) {</span><br><span>@@ -753,7 +753,7 @@</span><br><span>                 num = 4;</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   return GprsCodingScheme::getGprsByNum(num);</span><br><span style="color: hsl(120, 100%, 40%);">+   return mcs_get_gprs_by_num(num);</span><br><span> }</span><br><span> </span><br><span> static int gprs_bssgp_tx_fc_bvc(void)</span><br><span>@@ -765,7 +765,7 @@</span><br><span>     uint32_t ms_leak_rate; /* oct/s */</span><br><span>   uint32_t avg_delay_ms;</span><br><span>       int num_pdch = -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      GprsCodingScheme max_cs_dl;</span><br><span style="color: hsl(120, 100%, 40%);">+   CodingScheme max_cs_dl;</span><br><span> </span><br><span>  if (!the_pcu.bctx) {</span><br><span>                 LOGP(DBSSGP, LOGL_ERROR, "No bctx\n");</span><br><span>diff --git a/src/gprs_coding_scheme.cpp b/src/gprs_coding_scheme.cpp</span><br><span>deleted file mode 100644</span><br><span>index 0c22670..0000000</span><br><span>--- a/src/gprs_coding_scheme.cpp</span><br><span>+++ /dev/null</span><br><span>@@ -1,231 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/* gprs_coding_scheme.cpp</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * Copyright (C) 2015 by Sysmocom s.f.m.c. GmbH</span><br><span style="color: hsl(0, 100%, 40%);">- * Author: Jacob Erlbeck <jerlbeck@sysmocom.de></span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is free software; you can redistribute it and/or</span><br><span style="color: hsl(0, 100%, 40%);">- * modify it under the terms of the GNU General Public License</span><br><span style="color: hsl(0, 100%, 40%);">- * as published by the Free Software Foundation; either version 2</span><br><span style="color: hsl(0, 100%, 40%);">- * of the License, or (at your option) any later version.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(0, 100%, 40%);">- * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(0, 100%, 40%);">- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(0, 100%, 40%);">- * GNU General Public License for more details.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * You should have received a copy of the GNU General Public License</span><br><span style="color: hsl(0, 100%, 40%);">- * along with this program; if not, write to the Free Software</span><br><span style="color: hsl(0, 100%, 40%);">- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.</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%);">-#include "gprs_coding_scheme.h"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-enum Family {</span><br><span style="color: hsl(0, 100%, 40%);">-      FAMILY_INVALID,</span><br><span style="color: hsl(0, 100%, 40%);">- FAMILY_A,</span><br><span style="color: hsl(0, 100%, 40%);">-       FAMILY_B,</span><br><span style="color: hsl(0, 100%, 40%);">-       FAMILY_C,</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%);">-static struct {</span><br><span style="color: hsl(0, 100%, 40%);">-      struct {</span><br><span style="color: hsl(0, 100%, 40%);">-                uint8_t bytes;</span><br><span style="color: hsl(0, 100%, 40%);">-          uint8_t ext_bits;</span><br><span style="color: hsl(0, 100%, 40%);">-               uint8_t data_header_bits;</span><br><span style="color: hsl(0, 100%, 40%);">-       } uplink, downlink;</span><br><span style="color: hsl(0, 100%, 40%);">-     uint8_t data_bytes;</span><br><span style="color: hsl(0, 100%, 40%);">-     uint8_t optional_padding_bits;</span><br><span style="color: hsl(0, 100%, 40%);">-  enum HeaderType data_hdr;</span><br><span style="color: hsl(0, 100%, 40%);">-       enum Family family;</span><br><span style="color: hsl(0, 100%, 40%);">-} mcs_info[NUM_SCHEMES] = {</span><br><span style="color: hsl(0, 100%, 40%);">-  {{0, 0},   {0, 0},    0,  0,</span><br><span style="color: hsl(0, 100%, 40%);">-            HEADER_INVALID, FAMILY_INVALID},</span><br><span style="color: hsl(0, 100%, 40%);">-        {{23, 0},  {23, 0},  20,  0,</span><br><span style="color: hsl(0, 100%, 40%);">-            HEADER_GPRS_DATA, FAMILY_INVALID},</span><br><span style="color: hsl(0, 100%, 40%);">-      {{33, 7},  {33, 7},  30,  0,</span><br><span style="color: hsl(0, 100%, 40%);">-            HEADER_GPRS_DATA, FAMILY_INVALID},</span><br><span style="color: hsl(0, 100%, 40%);">-      {{39, 3},  {39, 3},  36,  0,</span><br><span style="color: hsl(0, 100%, 40%);">-            HEADER_GPRS_DATA, FAMILY_INVALID},</span><br><span style="color: hsl(0, 100%, 40%);">-      {{53, 7},  {53, 7},  50,  0,</span><br><span style="color: hsl(0, 100%, 40%);">-            HEADER_GPRS_DATA, FAMILY_INVALID},</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      {{26, 1},  {26, 1},  22,  0,</span><br><span style="color: hsl(0, 100%, 40%);">-            HEADER_EGPRS_DATA_TYPE_3, FAMILY_C},</span><br><span style="color: hsl(0, 100%, 40%);">-    {{32, 1},  {32, 1},  28,  0,</span><br><span style="color: hsl(0, 100%, 40%);">-            HEADER_EGPRS_DATA_TYPE_3, FAMILY_B},</span><br><span style="color: hsl(0, 100%, 40%);">-    {{41, 1},  {41, 1},  37, 48,</span><br><span style="color: hsl(0, 100%, 40%);">-            HEADER_EGPRS_DATA_TYPE_3, FAMILY_A},</span><br><span style="color: hsl(0, 100%, 40%);">-    {{48, 1},  {48, 1},  44,  0,</span><br><span style="color: hsl(0, 100%, 40%);">-            HEADER_EGPRS_DATA_TYPE_3, FAMILY_C},</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    {{60, 7},  {59, 6},  56,  0,</span><br><span style="color: hsl(0, 100%, 40%);">-            HEADER_EGPRS_DATA_TYPE_2, FAMILY_B},</span><br><span style="color: hsl(0, 100%, 40%);">-    {{78, 7},  {77, 6},  74, 48,</span><br><span style="color: hsl(0, 100%, 40%);">-            HEADER_EGPRS_DATA_TYPE_2, FAMILY_A},</span><br><span style="color: hsl(0, 100%, 40%);">-    {{118, 2}, {117, 4}, 56,  0,</span><br><span style="color: hsl(0, 100%, 40%);">-            HEADER_EGPRS_DATA_TYPE_1, FAMILY_B},</span><br><span style="color: hsl(0, 100%, 40%);">-    {{142, 2}, {141, 4}, 68,  0,</span><br><span style="color: hsl(0, 100%, 40%);">-            HEADER_EGPRS_DATA_TYPE_1, FAMILY_A},</span><br><span style="color: hsl(0, 100%, 40%);">-    {{154, 2}, {153, 4}, 74,  0,</span><br><span style="color: hsl(0, 100%, 40%);">-            HEADER_EGPRS_DATA_TYPE_1, FAMILY_A},</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%);">-GprsCodingScheme GprsCodingScheme::getBySizeUL(unsigned size)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    switch (size) {</span><br><span style="color: hsl(0, 100%, 40%);">-         case 23: return GprsCodingScheme(CS1);</span><br><span style="color: hsl(0, 100%, 40%);">-          case 27: return GprsCodingScheme(MCS1);</span><br><span style="color: hsl(0, 100%, 40%);">-         case 33: return GprsCodingScheme(MCS2);</span><br><span style="color: hsl(0, 100%, 40%);">-         case 34: return GprsCodingScheme(CS2);</span><br><span style="color: hsl(0, 100%, 40%);">-          case 40: return GprsCodingScheme(CS3);</span><br><span style="color: hsl(0, 100%, 40%);">-          case 42: return GprsCodingScheme(MCS3);</span><br><span style="color: hsl(0, 100%, 40%);">-         case 49: return GprsCodingScheme(MCS4);</span><br><span style="color: hsl(0, 100%, 40%);">-         case 54: return GprsCodingScheme(CS4);</span><br><span style="color: hsl(0, 100%, 40%);">-          case 61: return GprsCodingScheme(MCS5);</span><br><span style="color: hsl(0, 100%, 40%);">-         case 79: return GprsCodingScheme(MCS6);</span><br><span style="color: hsl(0, 100%, 40%);">-         case 119: return GprsCodingScheme(MCS7);</span><br><span style="color: hsl(0, 100%, 40%);">-                case 143: return GprsCodingScheme(MCS8);</span><br><span style="color: hsl(0, 100%, 40%);">-                case 155: return GprsCodingScheme(MCS9);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return GprsCodingScheme(UNKNOWN);</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%);">-uint8_t GprsCodingScheme::sizeUL() const</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     return mcs_info[m_scheme].uplink.bytes + (spareBitsUL() ? 1 : 0);</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%);">-uint8_t GprsCodingScheme::usedSizeUL() const</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- if (mcs_info[m_scheme].data_hdr == HEADER_GPRS_DATA)</span><br><span style="color: hsl(0, 100%, 40%);">-            return mcs_info[m_scheme].uplink.bytes;</span><br><span style="color: hsl(0, 100%, 40%);">- else</span><br><span style="color: hsl(0, 100%, 40%);">-            return sizeUL();</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%);">-uint8_t GprsCodingScheme::maxBytesUL() const</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  return mcs_info[m_scheme].uplink.bytes;</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%);">-uint8_t GprsCodingScheme::spareBitsUL() const</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  return mcs_info[m_scheme].uplink.ext_bits;</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%);">-uint8_t GprsCodingScheme::sizeDL() const</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    return mcs_info[m_scheme].downlink.bytes + (spareBitsDL() ? 1 : 0);</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%);">-uint8_t GprsCodingScheme::usedSizeDL() const</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       if (mcs_info[m_scheme].data_hdr == HEADER_GPRS_DATA)</span><br><span style="color: hsl(0, 100%, 40%);">-            return mcs_info[m_scheme].downlink.bytes;</span><br><span style="color: hsl(0, 100%, 40%);">-       else</span><br><span style="color: hsl(0, 100%, 40%);">-            return sizeDL();</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%);">-uint8_t GprsCodingScheme::maxBytesDL() const</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  return mcs_info[m_scheme].downlink.bytes;</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%);">-uint8_t GprsCodingScheme::spareBitsDL() const</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        return mcs_info[m_scheme].downlink.ext_bits;</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%);">-uint8_t GprsCodingScheme::maxDataBlockBytes() const</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       return mcs_info[m_scheme].data_bytes;</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%);">-uint8_t GprsCodingScheme::optionalPaddingBits() const</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    return mcs_info[m_scheme].optional_padding_bits;</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%);">-enum HeaderType GprsCodingScheme::headerTypeData() const</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      return mcs_info[m_scheme].data_hdr;</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%);">-void GprsCodingScheme::inc(enum mcs_kind mode)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     if (!isCompatible(mode))</span><br><span style="color: hsl(0, 100%, 40%);">-                /* This should not happen. TODO: Use assert? */</span><br><span style="color: hsl(0, 100%, 40%);">-         return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- CodingScheme new_cs(CodingScheme(m_scheme + 1));</span><br><span style="color: hsl(0, 100%, 40%);">-        if (!GprsCodingScheme(new_cs).isCompatible(mode))</span><br><span style="color: hsl(0, 100%, 40%);">-               /* Clipping, do not change the value */</span><br><span style="color: hsl(0, 100%, 40%);">-         return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- m_scheme = new_cs;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void GprsCodingScheme::dec(enum mcs_kind mode)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      if (!isCompatible(mode))</span><br><span style="color: hsl(0, 100%, 40%);">-                /* This should not happen. TODO: Use assert? */</span><br><span style="color: hsl(0, 100%, 40%);">-         return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- CodingScheme new_cs(CodingScheme(m_scheme - 1));</span><br><span style="color: hsl(0, 100%, 40%);">-        if (!GprsCodingScheme(new_cs).isCompatible(mode))</span><br><span style="color: hsl(0, 100%, 40%);">-               /* Clipping, do not change the value */</span><br><span style="color: hsl(0, 100%, 40%);">-         return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- m_scheme = new_cs;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void GprsCodingScheme::inc()</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        if (mcs_is_gprs(m_scheme) && m_scheme == CS4)</span><br><span style="color: hsl(0, 100%, 40%);">-           return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (mcs_is_edge(m_scheme) && m_scheme == MCS9)</span><br><span style="color: hsl(0, 100%, 40%);">-          return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!isValid())</span><br><span style="color: hsl(0, 100%, 40%);">-         return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- m_scheme = CodingScheme(m_scheme + 1);</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%);">-void GprsCodingScheme::dec()</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    if (mcs_is_gprs(m_scheme) && m_scheme == CS1)</span><br><span style="color: hsl(0, 100%, 40%);">-           return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (mcs_is_edge(m_scheme) && m_scheme == MCS1)</span><br><span style="color: hsl(0, 100%, 40%);">-          return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!isValid())</span><br><span style="color: hsl(0, 100%, 40%);">-         return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- m_scheme = CodingScheme(m_scheme - 1);</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%);">-bool GprsCodingScheme::isFamilyCompatible(GprsCodingScheme o) const</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     if (*this == o)</span><br><span style="color: hsl(0, 100%, 40%);">-         return true;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    if (mcs_info[m_scheme].family == FAMILY_INVALID)</span><br><span style="color: hsl(0, 100%, 40%);">-                return false;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   return mcs_info[m_scheme].family == mcs_info[o.m_scheme].family;</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%);">-void GprsCodingScheme::decToSingleBlock(bool *needStuffing)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   switch (m_scheme) {</span><br><span style="color: hsl(0, 100%, 40%);">-     case MCS7: *needStuffing = false; m_scheme = MCS5; break;</span><br><span style="color: hsl(0, 100%, 40%);">-       case MCS8: *needStuffing =  true; m_scheme = MCS6; break;</span><br><span style="color: hsl(0, 100%, 40%);">-       case MCS9: *needStuffing = false; m_scheme = MCS6; break;</span><br><span style="color: hsl(0, 100%, 40%);">-       default:   *needStuffing = false; break;</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span>diff --git a/src/gprs_coding_scheme.h b/src/gprs_coding_scheme.h</span><br><span>deleted file mode 100644</span><br><span>index c31f58f..0000000</span><br><span>--- a/src/gprs_coding_scheme.h</span><br><span>+++ /dev/null</span><br><span>@@ -1,163 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/* gprs_coding_scheme.h</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * Copyright (C) 2015 by Sysmocom s.f.m.c. GmbH</span><br><span style="color: hsl(0, 100%, 40%);">- * Author: Jacob Erlbeck <jerlbeck@sysmocom.de></span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is free software; you can redistribute it and/or</span><br><span style="color: hsl(0, 100%, 40%);">- * modify it under the terms of the GNU General Public License</span><br><span style="color: hsl(0, 100%, 40%);">- * as published by the Free Software Foundation; either version 2</span><br><span style="color: hsl(0, 100%, 40%);">- * of the License, or (at your option) any later version.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(0, 100%, 40%);">- * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(0, 100%, 40%);">- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(0, 100%, 40%);">- * GNU General Public License for more details.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * You should have received a copy of the GNU General Public License</span><br><span style="color: hsl(0, 100%, 40%);">- * along with this program; if not, write to the Free Software</span><br><span style="color: hsl(0, 100%, 40%);">- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.</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%);">-#pragma once</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <stdint.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <stddef.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-extern "C" {</span><br><span style="color: hsl(0, 100%, 40%);">-      #include <osmocom/core/utils.h></span><br><span style="color: hsl(0, 100%, 40%);">-   #include "coding_scheme.h"</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%);">-class GprsCodingScheme {</span><br><span style="color: hsl(0, 100%, 40%);">-public:</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define EGPRS_ARQ1            0x0</span><br><span style="color: hsl(0, 100%, 40%);">-#define EGPRS_ARQ2            0x1</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  GprsCodingScheme(CodingScheme s = UNKNOWN);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     operator bool() const {return m_scheme != UNKNOWN;}</span><br><span style="color: hsl(0, 100%, 40%);">-     operator CodingScheme() const {return m_scheme;}</span><br><span style="color: hsl(0, 100%, 40%);">-        uint8_t to_num() const;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- GprsCodingScheme& operator =(CodingScheme s);</span><br><span style="color: hsl(0, 100%, 40%);">-       bool operator == (CodingScheme s) const;</span><br><span style="color: hsl(0, 100%, 40%);">-        GprsCodingScheme& operator =(GprsCodingScheme o);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   bool isValid()   const {return UNKNOWN <= m_scheme && m_scheme <= MCS9;}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  bool isCompatible(enum mcs_kind mode) const;</span><br><span style="color: hsl(0, 100%, 40%);">-    bool isCompatible(GprsCodingScheme o) const;</span><br><span style="color: hsl(0, 100%, 40%);">-    bool isFamilyCompatible(GprsCodingScheme o) const;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      void inc(enum mcs_kind mode);</span><br><span style="color: hsl(0, 100%, 40%);">-   void dec(enum mcs_kind mode);</span><br><span style="color: hsl(0, 100%, 40%);">-   void inc();</span><br><span style="color: hsl(0, 100%, 40%);">-     void dec();</span><br><span style="color: hsl(0, 100%, 40%);">-     void decToSingleBlock(bool *needStuffing);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      uint8_t sizeUL() const;</span><br><span style="color: hsl(0, 100%, 40%);">- uint8_t sizeDL() const;</span><br><span style="color: hsl(0, 100%, 40%);">- uint8_t usedSizeUL() const;</span><br><span style="color: hsl(0, 100%, 40%);">-     uint8_t usedSizeDL() const;</span><br><span style="color: hsl(0, 100%, 40%);">-     uint8_t maxBytesUL() const;</span><br><span style="color: hsl(0, 100%, 40%);">-     uint8_t maxBytesDL() const;</span><br><span style="color: hsl(0, 100%, 40%);">-     uint8_t spareBitsUL() const;</span><br><span style="color: hsl(0, 100%, 40%);">-    uint8_t spareBitsDL() const;</span><br><span style="color: hsl(0, 100%, 40%);">-    uint8_t maxDataBlockBytes() const;</span><br><span style="color: hsl(0, 100%, 40%);">-      uint8_t optionalPaddingBits() const;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    enum HeaderType headerTypeData() const;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- static GprsCodingScheme getBySizeUL(unsigned size);</span><br><span style="color: hsl(0, 100%, 40%);">-     static GprsCodingScheme getGprsByNum(unsigned num);</span><br><span style="color: hsl(0, 100%, 40%);">-     static GprsCodingScheme getEgprsByNum(unsigned num);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-private:</span><br><span style="color: hsl(0, 100%, 40%);">-    GprsCodingScheme(int s); /* fail on use */</span><br><span style="color: hsl(0, 100%, 40%);">-      GprsCodingScheme& operator =(int s); /* fail on use */</span><br><span style="color: hsl(0, 100%, 40%);">-      enum CodingScheme m_scheme;</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%);">-// FIXME: remove once < comparison operator below is no longer necessary</span><br><span style="color: hsl(0, 100%, 40%);">-inline uint8_t GprsCodingScheme::to_num() const</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        if (mcs_is_gprs(m_scheme))</span><br><span style="color: hsl(0, 100%, 40%);">-              return (m_scheme - CS1) + 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    if (mcs_is_edge(m_scheme))</span><br><span style="color: hsl(0, 100%, 40%);">-              return (m_scheme - MCS1) + 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   return 0;</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%);">-inline bool GprsCodingScheme::isCompatible(enum mcs_kind mode) const</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- switch (mode) {</span><br><span style="color: hsl(0, 100%, 40%);">- case GPRS: return mcs_is_gprs(m_scheme);</span><br><span style="color: hsl(0, 100%, 40%);">-        case EGPRS_GMSK: return mcs_is_edge_gmsk(m_scheme);</span><br><span style="color: hsl(0, 100%, 40%);">-     case EGPRS: return mcs_is_edge(m_scheme);</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return false;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-inline bool GprsCodingScheme::isCompatible(GprsCodingScheme o) const</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     return (mcs_is_gprs(m_scheme) && mcs_is_gprs(o)) || (mcs_is_edge(m_scheme) && mcs_is_edge(o));</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%);">-inline GprsCodingScheme::GprsCodingScheme(CodingScheme s)</span><br><span style="color: hsl(0, 100%, 40%);">-        : m_scheme(s)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  if (!isValid())</span><br><span style="color: hsl(0, 100%, 40%);">-         m_scheme = UNKNOWN;</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%);">-inline GprsCodingScheme& GprsCodingScheme::operator =(CodingScheme s)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  m_scheme = s;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!isValid())</span><br><span style="color: hsl(0, 100%, 40%);">-         m_scheme = UNKNOWN;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     return *this;</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%);">-inline GprsCodingScheme& GprsCodingScheme::operator =(GprsCodingScheme o)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    m_scheme = o.m_scheme;</span><br><span style="color: hsl(0, 100%, 40%);">-  return *this;</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%);">-inline GprsCodingScheme GprsCodingScheme::getGprsByNum(unsigned num)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     if (num < 1 || num > 4)</span><br><span style="color: hsl(0, 100%, 40%);">-           return GprsCodingScheme();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      return GprsCodingScheme(CodingScheme(CS1 + (num - 1)));</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%);">-inline GprsCodingScheme GprsCodingScheme::getEgprsByNum(unsigned num)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  if (num < 1 || num > 9)</span><br><span style="color: hsl(0, 100%, 40%);">-           return GprsCodingScheme();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      return GprsCodingScheme(CodingScheme(MCS1 + (num - 1)));</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%);">-/* The coding schemes form a partial ordering */</span><br><span style="color: hsl(0, 100%, 40%);">-inline bool GprsCodingScheme::operator == (CodingScheme scheme) const</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- return this->m_scheme == scheme;</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%);">-inline bool operator !=(GprsCodingScheme a, GprsCodingScheme b)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    return !(a == b);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-inline bool operator <(GprsCodingScheme a, GprsCodingScheme b)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    return a.isCompatible(b) && a.to_num() < b.to_num();</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span>diff --git a/src/gprs_ms.cpp b/src/gprs_ms.cpp</span><br><span>index 102f558..68d7640 100644</span><br><span>--- a/src/gprs_ms.cpp</span><br><span>+++ b/src/gprs_ms.cpp</span><br><span>@@ -20,7 +20,6 @@</span><br><span> </span><br><span> </span><br><span> #include "gprs_ms.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include <gprs_coding_scheme.h></span><br><span> #include "bts.h"</span><br><span> #include "tbf.h"</span><br><span> #include "tbf_ul.h"</span><br><span>@@ -103,6 +102,8 @@</span><br><span>      m_ta(GSM48_TA_INVALID),</span><br><span>      m_ms_class(0),</span><br><span>       m_egprs_ms_class(0),</span><br><span style="color: hsl(120, 100%, 40%);">+  m_current_cs_ul(UNKNOWN),</span><br><span style="color: hsl(120, 100%, 40%);">+     m_current_cs_dl(UNKNOWN),</span><br><span>    m_is_idle(true),</span><br><span>     m_ref(0),</span><br><span>    m_list(this),</span><br><span>@@ -226,15 +227,15 @@</span><br><span>        switch (m_mode) {</span><br><span>    case GPRS:</span><br><span>           if (!mcs_is_gprs(m_current_cs_ul)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    m_current_cs_ul = GprsCodingScheme::getGprsByNum(</span><br><span style="color: hsl(120, 100%, 40%);">+                     m_current_cs_ul = mcs_get_gprs_by_num(</span><br><span>                               m_bts->bts_data()->initial_cs_ul);</span><br><span style="color: hsl(0, 100%, 40%);">-                        if (!m_current_cs_ul.isValid())</span><br><span style="color: hsl(120, 100%, 40%);">+                       if (!mcs_is_valid(m_current_cs_ul))</span><br><span>                          m_current_cs_ul = CS1;</span><br><span>               }</span><br><span>            if (!mcs_is_gprs(m_current_cs_dl)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    m_current_cs_dl = GprsCodingScheme::getGprsByNum(</span><br><span style="color: hsl(120, 100%, 40%);">+                     m_current_cs_dl = mcs_get_gprs_by_num(</span><br><span>                               m_bts->bts_data()->initial_cs_dl);</span><br><span style="color: hsl(0, 100%, 40%);">-                        if (!m_current_cs_dl.isValid())</span><br><span style="color: hsl(120, 100%, 40%);">+                       if (!mcs_is_valid(m_current_cs_dl))</span><br><span>                          m_current_cs_dl = CS1;</span><br><span>               }</span><br><span>            break;</span><br><span>@@ -242,15 +243,15 @@</span><br><span>       case EGPRS_GMSK:</span><br><span>     case EGPRS:</span><br><span>          if (!mcs_is_edge(m_current_cs_ul)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    m_current_cs_ul = GprsCodingScheme::getEgprsByNum(</span><br><span style="color: hsl(120, 100%, 40%);">+                    m_current_cs_ul = mcs_get_egprs_by_num(</span><br><span>                              m_bts->bts_data()->initial_mcs_ul);</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (!m_current_cs_ul.isValid())</span><br><span style="color: hsl(120, 100%, 40%);">+                       if (!mcs_is_valid(m_current_cs_ul))</span><br><span>                          m_current_cs_ul = MCS1;</span><br><span>              }</span><br><span>            if (!mcs_is_edge(m_current_cs_dl)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    m_current_cs_dl = GprsCodingScheme::getEgprsByNum(</span><br><span style="color: hsl(120, 100%, 40%);">+                    m_current_cs_dl = mcs_get_egprs_by_num(</span><br><span>                              m_bts->bts_data()->initial_mcs_dl);</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (!m_current_cs_dl.isValid())</span><br><span style="color: hsl(120, 100%, 40%);">+                       if (!mcs_is_valid(m_current_cs_dl))</span><br><span>                          m_current_cs_dl = MCS1;</span><br><span>              }</span><br><span>            break;</span><br><span>@@ -510,7 +511,7 @@</span><br><span> {</span><br><span>    struct gprs_rlcmac_bts *bts_data;</span><br><span>    int64_t now;</span><br><span style="color: hsl(0, 100%, 40%);">-    GprsCodingScheme max_cs_dl = this->max_cs_dl();</span><br><span style="color: hsl(120, 100%, 40%);">+    CodingScheme max_cs_dl = this->max_cs_dl();</span><br><span> </span><br><span>   OSMO_ASSERT(max_cs_dl);</span><br><span>      bts_data = m_bts->bts_data();</span><br><span>@@ -527,7 +528,7 @@</span><br><span> </span><br><span>   if (error_rate > bts_data->cs_adj_upper_limit) {</span><br><span>               if (mcs_chan_code(m_current_cs_dl) > 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    m_current_cs_dl.dec(mode());</span><br><span style="color: hsl(120, 100%, 40%);">+                  mcs_dec_kind(&m_current_cs_dl, mode());</span><br><span>                  LOGP(DRLCMACDL, LOGL_INFO,</span><br><span>                           "MS (IMSI %s): High error rate %d%%, "</span><br><span>                             "reducing CS level to %s\n",</span><br><span>@@ -537,7 +538,7 @@</span><br><span>         } else if (error_rate < bts_data->cs_adj_lower_limit) {</span><br><span>                if (m_current_cs_dl < max_cs_dl) {</span><br><span>                       if (now - m_last_cs_not_low > 1000) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        m_current_cs_dl.inc(mode());</span><br><span style="color: hsl(120, 100%, 40%);">+                          mcs_inc_kind(&m_current_cs_dl, mode());</span><br><span> </span><br><span>                              LOGP(DRLCMACDL, LOGL_INFO,</span><br><span>                                   "MS (IMSI %s): Low error rate %d%%, "</span><br><span>@@ -560,7 +561,7 @@</span><br><span>         }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-GprsCodingScheme GprsMs::max_cs_ul() const</span><br><span style="color: hsl(120, 100%, 40%);">+CodingScheme GprsMs::max_cs_ul() const</span><br><span> {</span><br><span>    struct gprs_rlcmac_bts *bts_data;</span><br><span> </span><br><span>@@ -568,21 +569,22 @@</span><br><span>        bts_data = m_bts->bts_data();</span><br><span> </span><br><span>         if (mcs_is_gprs(m_current_cs_ul)) {</span><br><span style="color: hsl(0, 100%, 40%);">-             if (!bts_data->max_cs_ul)</span><br><span style="color: hsl(0, 100%, 40%);">-                    return GprsCodingScheme(CS4);</span><br><span style="color: hsl(120, 100%, 40%);">+         if (!bts_data->max_cs_ul) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        return CS4;</span><br><span style="color: hsl(120, 100%, 40%);">+           }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-           return GprsCodingScheme::getGprsByNum(bts_data->max_cs_ul);</span><br><span style="color: hsl(120, 100%, 40%);">+                return mcs_get_gprs_by_num(bts_data->max_cs_ul);</span><br><span>  }</span><br><span> </span><br><span>        if (!mcs_is_edge(m_current_cs_ul))</span><br><span style="color: hsl(0, 100%, 40%);">-              return GprsCodingScheme(); /* UNKNOWN */</span><br><span style="color: hsl(120, 100%, 40%);">+              return UNKNOWN;</span><br><span> </span><br><span>  if (bts_data->max_mcs_ul)</span><br><span style="color: hsl(0, 100%, 40%);">-            return GprsCodingScheme::getEgprsByNum(bts_data->max_mcs_ul);</span><br><span style="color: hsl(120, 100%, 40%);">+              return mcs_get_egprs_by_num(bts_data->max_mcs_ul);</span><br><span>        else if (bts_data->max_cs_ul)</span><br><span style="color: hsl(0, 100%, 40%);">-                return GprsCodingScheme::getEgprsByNum(bts_data->max_cs_ul);</span><br><span style="color: hsl(120, 100%, 40%);">+               return mcs_get_egprs_by_num(bts_data->max_cs_ul);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        return GprsCodingScheme(MCS4);</span><br><span style="color: hsl(120, 100%, 40%);">+        return MCS4;</span><br><span> }</span><br><span> </span><br><span> void GprsMs::set_current_cs_dl(CodingScheme scheme)</span><br><span>@@ -590,7 +592,7 @@</span><br><span>   m_current_cs_dl = scheme;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-GprsCodingScheme GprsMs::max_cs_dl() const</span><br><span style="color: hsl(120, 100%, 40%);">+CodingScheme GprsMs::max_cs_dl() const</span><br><span> {</span><br><span>    struct gprs_rlcmac_bts *bts_data;</span><br><span> </span><br><span>@@ -598,32 +600,33 @@</span><br><span>        bts_data = m_bts->bts_data();</span><br><span> </span><br><span>         if (mcs_is_gprs(m_current_cs_dl)) {</span><br><span style="color: hsl(0, 100%, 40%);">-             if (!bts_data->max_cs_dl)</span><br><span style="color: hsl(0, 100%, 40%);">-                    return GprsCodingScheme(CS4);</span><br><span style="color: hsl(120, 100%, 40%);">+         if (!bts_data->max_cs_dl) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        return CS4;</span><br><span style="color: hsl(120, 100%, 40%);">+           }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-           return GprsCodingScheme::getGprsByNum(bts_data->max_cs_dl);</span><br><span style="color: hsl(120, 100%, 40%);">+                return mcs_get_gprs_by_num(bts_data->max_cs_dl);</span><br><span>  }</span><br><span> </span><br><span>        if (!mcs_is_edge(m_current_cs_dl))</span><br><span style="color: hsl(0, 100%, 40%);">-              return GprsCodingScheme(); /* UNKNOWN */</span><br><span style="color: hsl(120, 100%, 40%);">+              return CodingScheme(); /* UNKNOWN */</span><br><span> </span><br><span>     if (bts_data->max_mcs_dl)</span><br><span style="color: hsl(0, 100%, 40%);">-            return GprsCodingScheme::getEgprsByNum(bts_data->max_mcs_dl);</span><br><span style="color: hsl(120, 100%, 40%);">+              return mcs_get_egprs_by_num(bts_data->max_mcs_dl);</span><br><span>        else if (bts_data->max_cs_dl)</span><br><span style="color: hsl(0, 100%, 40%);">-                return GprsCodingScheme::getEgprsByNum(bts_data->max_cs_dl);</span><br><span style="color: hsl(120, 100%, 40%);">+               return mcs_get_egprs_by_num(bts_data->max_cs_dl);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        return GprsCodingScheme(MCS4);</span><br><span style="color: hsl(120, 100%, 40%);">+        return MCS4;</span><br><span> }</span><br><span> </span><br><span> void GprsMs::update_cs_ul(const pcu_l1_meas *meas)</span><br><span> {</span><br><span>     struct gprs_rlcmac_bts *bts_data;</span><br><span style="color: hsl(0, 100%, 40%);">-       GprsCodingScheme max_cs_ul = this->max_cs_ul();</span><br><span style="color: hsl(120, 100%, 40%);">+    CodingScheme max_cs_ul = this->max_cs_ul();</span><br><span> </span><br><span>   int old_link_qual;</span><br><span>   int low;</span><br><span>     int high;</span><br><span style="color: hsl(0, 100%, 40%);">-       GprsCodingScheme new_cs_ul = m_current_cs_ul;</span><br><span style="color: hsl(120, 100%, 40%);">+ CodingScheme new_cs_ul = m_current_cs_ul;</span><br><span>    uint8_t current_cs = mcs_chan_code(m_current_cs_ul);</span><br><span> </span><br><span>     bts_data = m_bts->bts_data();</span><br><span>@@ -674,10 +677,10 @@</span><br><span>             old_link_qual = meas->link_qual;</span><br><span> </span><br><span>      if (meas->link_qual < low &&  old_link_qual < low)</span><br><span style="color: hsl(0, 100%, 40%);">-             new_cs_ul.dec(mode());</span><br><span style="color: hsl(120, 100%, 40%);">+                mcs_dec_kind(&new_cs_ul, mode());</span><br><span>        else if (meas->link_qual > high &&  old_link_qual > high &&</span><br><span>                 m_current_cs_ul < max_cs_ul)</span><br><span style="color: hsl(0, 100%, 40%);">-         new_cs_ul.inc(mode());</span><br><span style="color: hsl(120, 100%, 40%);">+                mcs_inc_kind(&new_cs_ul, mode());</span><br><span> </span><br><span>    if (m_current_cs_ul != new_cs_ul) {</span><br><span>          LOGP(DRLCMACMEAS, LOGL_INFO,</span><br><span>@@ -724,9 +727,9 @@</span><br><span>   }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-GprsCodingScheme GprsMs::current_cs_dl() const</span><br><span style="color: hsl(120, 100%, 40%);">+CodingScheme GprsMs::current_cs_dl() const</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-       GprsCodingScheme cs = m_current_cs_dl;</span><br><span style="color: hsl(120, 100%, 40%);">+        CodingScheme cs = m_current_cs_dl;</span><br><span>   size_t unencoded_octets;</span><br><span> </span><br><span>         if (!m_bts)</span><br><span>@@ -747,11 +750,11 @@</span><br><span>          return cs;</span><br><span> </span><br><span>       /* The throughput would probably be better if the CS level was reduced */</span><br><span style="color: hsl(0, 100%, 40%);">-       cs.dec(mode());</span><br><span style="color: hsl(120, 100%, 40%);">+       mcs_dec_kind(&cs, mode());</span><br><span> </span><br><span>   /* CS-2 doesn't gain throughput with small packets, further reduce to CS-1 */</span><br><span style="color: hsl(0, 100%, 40%);">-       if (cs == GprsCodingScheme(CS2))</span><br><span style="color: hsl(0, 100%, 40%);">-                cs.dec(mode());</span><br><span style="color: hsl(120, 100%, 40%);">+       if (cs == CS2)</span><br><span style="color: hsl(120, 100%, 40%);">+                mcs_dec_kind(&cs, mode());</span><br><span> </span><br><span>   return cs;</span><br><span> }</span><br><span>diff --git a/src/gprs_ms.h b/src/gprs_ms.h</span><br><span>index 688708e..8836204 100644</span><br><span>--- a/src/gprs_ms.h</span><br><span>+++ b/src/gprs_ms.h</span><br><span>@@ -22,17 +22,17 @@</span><br><span> </span><br><span> struct gprs_codel;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#include <gprs_coding_scheme.h></span><br><span> #include "cxx_linuxlist.h"</span><br><span> #include "llc.h"</span><br><span> #include "tbf.h"</span><br><span> #include "tbf_dl.h"</span><br><span> #include "pcu_l1_if.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include <gprs_coding_scheme.h></span><br><span> </span><br><span> extern "C" {</span><br><span>        #include <osmocom/core/timer.h></span><br><span>        #include <osmocom/core/linuxlist.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   #include "coding_scheme.h"</span><br><span> }</span><br><span> </span><br><span> #include <stdint.h></span><br><span>@@ -89,10 +89,10 @@</span><br><span>     void set_egprs_ms_class(uint8_t ms_class);</span><br><span>   void set_current_cs_dl(CodingScheme scheme);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        GprsCodingScheme current_cs_ul() const;</span><br><span style="color: hsl(0, 100%, 40%);">- GprsCodingScheme current_cs_dl() const;</span><br><span style="color: hsl(0, 100%, 40%);">- GprsCodingScheme max_cs_ul() const;</span><br><span style="color: hsl(0, 100%, 40%);">-     GprsCodingScheme max_cs_dl() const;</span><br><span style="color: hsl(120, 100%, 40%);">+   CodingScheme current_cs_ul() const;</span><br><span style="color: hsl(120, 100%, 40%);">+   CodingScheme current_cs_dl() const;</span><br><span style="color: hsl(120, 100%, 40%);">+   CodingScheme max_cs_ul() const;</span><br><span style="color: hsl(120, 100%, 40%);">+       CodingScheme max_cs_dl() const;</span><br><span> </span><br><span>  int first_common_ts() const;</span><br><span>         uint8_t dl_slots() const;</span><br><span>@@ -164,8 +164,8 @@</span><br><span>      uint8_t m_ms_class;</span><br><span>  uint8_t m_egprs_ms_class;</span><br><span>    /* current coding scheme */</span><br><span style="color: hsl(0, 100%, 40%);">-     GprsCodingScheme m_current_cs_ul;</span><br><span style="color: hsl(0, 100%, 40%);">-       GprsCodingScheme m_current_cs_dl;</span><br><span style="color: hsl(120, 100%, 40%);">+     CodingScheme m_current_cs_ul;</span><br><span style="color: hsl(120, 100%, 40%);">+ CodingScheme m_current_cs_dl;</span><br><span> </span><br><span>    gprs_llc_queue m_llc_queue;</span><br><span> </span><br><span>@@ -235,7 +235,7 @@</span><br><span>        return m_egprs_ms_class;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-inline GprsCodingScheme GprsMs::current_cs_ul() const</span><br><span style="color: hsl(120, 100%, 40%);">+inline CodingScheme GprsMs::current_cs_ul() const</span><br><span> {</span><br><span>       return m_current_cs_ul;</span><br><span> }</span><br><span>diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp</span><br><span>index a33b655..3912204 100644</span><br><span>--- a/src/pcu_main.cpp</span><br><span>+++ b/src/pcu_main.cpp</span><br><span>@@ -31,12 +31,12 @@</span><br><span> #include <signal.h></span><br><span> #include <sched.h></span><br><span> #include <bts.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <gprs_coding_scheme.h></span><br><span> #include <osmocom/pcu/pcuif_proto.h></span><br><span> #include "gprs_bssgp_pcu.h"</span><br><span> </span><br><span> extern "C" {</span><br><span> #include "pcu_vty.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "coding_scheme.h"</span><br><span> #include <osmocom/gprs/gprs_bssgp.h></span><br><span> #include <osmocom/gprs/gprs_ns.h></span><br><span> #include <osmocom/vty/telnet_interface.h></span><br><span>diff --git a/src/pcu_vty_functions.cpp b/src/pcu_vty_functions.cpp</span><br><span>index 7b6c84f..97241e1 100644</span><br><span>--- a/src/pcu_vty_functions.cpp</span><br><span>+++ b/src/pcu_vty_functions.cpp</span><br><span>@@ -27,7 +27,6 @@</span><br><span> #include "gprs_ms_storage.h"</span><br><span> #include "gprs_ms.h"</span><br><span> #include "cxx_linuxlist.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include <gprs_coding_scheme.h></span><br><span> #include <llc.h></span><br><span> #include <pcu_l1_if.h></span><br><span> #include <rlc.h></span><br><span>diff --git a/src/pdch.cpp b/src/pdch.cpp</span><br><span>index fb02d59..953dec4 100644</span><br><span>--- a/src/pdch.cpp</span><br><span>+++ b/src/pdch.cpp</span><br><span>@@ -25,7 +25,7 @@</span><br><span> #include <encoding.h></span><br><span> #include <gprs_rlcmac.h></span><br><span> #include <gprs_debug.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <gprs_coding_scheme.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <coding_scheme.h></span><br><span> #include <gprs_ms.h></span><br><span> #include <gprs_ms_storage.h></span><br><span> #include <pcu_l1_if.h></span><br><span>@@ -688,11 +688,11 @@</span><br><span> </span><br><span> /* Received Uplink RLC control block. */</span><br><span> int gprs_rlcmac_pdch::rcv_control_block(const uint8_t *data, uint8_t data_len,</span><br><span style="color: hsl(0, 100%, 40%);">-                                      uint32_t fn, struct pcu_l1_meas *meas, GprsCodingScheme cs)</span><br><span style="color: hsl(120, 100%, 40%);">+                                   uint32_t fn, struct pcu_l1_meas *meas, CodingScheme cs)</span><br><span> {</span><br><span>         bitvec *rlc_block;</span><br><span>   RlcMacUplink_t *ul_control_block;</span><br><span style="color: hsl(0, 100%, 40%);">-       unsigned len = cs.maxBytesUL();</span><br><span style="color: hsl(120, 100%, 40%);">+       unsigned len = mcs_max_bytes_ul(cs);</span><br><span>         int rc;</span><br><span> </span><br><span>  if (!(rlc_block = bitvec_alloc(len, tall_pcu_ctx)))</span><br><span>@@ -751,7 +751,7 @@</span><br><span> int gprs_rlcmac_pdch::rcv_block(uint8_t *data, uint8_t len, uint32_t fn,</span><br><span>        struct pcu_l1_meas *meas)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  GprsCodingScheme cs = GprsCodingScheme::getBySizeUL(len);</span><br><span style="color: hsl(120, 100%, 40%);">+     CodingScheme cs = mcs_get_by_size_ul(len);</span><br><span>   if (!cs) {</span><br><span>           bts()->do_rate_ctr_inc(CTR_DECODE_ERRORS);</span><br><span>                LOGP(DRLCMACUL, LOGL_ERROR, "Dropping data block with invalid"</span><br><span>@@ -762,7 +762,7 @@</span><br><span>       bts()->do_rate_ctr_add(CTR_RLC_UL_BYTES, len);</span><br><span> </span><br><span>        LOGP(DRLCMACUL, LOGL_DEBUG, "Got RLC block, coding scheme: %s, "</span><br><span style="color: hsl(0, 100%, 40%);">-              "length: %d (%d))\n", mcs_name(cs), len, cs.usedSizeUL());</span><br><span style="color: hsl(120, 100%, 40%);">+          "length: %d (%d))\n", mcs_name(cs), len, mcs_used_size_ul(cs));</span><br><span> </span><br><span>        if (mcs_is_gprs(cs))</span><br><span>                 return rcv_block_gprs(data, len, fn, meas, cs);</span><br><span>@@ -778,12 +778,12 @@</span><br><span> </span><br><span> /*! \brief process egprs and gprs data blocks */</span><br><span> int gprs_rlcmac_pdch::rcv_data_block(uint8_t *data, uint8_t data_len, uint32_t fn,</span><br><span style="color: hsl(0, 100%, 40%);">-   struct pcu_l1_meas *meas, GprsCodingScheme cs)</span><br><span style="color: hsl(120, 100%, 40%);">+        struct pcu_l1_meas *meas, CodingScheme cs)</span><br><span> {</span><br><span>      int rc;</span><br><span>      struct gprs_rlc_data_info rlc_dec;</span><br><span>   struct gprs_rlcmac_ul_tbf *tbf;</span><br><span style="color: hsl(0, 100%, 40%);">- unsigned len = cs.sizeUL();</span><br><span style="color: hsl(120, 100%, 40%);">+   unsigned len = mcs_size_ul(cs);</span><br><span> </span><br><span>  /* These are always data blocks, since EGPRS still uses CS-1 for</span><br><span>      * control blocks (see 44.060, section 10.3, 1st par.)</span><br><span>@@ -836,7 +836,7 @@</span><br><span> }</span><br><span> </span><br><span> int gprs_rlcmac_pdch::rcv_block_gprs(uint8_t *data, uint8_t data_len, uint32_t fn,</span><br><span style="color: hsl(0, 100%, 40%);">-     struct pcu_l1_meas *meas, GprsCodingScheme cs)</span><br><span style="color: hsl(120, 100%, 40%);">+        struct pcu_l1_meas *meas, CodingScheme cs)</span><br><span> {</span><br><span>      unsigned payload = data[0] >> 6;</span><br><span>       int rc = 0;</span><br><span>diff --git a/src/pdch.h b/src/pdch.h</span><br><span>index 97b4b23..1bb028b 100644</span><br><span>--- a/src/pdch.h</span><br><span>+++ b/src/pdch.h</span><br><span>@@ -25,9 +25,9 @@</span><br><span> extern "C" {</span><br><span> #include <osmocom/core/linuxlist.h></span><br><span> #include "gsm_rlcmac.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "coding_scheme.h"</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#include <gprs_coding_scheme.h></span><br><span> #include <bts.h></span><br><span> #endif</span><br><span> </span><br><span>@@ -61,9 +61,9 @@</span><br><span>     int rcv_block(uint8_t *data, uint8_t len, uint32_t fn,</span><br><span>               struct pcu_l1_meas *meas);</span><br><span>   int rcv_block_gprs(uint8_t *data, uint8_t data_len, uint32_t fn,</span><br><span style="color: hsl(0, 100%, 40%);">-                struct pcu_l1_meas *meas, GprsCodingScheme cs);</span><br><span style="color: hsl(120, 100%, 40%);">+               struct pcu_l1_meas *meas, CodingScheme cs);</span><br><span>  int rcv_data_block(uint8_t *data, uint8_t data_len, uint32_t fn,</span><br><span style="color: hsl(0, 100%, 40%);">-                struct pcu_l1_meas *meas, GprsCodingScheme cs);</span><br><span style="color: hsl(120, 100%, 40%);">+               struct pcu_l1_meas *meas, CodingScheme cs);</span><br><span> </span><br><span>      gprs_rlcmac_bts *bts_data() const;</span><br><span>   BTS *bts() const;</span><br><span>@@ -113,7 +113,7 @@</span><br><span> #ifdef __cplusplus</span><br><span> private:</span><br><span>    int rcv_control_block(const uint8_t *data, uint8_t data_len, uint32_t fn,</span><br><span style="color: hsl(0, 100%, 40%);">-                             struct pcu_l1_meas *meas, GprsCodingScheme cs);</span><br><span style="color: hsl(120, 100%, 40%);">+                       struct pcu_l1_meas *meas, CodingScheme cs);</span><br><span> </span><br><span>        void rcv_control_ack(Packet_Control_Acknowledgement_t *, uint32_t fn);</span><br><span>       void rcv_control_dl_ack_nack(Packet_Downlink_Ack_Nack_t *, uint32_t fn, struct pcu_l1_meas *meas);</span><br><span>diff --git a/src/rlc.cpp b/src/rlc.cpp</span><br><span>index 5316136..bbfb798 100644</span><br><span>--- a/src/rlc.cpp</span><br><span>+++ b/src/rlc.cpp</span><br><span>@@ -18,7 +18,6 @@</span><br><span> </span><br><span> #include "bts.h"</span><br><span> #include "gprs_debug.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include <gprs_coding_scheme.h></span><br><span> #include <rlc.h></span><br><span> </span><br><span> #include <stdbool.h></span><br><span>@@ -29,6 +28,8 @@</span><br><span> #include <osmocom/core/utils.h></span><br><span> #include <osmocom/core/bitvec.h></span><br><span> #include <osmocom/core/logging.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "coding_scheme.h"</span><br><span> }</span><br><span> </span><br><span> </span><br><span>@@ -314,11 +315,11 @@</span><br><span> }</span><br><span> </span><br><span> static void gprs_rlc_data_header_init(struct gprs_rlc_data_info *rlc,</span><br><span style="color: hsl(0, 100%, 40%);">-        GprsCodingScheme cs, bool with_padding, unsigned int header_bits,</span><br><span style="color: hsl(120, 100%, 40%);">+     CodingScheme cs, bool with_padding, unsigned int header_bits,</span><br><span>        const unsigned int spb)</span><br><span> {</span><br><span>         unsigned int i;</span><br><span style="color: hsl(0, 100%, 40%);">- unsigned int padding_bits = with_padding ? cs.optionalPaddingBits() : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+      unsigned int padding_bits = with_padding ? mcs_opt_padding_bits(cs) : 0;</span><br><span> </span><br><span>         rlc->cs = cs;</span><br><span>     rlc->r = 0;</span><br><span>@@ -330,7 +331,7 @@</span><br><span>         rlc->es_p = 0;</span><br><span>    rlc->rrbp = 0;</span><br><span>    rlc->pr = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- rlc->num_data_blocks = num_data_blocks(cs.headerTypeData());</span><br><span style="color: hsl(120, 100%, 40%);">+       rlc->num_data_blocks = num_data_blocks(mcs_header_type(cs));</span><br><span>      rlc->with_padding = with_padding;</span><br><span> </span><br><span>     OSMO_ASSERT(rlc->num_data_blocks <= ARRAY_SIZE(rlc->block_info));</span><br><span>@@ -341,35 +342,35 @@</span><br><span> </span><br><span>               rlc->data_offs_bits[i] =</span><br><span>                  header_bits + padding_bits +</span><br><span style="color: hsl(0, 100%, 40%);">-                    (i+1) * num_data_block_header_bits(cs.headerTypeData()) +</span><br><span style="color: hsl(120, 100%, 40%);">+                     (i+1) * num_data_block_header_bits(mcs_header_type(cs)) +</span><br><span>                    i * 8 * rlc->block_info[0].data_len;</span><br><span>      }</span><br><span> }</span><br><span> </span><br><span> void gprs_rlc_data_info_init_dl(struct gprs_rlc_data_info *rlc,</span><br><span style="color: hsl(0, 100%, 40%);">-   GprsCodingScheme cs, bool with_padding, const unsigned int spb)</span><br><span style="color: hsl(120, 100%, 40%);">+       CodingScheme cs, bool with_padding, const unsigned int spb)</span><br><span> {</span><br><span>     return gprs_rlc_data_header_init(rlc, cs, with_padding,</span><br><span style="color: hsl(0, 100%, 40%);">-                                  num_data_header_bits_DL(cs.headerTypeData()), spb);</span><br><span style="color: hsl(120, 100%, 40%);">+                                   num_data_header_bits_DL(mcs_header_type(cs)), spb);</span><br><span> }</span><br><span> </span><br><span> void gprs_rlc_data_info_init_ul(struct gprs_rlc_data_info *rlc,</span><br><span style="color: hsl(0, 100%, 40%);">-        GprsCodingScheme cs, bool with_padding)</span><br><span style="color: hsl(120, 100%, 40%);">+       CodingScheme cs, bool with_padding)</span><br><span> {</span><br><span>     /*</span><br><span>    * last parameter is sent as 0 since common function used</span><br><span>     * for both DL and UL</span><br><span>         */</span><br><span>  return gprs_rlc_data_header_init(rlc, cs, with_padding,</span><br><span style="color: hsl(0, 100%, 40%);">-                                  num_data_header_bits_UL(cs.headerTypeData()), 0);</span><br><span style="color: hsl(120, 100%, 40%);">+                                     num_data_header_bits_UL(mcs_header_type(cs)), 0);</span><br><span> }</span><br><span> </span><br><span> void gprs_rlc_data_block_info_init(struct gprs_rlc_data_block_info *rdbi,</span><br><span style="color: hsl(0, 100%, 40%);">-        GprsCodingScheme cs, bool with_padding, const unsigned int spb)</span><br><span style="color: hsl(120, 100%, 40%);">+       CodingScheme cs, bool with_padding, const unsigned int spb)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-        unsigned int data_len = cs.maxDataBlockBytes();</span><br><span style="color: hsl(120, 100%, 40%);">+       unsigned int data_len = mcs_max_data_block_bytes(cs);</span><br><span>        if (with_padding)</span><br><span style="color: hsl(0, 100%, 40%);">-               data_len -= cs.optionalPaddingBits() / 8;</span><br><span style="color: hsl(120, 100%, 40%);">+             data_len -= mcs_opt_padding_bits(cs) / 8;</span><br><span> </span><br><span>        rdbi->data_len = data_len;</span><br><span>        rdbi->bsn = 0;</span><br><span>@@ -380,19 +381,19 @@</span><br><span>    rdbi->spb = spb;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-unsigned int gprs_rlc_mcs_cps(GprsCodingScheme cs,</span><br><span style="color: hsl(120, 100%, 40%);">+unsigned int gprs_rlc_mcs_cps(CodingScheme cs,</span><br><span>       enum egprs_puncturing_values punct,</span><br><span>  enum egprs_puncturing_values punct2, bool with_padding)</span><br><span> {</span><br><span>         /* validate that punct and punct2 are as expected */</span><br><span style="color: hsl(0, 100%, 40%);">-    switch (CodingScheme(cs)) {</span><br><span style="color: hsl(120, 100%, 40%);">+   switch (cs) {</span><br><span>        case MCS9:</span><br><span>   case MCS8:</span><br><span>   case MCS7:</span><br><span>           if (punct2 == EGPRS_PS_INVALID) {</span><br><span>                    LOGP(DRLCMACDL, LOGL_ERROR,</span><br><span>                       "Invalid punct2 value for coding scheme %d: %d\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                            CodingScheme(cs), punct2);</span><br><span style="color: hsl(120, 100%, 40%);">+                            cs, punct2);</span><br><span>                    return -1;</span><br><span>           }</span><br><span>            /* fall through */</span><br><span>@@ -405,7 +406,7 @@</span><br><span>             if (punct == EGPRS_PS_INVALID) {</span><br><span>                     LOGP(DRLCMACDL, LOGL_ERROR,</span><br><span>                       "Invalid punct value for coding scheme %d: %d\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                             CodingScheme(cs), punct);</span><br><span style="color: hsl(120, 100%, 40%);">+                             cs, punct);</span><br><span>                     return -1;</span><br><span>           }</span><br><span>            break;</span><br><span>@@ -414,7 +415,7 @@</span><br><span>         }</span><br><span> </span><br><span>        /* See 3GPP TS 44.060 10.4.8a.3.1, 10.4.8a.2.1, 10.4.8a.1.1 */</span><br><span style="color: hsl(0, 100%, 40%);">-  switch (CodingScheme(cs)) {</span><br><span style="color: hsl(120, 100%, 40%);">+   switch (cs) {</span><br><span>        case MCS1: return 0b1011 +</span><br><span>           punct % EGPRS_MAX_PS_NUM_2;</span><br><span>  case MCS2: return 0b1001 +</span><br><span>@@ -443,12 +444,12 @@</span><br><span> }</span><br><span> </span><br><span> void gprs_rlc_mcs_cps_decode(unsigned int cps,</span><br><span style="color: hsl(0, 100%, 40%);">-   GprsCodingScheme cs, int *punct, int *punct2, int *with_padding)</span><br><span style="color: hsl(120, 100%, 40%);">+      CodingScheme cs, int *punct, int *punct2, int *with_padding)</span><br><span> {</span><br><span>    *punct2 = -1;</span><br><span>        *with_padding = 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  switch (CodingScheme(cs)) {</span><br><span style="color: hsl(120, 100%, 40%);">+   switch (cs) {</span><br><span>        case MCS1:</span><br><span>           cps -= 0b1011; *punct = cps % 2; break;</span><br><span>      case MCS2:</span><br><span>@@ -481,8 +482,8 @@</span><br><span>  */</span><br><span> enum egprs_puncturing_values gprs_get_punct_scheme(</span><br><span>       enum egprs_puncturing_values punct,</span><br><span style="color: hsl(0, 100%, 40%);">-     const GprsCodingScheme &cs,</span><br><span style="color: hsl(0, 100%, 40%);">- const GprsCodingScheme &cs_current,</span><br><span style="color: hsl(120, 100%, 40%);">+       const CodingScheme &cs,</span><br><span style="color: hsl(120, 100%, 40%);">+   const CodingScheme &cs_current,</span><br><span>  const enum egprs_rlcmac_dl_spb spb)</span><br><span> {</span><br><span> </span><br><span>@@ -495,23 +496,23 @@</span><br><span>                 return punct;</span><br><span> </span><br><span>    /* TS  44.060 9.3.2.1.1 */</span><br><span style="color: hsl(0, 100%, 40%);">-      if ((CodingScheme(cs) == MCS9) &&</span><br><span style="color: hsl(0, 100%, 40%);">-       (CodingScheme(cs_current) == MCS6)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((cs == MCS9) &&</span><br><span style="color: hsl(120, 100%, 40%);">+   (cs_current == MCS6)) {</span><br><span>              if ((punct == EGPRS_PS_1) || (punct == EGPRS_PS_3))</span><br><span>                  return EGPRS_PS_1;</span><br><span>           else if (punct == EGPRS_PS_2)</span><br><span>                        return EGPRS_PS_2;</span><br><span style="color: hsl(0, 100%, 40%);">-      } else if ((CodingScheme(cs) == MCS6) &&</span><br><span style="color: hsl(0, 100%, 40%);">-        (CodingScheme(cs_current) == MCS9)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if ((cs == MCS6) &&</span><br><span style="color: hsl(120, 100%, 40%);">+    (cs_current == MCS9)) {</span><br><span>              if (punct == EGPRS_PS_1)</span><br><span>                     return EGPRS_PS_3;</span><br><span>           else if (punct == EGPRS_PS_2)</span><br><span>                        return EGPRS_PS_2;</span><br><span style="color: hsl(0, 100%, 40%);">-      } else if ((CodingScheme(cs) == MCS7) &&</span><br><span style="color: hsl(0, 100%, 40%);">-        (CodingScheme(cs_current) == MCS5))</span><br><span style="color: hsl(120, 100%, 40%);">+   } else if ((cs == MCS7) &&</span><br><span style="color: hsl(120, 100%, 40%);">+    (cs_current == MCS5))</span><br><span>                return EGPRS_PS_1;</span><br><span style="color: hsl(0, 100%, 40%);">-      else if ((CodingScheme(cs) == MCS5) &&</span><br><span style="color: hsl(0, 100%, 40%);">-  (CodingScheme(cs_current) == MCS7))</span><br><span style="color: hsl(120, 100%, 40%);">+   else if ((cs == MCS5) &&</span><br><span style="color: hsl(120, 100%, 40%);">+      (cs_current == MCS7))</span><br><span>                return EGPRS_PS_2;</span><br><span>   else if (cs != cs_current)</span><br><span>           return EGPRS_PS_1;</span><br><span>@@ -532,9 +533,9 @@</span><br><span>  * TS 44.060 10.4.8a.3.1, 10.4.8a.2.1, 10.4.8a.1.1</span><br><span>  */</span><br><span> void gprs_update_punct_scheme(enum egprs_puncturing_values *punct,</span><br><span style="color: hsl(0, 100%, 40%);">-     const GprsCodingScheme &cs)</span><br><span style="color: hsl(120, 100%, 40%);">+       const CodingScheme &cs)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-        switch (CodingScheme(cs)) {</span><br><span style="color: hsl(120, 100%, 40%);">+   switch (cs) {</span><br><span>        case MCS1 :</span><br><span>  case MCS2 :</span><br><span>  case MCS5 :</span><br><span>diff --git a/src/rlc.h b/src/rlc.h</span><br><span>index 109c5b3..02ea437 100644</span><br><span>--- a/src/rlc.h</span><br><span>+++ b/src/rlc.h</span><br><span>@@ -19,7 +19,9 @@</span><br><span>  */</span><br><span> #pragma once</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#include "gprs_coding_scheme.h"</span><br><span style="color: hsl(120, 100%, 40%);">+extern "C" {</span><br><span style="color: hsl(120, 100%, 40%);">+#include "coding_scheme.h"</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span> </span><br><span> #include <osmocom/core/endian.h></span><br><span> </span><br><span>@@ -154,7 +156,7 @@</span><br><span> };</span><br><span> </span><br><span> struct gprs_rlc_data_info {</span><br><span style="color: hsl(0, 100%, 40%);">-  GprsCodingScheme cs;</span><br><span style="color: hsl(120, 100%, 40%);">+  CodingScheme cs;</span><br><span>     unsigned int r;</span><br><span>      unsigned int si;</span><br><span>     unsigned int tfi;</span><br><span>@@ -192,15 +194,15 @@</span><br><span>     * 8.1.1.1 and Table 8.1.1.2</span><br><span>          * For UL. cs_last shall be used everywhere.</span><br><span>          */</span><br><span style="color: hsl(0, 100%, 40%);">-     GprsCodingScheme cs_current_trans;</span><br><span style="color: hsl(0, 100%, 40%);">-      GprsCodingScheme cs_last;</span><br><span style="color: hsl(120, 100%, 40%);">+     CodingScheme cs_current_trans;</span><br><span style="color: hsl(120, 100%, 40%);">+        CodingScheme cs_last;</span><br><span> </span><br><span>    /*</span><br><span>    * The MCS of initial transmission of a BSN</span><br><span>   * This variable is used for split block</span><br><span>      * processing in DL</span><br><span>   */</span><br><span style="color: hsl(0, 100%, 40%);">-     GprsCodingScheme cs_init;</span><br><span style="color: hsl(120, 100%, 40%);">+     CodingScheme cs_init;</span><br><span> </span><br><span>    /* puncturing scheme value to be used for next transmission*/</span><br><span>        enum egprs_puncturing_values next_ps;</span><br><span>@@ -212,21 +214,21 @@</span><br><span> uint8_t *prepare(struct gprs_rlc_data *rlc, size_t block_data_length);</span><br><span> </span><br><span> void gprs_rlc_data_info_init_dl(struct gprs_rlc_data_info *rlc,</span><br><span style="color: hsl(0, 100%, 40%);">-  GprsCodingScheme cs, bool with_padding, const unsigned int spb);</span><br><span style="color: hsl(120, 100%, 40%);">+      CodingScheme cs, bool with_padding, const unsigned int spb);</span><br><span> void gprs_rlc_data_info_init_ul(struct gprs_rlc_data_info *rlc,</span><br><span style="color: hsl(0, 100%, 40%);">- GprsCodingScheme cs, bool with_padding);</span><br><span style="color: hsl(120, 100%, 40%);">+      CodingScheme cs, bool with_padding);</span><br><span> void gprs_rlc_data_block_info_init(struct gprs_rlc_data_block_info *rdbi,</span><br><span style="color: hsl(0, 100%, 40%);">-       GprsCodingScheme cs, bool with_padding, const unsigned int spb);</span><br><span style="color: hsl(0, 100%, 40%);">-unsigned int gprs_rlc_mcs_cps(GprsCodingScheme cs, enum egprs_puncturing_values</span><br><span style="color: hsl(120, 100%, 40%);">+       CodingScheme cs, bool with_padding, const unsigned int spb);</span><br><span style="color: hsl(120, 100%, 40%);">+unsigned int gprs_rlc_mcs_cps(CodingScheme cs, enum egprs_puncturing_values</span><br><span>    punct, enum egprs_puncturing_values punct2, bool with_padding);</span><br><span style="color: hsl(0, 100%, 40%);">-void gprs_rlc_mcs_cps_decode(unsigned int cps, GprsCodingScheme cs,</span><br><span style="color: hsl(120, 100%, 40%);">+void gprs_rlc_mcs_cps_decode(unsigned int cps, CodingScheme cs,</span><br><span>  int *punct, int *punct2, int *with_padding);</span><br><span> enum egprs_puncturing_values gprs_get_punct_scheme(enum egprs_puncturing_values</span><br><span style="color: hsl(0, 100%, 40%);">- punct, const GprsCodingScheme &cs,</span><br><span style="color: hsl(0, 100%, 40%);">-  const GprsCodingScheme &cs_current_trans,</span><br><span style="color: hsl(120, 100%, 40%);">+ punct, const CodingScheme &cs,</span><br><span style="color: hsl(120, 100%, 40%);">+    const CodingScheme &cs_current_trans,</span><br><span>    const enum egprs_rlcmac_dl_spb spb);</span><br><span> void gprs_update_punct_scheme(enum egprs_puncturing_values *punct,</span><br><span style="color: hsl(0, 100%, 40%);">-      const GprsCodingScheme &cs);</span><br><span style="color: hsl(120, 100%, 40%);">+      const CodingScheme &cs);</span><br><span> /*</span><br><span>  * I hold the currently transferred blocks and will provide</span><br><span>  * the routines to manipulate these arrays.</span><br><span>diff --git a/src/tbf.cpp b/src/tbf.cpp</span><br><span>index ccf257d..3726707 100644</span><br><span>--- a/src/tbf.cpp</span><br><span>+++ b/src/tbf.cpp</span><br><span>@@ -33,7 +33,6 @@</span><br><span> #include <pcu_utils.h></span><br><span> #include <gprs_ms_storage.h></span><br><span> #include <sba.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <gprs_coding_scheme.h></span><br><span> #include <gsm_timer.h></span><br><span> #include <pdch.h></span><br><span> </span><br><span>@@ -49,6 +48,7 @@</span><br><span> #include <osmocom/gsm/protocol/gsm_04_08.h></span><br><span> </span><br><span> #include "gsm_rlcmac.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "coding_scheme.h"</span><br><span> }</span><br><span> </span><br><span> #include <errno.h></span><br><span>@@ -310,13 +310,14 @@</span><br><span>       m_ms_class = ms_class_;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-GprsCodingScheme gprs_rlcmac_tbf::current_cs() const</span><br><span style="color: hsl(120, 100%, 40%);">+CodingScheme gprs_rlcmac_tbf::current_cs() const</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-     GprsCodingScheme cs;</span><br><span style="color: hsl(120, 100%, 40%);">+  CodingScheme cs;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>   if (direction == GPRS_RLCMAC_UL_TBF)</span><br><span style="color: hsl(0, 100%, 40%);">-            cs = m_ms ? m_ms->current_cs_ul() : GprsCodingScheme();</span><br><span style="color: hsl(120, 100%, 40%);">+            cs = m_ms ? m_ms->current_cs_ul() : UNKNOWN;</span><br><span>      else</span><br><span style="color: hsl(0, 100%, 40%);">-            cs = m_ms ? m_ms->current_cs_dl() : GprsCodingScheme();</span><br><span style="color: hsl(120, 100%, 40%);">+            cs = m_ms ? m_ms->current_cs_dl() : UNKNOWN;</span><br><span> </span><br><span>  return cs;</span><br><span> }</span><br><span>@@ -965,8 +966,8 @@</span><br><span> </span><br><span> static void setup_egprs_mode(gprs_rlcmac_bts *bts, GprsMs *ms)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-        if (mcs_is_edge_gmsk(GprsCodingScheme::getEgprsByNum(bts->max_mcs_ul)) &&</span><br><span style="color: hsl(0, 100%, 40%);">-            mcs_is_edge_gmsk(GprsCodingScheme::getEgprsByNum(bts->max_mcs_dl)) &&</span><br><span style="color: hsl(120, 100%, 40%);">+      if (mcs_is_edge_gmsk(mcs_get_egprs_by_num(bts->max_mcs_ul)) &&</span><br><span style="color: hsl(120, 100%, 40%);">+             mcs_is_edge_gmsk(mcs_get_egprs_by_num(bts->max_mcs_dl)) &&</span><br><span>                ms->mode() != EGPRS)</span><br><span>      {</span><br><span>            ms->set_mode(EGPRS_GMSK);</span><br><span>diff --git a/src/tbf.h b/src/tbf.h</span><br><span>index 2b4cf6d..764c76f 100644</span><br><span>--- a/src/tbf.h</span><br><span>+++ b/src/tbf.h</span><br><span>@@ -24,14 +24,16 @@</span><br><span> #include "rlc.h"</span><br><span> #include "cxx_linuxlist.h"</span><br><span> #include <gprs_debug.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <gprs_coding_scheme.h></span><br><span> #include <gsm_timer.h></span><br><span> #include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> extern "C" {</span><br><span> #include <osmocom/core/utils.h></span><br><span style="color: hsl(0, 100%, 40%);">-       #include <osmocom/core/linuxlist.h></span><br><span style="color: hsl(0, 100%, 40%);">-       #include <osmocom/core/logging.h></span><br><span style="color: hsl(0, 100%, 40%);">- #include <osmocom/core/timer.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/linuxlist.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/logging.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/timer.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "coding_scheme.h"</span><br><span> }</span><br><span> </span><br><span> struct bssgp_bvc_ctx;</span><br><span>@@ -245,7 +247,7 @@</span><br><span>     void set_ta(uint8_t);</span><br><span>        uint8_t ms_class() const;</span><br><span>    void set_ms_class(uint8_t);</span><br><span style="color: hsl(0, 100%, 40%);">-     GprsCodingScheme current_cs() const;</span><br><span style="color: hsl(120, 100%, 40%);">+  CodingScheme current_cs() const;</span><br><span>     size_t llc_queue_size() const;</span><br><span> </span><br><span>   time_t created_ts() const;</span><br><span>diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp</span><br><span>index cd4ddb9..530ed04 100644</span><br><span>--- a/src/tbf_dl.cpp</span><br><span>+++ b/src/tbf_dl.cpp</span><br><span>@@ -30,7 +30,6 @@</span><br><span> #include <gprs_codel.h></span><br><span> #include <decoding.h></span><br><span> #include <encoding.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <gprs_coding_scheme.h></span><br><span> #include <gprs_ms.h></span><br><span> #include <gprs_ms_storage.h></span><br><span> #include <llc.h></span><br><span>@@ -370,7 +369,7 @@</span><br><span> {</span><br><span>     int bsn;</span><br><span>     int data_len2, force_data_len = -1;</span><br><span style="color: hsl(0, 100%, 40%);">-     GprsCodingScheme force_cs;</span><br><span style="color: hsl(120, 100%, 40%);">+    CodingScheme force_cs = UNKNOWN;</span><br><span> </span><br><span>         /* search for a nacked or resend marked bsn */</span><br><span>       bsn = m_window.resend_needed();</span><br><span>@@ -446,7 +445,7 @@</span><br><span>                        return take_next_bsn(fn, previous_bsn, may_combine);</span><br><span>         } else if (have_data()) {</span><br><span>            /* The window has space left, generate new bsn */</span><br><span style="color: hsl(0, 100%, 40%);">-               GprsCodingScheme new_cs;</span><br><span style="color: hsl(120, 100%, 40%);">+              CodingScheme new_cs;</span><br><span>                 new_cs = force_cs ? force_cs : current_cs();</span><br><span>                 LOGPTBFDL(this, LOGL_DEBUG,</span><br><span>                    "Sending new block at BSN %d, CS=%s\n",</span><br><span>@@ -480,7 +479,7 @@</span><br><span>            bts->do_rate_ctr_inc(CTR_RLC_RESENT);</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   *may_combine = num_data_blocks(m_rlc.block(bsn)->cs_current_trans.headerTypeData()) > 1;</span><br><span style="color: hsl(120, 100%, 40%);">+        *may_combine = num_data_blocks(mcs_header_type(m_rlc.block(bsn)->cs_current_trans)) > 1;</span><br><span> </span><br><span>   return bsn;</span><br><span> }</span><br><span>@@ -561,7 +560,7 @@</span><br><span>       m_last_dl_drained_fn = -1;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, GprsCodingScheme cs)</span><br><span style="color: hsl(120, 100%, 40%);">+int gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, CodingScheme cs)</span><br><span> {</span><br><span>   uint8_t *data;</span><br><span>       gprs_rlc_data *rlc_data;</span><br><span>@@ -574,10 +573,10 @@</span><br><span>     if (m_llc.frame_length() == 0)</span><br><span>               schedule_next_frame();</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT(cs.isValid());</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(mcs_is_valid(cs));</span><br><span> </span><br><span>   /* length of usable data block (single data unit w/o header) */</span><br><span style="color: hsl(0, 100%, 40%);">- const uint8_t block_data_len = cs.maxDataBlockBytes();</span><br><span style="color: hsl(120, 100%, 40%);">+        const uint8_t block_data_len = mcs_max_data_block_bytes(cs);</span><br><span> </span><br><span>     /* now we still have untransmitted LLC data, so we fill mac block */</span><br><span>         rlc_data = m_rlc.block(bsn);</span><br><span>@@ -691,7 +690,7 @@</span><br><span>   int rc;</span><br><span>      bool is_final = false;</span><br><span>       gprs_rlc_data_info rlc;</span><br><span style="color: hsl(0, 100%, 40%);">- GprsCodingScheme cs;</span><br><span style="color: hsl(120, 100%, 40%);">+  CodingScheme cs;</span><br><span>     int bsns[ARRAY_SIZE(rlc.block_info)];</span><br><span>        unsigned num_bsns;</span><br><span>   bool need_padding = false;</span><br><span>@@ -740,8 +739,8 @@</span><br><span>              * Refer commit be881c028fc4da00c4046ecd9296727975c206a3</span><br><span>              * dated 2016-02-07 23:45:40 (UTC)</span><br><span>            */</span><br><span style="color: hsl(0, 100%, 40%);">-             if (cs != GprsCodingScheme(MCS8))</span><br><span style="color: hsl(0, 100%, 40%);">-                       cs.decToSingleBlock(&need_padding);</span><br><span style="color: hsl(120, 100%, 40%);">+               if (cs != MCS8)</span><br><span style="color: hsl(120, 100%, 40%);">+                       mcs_dec_to_single_block(&cs, &need_padding);</span><br><span>         }</span><br><span> </span><br><span>        spb = get_egprs_dl_spb(index);</span><br><span>@@ -756,7 +755,7 @@</span><br><span>         rlc.tfi = m_tfi; /* TFI */</span><br><span> </span><br><span>       /* return data block(s) as message */</span><br><span style="color: hsl(0, 100%, 40%);">-   msg_len = cs.sizeDL();</span><br><span style="color: hsl(120, 100%, 40%);">+        msg_len = mcs_size_dl(cs);</span><br><span>   dl_msg = msgb_alloc(msg_len, "rlcmac_dl_data");</span><br><span>    if (!dl_msg)</span><br><span>                 return NULL;</span><br><span>@@ -1273,11 +1272,11 @@</span><br><span>       egprs_rlc_dl_reseg_bsn_state *block_status_dl =</span><br><span>                              &rlc_data->spb_status.block_status_dl;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       enum CodingScheme cs_init = CodingScheme(rlc_data->cs_init);</span><br><span style="color: hsl(0, 100%, 40%);">- enum CodingScheme cs_current_trans = CodingScheme(rlc_data->cs_current_trans);</span><br><span style="color: hsl(120, 100%, 40%);">+     enum CodingScheme cs_init = rlc_data->cs_init;</span><br><span style="color: hsl(120, 100%, 40%);">+     enum CodingScheme cs_current_trans = rlc_data->cs_current_trans;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- enum HeaderType ht_cs_init = rlc_data->cs_init.headerTypeData();</span><br><span style="color: hsl(0, 100%, 40%);">-     enum HeaderType ht_cs_current_trans = rlc_data->cs_current_trans.headerTypeData();</span><br><span style="color: hsl(120, 100%, 40%);">+ enum HeaderType ht_cs_init = mcs_header_type(rlc_data->cs_init);</span><br><span style="color: hsl(120, 100%, 40%);">+   enum HeaderType ht_cs_current_trans = mcs_header_type(rlc_data->cs_current_trans);</span><br><span> </span><br><span>    *block_data = &rlc_data->block[0];</span><br><span> </span><br><span>@@ -1346,11 +1345,11 @@</span><br><span>      struct gprs_rlc_data *rlc_data = m_rlc.block(bsn);</span><br><span>   egprs_rlc_dl_reseg_bsn_state block_status_dl = rlc_data->spb_status.block_status_dl;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     enum CodingScheme cs_init = CodingScheme(rlc_data->cs_init);</span><br><span style="color: hsl(0, 100%, 40%);">- enum CodingScheme cs_current_trans = CodingScheme(rlc_data->cs_current_trans);</span><br><span style="color: hsl(120, 100%, 40%);">+     enum CodingScheme cs_init = rlc_data->cs_init;</span><br><span style="color: hsl(120, 100%, 40%);">+     enum CodingScheme cs_current_trans = rlc_data->cs_current_trans;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- enum HeaderType ht_cs_init = rlc_data->cs_init.headerTypeData();</span><br><span style="color: hsl(0, 100%, 40%);">-     enum HeaderType ht_cs_current_trans = rlc_data->cs_current_trans.headerTypeData();</span><br><span style="color: hsl(120, 100%, 40%);">+ enum HeaderType ht_cs_init = mcs_header_type(rlc_data->cs_init);</span><br><span style="color: hsl(120, 100%, 40%);">+   enum HeaderType ht_cs_current_trans = mcs_header_type(rlc_data->cs_current_trans);</span><br><span> </span><br><span>    /* Table 10.4.8b.1 of 44.060 */</span><br><span>      if (ht_cs_current_trans == HEADER_EGPRS_DATA_TYPE_3) {</span><br><span>diff --git a/src/tbf_dl.h b/src/tbf_dl.h</span><br><span>index f3838d7..2da0ec1 100644</span><br><span>--- a/src/tbf_dl.h</span><br><span>+++ b/src/tbf_dl.h</span><br><span>@@ -111,7 +111,7 @@</span><br><span>    int take_next_bsn(uint32_t fn, int previous_bsn,</span><br><span>             bool *may_combine);</span><br><span>  bool restart_bsn_cycle();</span><br><span style="color: hsl(0, 100%, 40%);">-       int create_new_bsn(const uint32_t fn, GprsCodingScheme cs);</span><br><span style="color: hsl(120, 100%, 40%);">+   int create_new_bsn(const uint32_t fn, CodingScheme cs);</span><br><span>      struct msgb *create_dl_acked_block(const uint32_t fn, const uint8_t ts,</span><br><span>                                      int index, int index2 = -1);</span><br><span>         int update_window(const uint8_t ssn, const uint8_t *rbb);</span><br><span>diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp</span><br><span>index 9899580..0cc60f3 100644</span><br><span>--- a/src/tbf_ul.cpp</span><br><span>+++ b/src/tbf_ul.cpp</span><br><span>@@ -29,7 +29,6 @@</span><br><span> #include <gprs_bssgp_pcu.h></span><br><span> #include <decoding.h></span><br><span> #include <pcu_l1_if.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <gprs_coding_scheme.h></span><br><span> #include <gprs_ms.h></span><br><span> #include <llc.h></span><br><span> #include "pcu_utils.h"</span><br><span>@@ -75,7 +74,7 @@</span><br><span>  const uint8_t *data = _data->block;</span><br><span>       uint8_t len = _data->len;</span><br><span>         const struct gprs_rlc_data_block_info *rdbi = &_data->block_info;</span><br><span style="color: hsl(0, 100%, 40%);">-        GprsCodingScheme cs = _data->cs_last;</span><br><span style="color: hsl(120, 100%, 40%);">+      CodingScheme cs = _data->cs_last;</span><br><span> </span><br><span>     Decoding::RlcData frames[16], *frame;</span><br><span>        int i, num_frames = 0;</span><br><span>diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp</span><br><span>index 3f424d1..4f5fb5d 100644</span><br><span>--- a/tests/edge/EdgeTest.cpp</span><br><span>+++ b/tests/edge/EdgeTest.cpp</span><br><span>@@ -21,7 +21,6 @@</span><br><span>  */</span><br><span> </span><br><span> #include "gprs_debug.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "gprs_coding_scheme.h"</span><br><span> #include "decoding.h"</span><br><span> #include "encoding.h"</span><br><span> #include "rlc.h"</span><br><span>@@ -31,6 +30,7 @@</span><br><span> </span><br><span> extern "C" {</span><br><span> #include "pcu_vty.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "coding_scheme.h"</span><br><span> </span><br><span> #include <osmocom/core/application.h></span><br><span> #include <osmocom/core/msgb.h></span><br><span>@@ -48,69 +48,69 @@</span><br><span> int16_t spoof_mnc = 0, spoof_mcc = 0;</span><br><span> bool spoof_mnc_3_digits = false;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void check_coding_scheme(GprsCodingScheme& cs, enum mcs_kind mode)</span><br><span style="color: hsl(120, 100%, 40%);">+static void check_coding_scheme(CodingScheme& cs, enum mcs_kind mode)</span><br><span> {</span><br><span>    volatile unsigned expected_size;</span><br><span>     bool need_padding;</span><br><span style="color: hsl(0, 100%, 40%);">-      GprsCodingScheme new_cs;</span><br><span style="color: hsl(120, 100%, 40%);">+      CodingScheme new_cs;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        OSMO_ASSERT(cs.isValid());</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT(cs.isCompatible(mode));</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_ASSERT(mcs_is_valid(cs));</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_ASSERT(mcs_is_compat_kind(cs, mode));</span><br><span> </span><br><span>       /* Check static getBySizeUL() */</span><br><span style="color: hsl(0, 100%, 40%);">-        expected_size = cs.usedSizeUL();</span><br><span style="color: hsl(0, 100%, 40%);">-        if (cs.spareBitsUL() > 0 && mcs_is_gprs(cs))</span><br><span style="color: hsl(120, 100%, 40%);">+       expected_size = mcs_used_size_ul(cs);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (mcs_spare_bits_ul(cs) > 0 && mcs_is_gprs(cs))</span><br><span>                 expected_size += 1;</span><br><span style="color: hsl(0, 100%, 40%);">-     OSMO_ASSERT(expected_size == cs.sizeUL());</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT(cs == GprsCodingScheme::getBySizeUL(expected_size));</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_ASSERT(expected_size == mcs_size_ul(cs));</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_ASSERT(cs == mcs_get_by_size_ul(expected_size));</span><br><span> </span><br><span>    /* Check static sizeUL() */</span><br><span style="color: hsl(0, 100%, 40%);">-     expected_size = cs.usedSizeDL();</span><br><span style="color: hsl(0, 100%, 40%);">-        if (cs.spareBitsDL() > 0 && mcs_is_gprs(cs))</span><br><span style="color: hsl(120, 100%, 40%);">+       expected_size = mcs_used_size_dl(cs);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (mcs_spare_bits_dl(cs) > 0 && mcs_is_gprs(cs))</span><br><span>                 expected_size += 1;</span><br><span style="color: hsl(0, 100%, 40%);">-     OSMO_ASSERT(expected_size == cs.sizeDL());</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(expected_size == mcs_size_dl(cs));</span><br><span> </span><br><span>   /* Check data block sizes */</span><br><span style="color: hsl(0, 100%, 40%);">-    OSMO_ASSERT(cs.maxDataBlockBytes() * num_data_blocks(cs.headerTypeData()) < cs.maxBytesDL());</span><br><span style="color: hsl(0, 100%, 40%);">-        OSMO_ASSERT(cs.maxDataBlockBytes() * num_data_blocks(cs.headerTypeData()) < cs.maxBytesUL());</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_ASSERT(mcs_max_data_block_bytes(cs) * num_data_blocks(mcs_header_type(cs)) < mcs_max_bytes_dl(cs));</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_ASSERT(mcs_max_data_block_bytes(cs) * num_data_blocks(mcs_header_type(cs)) < mcs_max_bytes_ul(cs));</span><br><span> </span><br><span>      /* Check inc/dec */</span><br><span>  new_cs = cs;</span><br><span style="color: hsl(0, 100%, 40%);">-    new_cs.inc(mode);</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(new_cs.isCompatible(mode));</span><br><span style="color: hsl(120, 100%, 40%);">+       mcs_inc_kind(&new_cs, mode);</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_ASSERT(mcs_is_compat_kind(new_cs, mode));</span><br><span>       if (new_cs != cs) {</span><br><span style="color: hsl(0, 100%, 40%);">-             new_cs.dec(mode);</span><br><span style="color: hsl(0, 100%, 40%);">-               OSMO_ASSERT(new_cs.isCompatible(mode));</span><br><span style="color: hsl(120, 100%, 40%);">+               mcs_dec_kind(&new_cs, mode);</span><br><span style="color: hsl(120, 100%, 40%);">+              OSMO_ASSERT(mcs_is_compat_kind(new_cs, mode));</span><br><span>               OSMO_ASSERT(new_cs == cs);</span><br><span>   }</span><br><span style="color: hsl(0, 100%, 40%);">-       new_cs.dec(mode);</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(new_cs.isCompatible(mode));</span><br><span style="color: hsl(120, 100%, 40%);">+       mcs_dec_kind(&new_cs, mode);</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_ASSERT(mcs_is_compat_kind(new_cs, mode));</span><br><span>       if (new_cs != cs) {</span><br><span style="color: hsl(0, 100%, 40%);">-             new_cs.inc(mode);</span><br><span style="color: hsl(0, 100%, 40%);">-               OSMO_ASSERT(new_cs.isCompatible(mode));</span><br><span style="color: hsl(120, 100%, 40%);">+               mcs_inc_kind(&new_cs, mode);</span><br><span style="color: hsl(120, 100%, 40%);">+              OSMO_ASSERT(mcs_is_compat_kind(new_cs, mode));</span><br><span>               OSMO_ASSERT(new_cs == cs);</span><br><span>   }</span><br><span> </span><br><span>        new_cs = cs;</span><br><span style="color: hsl(0, 100%, 40%);">-    new_cs.decToSingleBlock(&need_padding);</span><br><span style="color: hsl(0, 100%, 40%);">-     OSMO_ASSERT(new_cs.isFamilyCompatible(cs));</span><br><span style="color: hsl(0, 100%, 40%);">-     OSMO_ASSERT(cs.isFamilyCompatible(new_cs));</span><br><span style="color: hsl(0, 100%, 40%);">-     OSMO_ASSERT(cs.isCompatible(new_cs));</span><br><span style="color: hsl(120, 100%, 40%);">+ mcs_dec_to_single_block(&new_cs, &need_padding);</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_ASSERT(mcs_is_family_compat(new_cs, cs));</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_ASSERT(mcs_is_family_compat(cs, new_cs));</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_ASSERT(mcs_is_compat(cs, new_cs));</span><br><span>      if (need_padding) {</span><br><span style="color: hsl(0, 100%, 40%);">-             OSMO_ASSERT(new_cs.maxDataBlockBytes() ==</span><br><span style="color: hsl(0, 100%, 40%);">-                       new_cs.optionalPaddingBits()/8 + cs.maxDataBlockBytes());</span><br><span style="color: hsl(120, 100%, 40%);">+             OSMO_ASSERT(mcs_max_data_block_bytes(new_cs) ==</span><br><span style="color: hsl(120, 100%, 40%);">+                       mcs_opt_padding_bits(new_cs)/8 + mcs_max_data_block_bytes(cs));</span><br><span>      } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                OSMO_ASSERT(new_cs.maxDataBlockBytes() == cs.maxDataBlockBytes());</span><br><span style="color: hsl(120, 100%, 40%);">+            OSMO_ASSERT(mcs_max_data_block_bytes(new_cs) == mcs_max_data_block_bytes(cs));</span><br><span>       }</span><br><span> </span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static bool check_strong_monotonicity(const GprsCodingScheme *cs, uint8_t last_UL, uint8_t last_DL)</span><br><span style="color: hsl(120, 100%, 40%);">+static bool check_strong_monotonicity(const CodingScheme cs, uint8_t last_UL, uint8_t last_DL)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  if (cs->maxBytesUL() <= last_UL)</span><br><span style="color: hsl(120, 100%, 40%);">+        if (mcs_max_bytes_ul(cs) <= last_UL)</span><br><span>              return false;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       if (cs->maxBytesDL() <= last_DL)</span><br><span style="color: hsl(120, 100%, 40%);">+        if (mcs_max_bytes_dl(cs) <= last_DL)</span><br><span>              return false;</span><br><span> </span><br><span>    return true;</span><br><span>@@ -144,31 +144,28 @@</span><br><span> </span><br><span>     printf("=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   GprsCodingScheme cs;</span><br><span style="color: hsl(120, 100%, 40%);">+  CodingScheme cs = UNKNOWN;</span><br><span>   OSMO_ASSERT(!cs);</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(CodingScheme(cs) == UNKNOWN);</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(cs == GprsCodingScheme(UNKNOWN));</span><br><span style="color: hsl(0, 100%, 40%);">-   OSMO_ASSERT(!cs.isCompatible(GPRS));</span><br><span style="color: hsl(0, 100%, 40%);">-    OSMO_ASSERT(!cs.isCompatible(EGPRS_GMSK));</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT(!cs.isCompatible(EGPRS));</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(!mcs_is_compat_kind(cs, GPRS));</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_ASSERT(!mcs_is_compat_kind(cs, EGPRS_GMSK));</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_ASSERT(!mcs_is_compat_kind(cs, EGPRS));</span><br><span> </span><br><span>     last_size_UL = 0;</span><br><span>    last_size_DL = 0;</span><br><span> </span><br><span>        for (i = 0; i < ARRAY_SIZE(gprs_schemes); i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-             GprsCodingScheme current_cs(gprs_schemes[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+         CodingScheme current_cs = gprs_schemes[i];</span><br><span>           OSMO_ASSERT(mcs_is_gprs(current_cs));</span><br><span>                OSMO_ASSERT(!mcs_is_edge(current_cs));</span><br><span>               OSMO_ASSERT(!mcs_is_edge_gmsk(current_cs));</span><br><span style="color: hsl(0, 100%, 40%);">-             OSMO_ASSERT(CodingScheme(current_cs) == gprs_schemes[i]);</span><br><span style="color: hsl(0, 100%, 40%);">-               OSMO_ASSERT(current_cs == GprsCodingScheme(gprs_schemes[i]));</span><br><span style="color: hsl(120, 100%, 40%);">+         OSMO_ASSERT(current_cs == gprs_schemes[i]);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-         OSMO_ASSERT(check_strong_monotonicity(&current_cs, last_size_UL, last_size_DL));</span><br><span style="color: hsl(0, 100%, 40%);">-            last_size_UL = current_cs.maxBytesUL();</span><br><span style="color: hsl(0, 100%, 40%);">-         last_size_DL = current_cs.maxBytesDL();</span><br><span style="color: hsl(120, 100%, 40%);">+               OSMO_ASSERT(check_strong_monotonicity(current_cs, last_size_UL, last_size_DL));</span><br><span style="color: hsl(120, 100%, 40%);">+               last_size_UL = mcs_max_bytes_ul(current_cs);</span><br><span style="color: hsl(120, 100%, 40%);">+          last_size_DL = mcs_max_bytes_dl(current_cs);</span><br><span> </span><br><span>             /* Check header types */</span><br><span style="color: hsl(0, 100%, 40%);">-                OSMO_ASSERT(current_cs.headerTypeData() == HEADER_GPRS_DATA);</span><br><span style="color: hsl(120, 100%, 40%);">+         OSMO_ASSERT(mcs_header_type(current_cs) == HEADER_GPRS_DATA);</span><br><span> </span><br><span>            check_coding_scheme(current_cs, GPRS);</span><br><span>       }</span><br><span>@@ -178,16 +175,15 @@</span><br><span>    last_size_DL = 0;</span><br><span> </span><br><span>        for (i = 0; i < ARRAY_SIZE(egprs_schemes); i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-            GprsCodingScheme current_cs(egprs_schemes[i].s);</span><br><span style="color: hsl(120, 100%, 40%);">+              CodingScheme current_cs = egprs_schemes[i].s;</span><br><span>                OSMO_ASSERT(!mcs_is_gprs(current_cs));</span><br><span>               OSMO_ASSERT(mcs_is_edge(current_cs));</span><br><span>                OSMO_ASSERT(mcs_is_edge_gmsk(current_cs) == !!egprs_schemes[i].is_gmsk);</span><br><span style="color: hsl(0, 100%, 40%);">-                OSMO_ASSERT(CodingScheme(current_cs) == egprs_schemes[i].s);</span><br><span style="color: hsl(0, 100%, 40%);">-            OSMO_ASSERT(current_cs == GprsCodingScheme(egprs_schemes[i].s));</span><br><span style="color: hsl(120, 100%, 40%);">+              OSMO_ASSERT(current_cs == egprs_schemes[i].s);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-              OSMO_ASSERT(check_strong_monotonicity(&current_cs, last_size_UL, last_size_DL));</span><br><span style="color: hsl(0, 100%, 40%);">-            last_size_UL = current_cs.maxBytesUL();</span><br><span style="color: hsl(0, 100%, 40%);">-         last_size_DL = current_cs.maxBytesDL();</span><br><span style="color: hsl(120, 100%, 40%);">+               OSMO_ASSERT(check_strong_monotonicity(current_cs, last_size_UL, last_size_DL));</span><br><span style="color: hsl(120, 100%, 40%);">+               last_size_UL = mcs_max_bytes_ul(current_cs);</span><br><span style="color: hsl(120, 100%, 40%);">+          last_size_DL = mcs_max_bytes_dl(current_cs);</span><br><span> </span><br><span>             if (egprs_schemes[i].is_gmsk)</span><br><span>                        check_coding_scheme(current_cs, EGPRS_GMSK);</span><br><span>@@ -201,7 +197,7 @@</span><br><span> static void test_rlc_unit_decoder()</span><br><span> {</span><br><span>       struct gprs_rlc_data_block_info rdbi = {0};</span><br><span style="color: hsl(0, 100%, 40%);">-     GprsCodingScheme cs;</span><br><span style="color: hsl(120, 100%, 40%);">+  CodingScheme cs;</span><br><span>     uint8_t data[74];</span><br><span>    Decoding::RlcData chunks[16];</span><br><span>        volatile int num_chunks = 0;</span><br><span>@@ -213,7 +209,7 @@</span><br><span> </span><br><span>       /* TS 44.060, B.1 */</span><br><span>         cs = CS4;</span><br><span style="color: hsl(0, 100%, 40%);">-       rdbi.data_len = cs.maxDataBlockBytes();</span><br><span style="color: hsl(120, 100%, 40%);">+       rdbi.data_len = mcs_max_data_block_bytes(cs);</span><br><span>        rdbi.e = 0;</span><br><span>  rdbi.ti = 0;</span><br><span>         rdbi.cv = 15;</span><br><span>@@ -232,12 +228,12 @@</span><br><span>        OSMO_ASSERT(chunks[1].length == 26);</span><br><span>         OSMO_ASSERT(chunks[1].is_complete);</span><br><span>  OSMO_ASSERT(chunks[2].offset == 39);</span><br><span style="color: hsl(0, 100%, 40%);">-    OSMO_ASSERT(chunks[2].length == cs.maxDataBlockBytes() - 39);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(chunks[2].length == mcs_max_data_block_bytes(cs) - 39);</span><br><span>  OSMO_ASSERT(!chunks[2].is_complete);</span><br><span> </span><br><span>     /* TS 44.060, B.2 */</span><br><span>         cs = CS1;</span><br><span style="color: hsl(0, 100%, 40%);">-       rdbi.data_len = cs.maxDataBlockBytes();</span><br><span style="color: hsl(120, 100%, 40%);">+       rdbi.data_len = mcs_max_data_block_bytes(cs);</span><br><span>        rdbi.e = 0;</span><br><span>  rdbi.ti = 0;</span><br><span>         rdbi.cv = 15;</span><br><span>@@ -271,7 +267,7 @@</span><br><span> </span><br><span>      /* TS 44.060, B.3 */</span><br><span>         cs = CS1;</span><br><span style="color: hsl(0, 100%, 40%);">-       rdbi.data_len = cs.maxDataBlockBytes();</span><br><span style="color: hsl(120, 100%, 40%);">+       rdbi.data_len = mcs_max_data_block_bytes(cs);</span><br><span>        rdbi.e = 0;</span><br><span>  rdbi.ti = 0;</span><br><span>         rdbi.cv = 15;</span><br><span>@@ -292,7 +288,7 @@</span><br><span> </span><br><span>      /* TS 44.060, B.4 */</span><br><span>         cs = CS1;</span><br><span style="color: hsl(0, 100%, 40%);">-       rdbi.data_len = cs.maxDataBlockBytes();</span><br><span style="color: hsl(120, 100%, 40%);">+       rdbi.data_len = mcs_max_data_block_bytes(cs);</span><br><span>        rdbi.e = 1;</span><br><span>  rdbi.ti = 0;</span><br><span>         rdbi.cv = 15;</span><br><span>@@ -308,7 +304,7 @@</span><br><span> </span><br><span>      /* TS 44.060, B.6 */</span><br><span>         cs = CS1;</span><br><span style="color: hsl(0, 100%, 40%);">-       rdbi.data_len = cs.maxDataBlockBytes();</span><br><span style="color: hsl(120, 100%, 40%);">+       rdbi.data_len = mcs_max_data_block_bytes(cs);</span><br><span>        rdbi.e = 1;</span><br><span>  rdbi.ti = 0;</span><br><span>         rdbi.cv = 0;</span><br><span>@@ -324,7 +320,7 @@</span><br><span> </span><br><span>       /* TS 44.060, B.8.1 */</span><br><span>       cs = MCS4;</span><br><span style="color: hsl(0, 100%, 40%);">-      rdbi.data_len = cs.maxDataBlockBytes();</span><br><span style="color: hsl(120, 100%, 40%);">+       rdbi.data_len = mcs_max_data_block_bytes(cs);</span><br><span>        rdbi.e = 0;</span><br><span>  rdbi.ti = 0;</span><br><span>         rdbi.cv = 15;</span><br><span>@@ -353,7 +349,7 @@</span><br><span>   * is not consistent with Section 10.3a.1 & 10.3a.2. */</span><br><span> </span><br><span>      cs = MCS2;</span><br><span style="color: hsl(0, 100%, 40%);">-      rdbi.data_len = cs.maxDataBlockBytes();</span><br><span style="color: hsl(120, 100%, 40%);">+       rdbi.data_len = mcs_max_data_block_bytes(cs);</span><br><span>        rdbi.e = 0;</span><br><span>  rdbi.ti = 0;</span><br><span>         rdbi.cv = 15;</span><br><span>@@ -417,7 +413,7 @@</span><br><span>  /* Note that the spec confuses the byte numbering here, too (see above) */</span><br><span> </span><br><span>       cs = MCS2;</span><br><span style="color: hsl(0, 100%, 40%);">-      rdbi.data_len = cs.maxDataBlockBytes();</span><br><span style="color: hsl(120, 100%, 40%);">+       rdbi.data_len = mcs_max_data_block_bytes(cs);</span><br><span>        rdbi.e = 1;</span><br><span>  rdbi.ti = 0;</span><br><span>         rdbi.cv = 0;</span><br><span>@@ -433,7 +429,7 @@</span><br><span> </span><br><span>       /* CS-1, TLLI, last block, single chunk until the end of the block */</span><br><span>        cs = CS1;</span><br><span style="color: hsl(0, 100%, 40%);">-       rdbi.data_len = cs.maxDataBlockBytes();</span><br><span style="color: hsl(120, 100%, 40%);">+       rdbi.data_len = mcs_max_data_block_bytes(cs);</span><br><span>        rdbi.e = 1;</span><br><span>  rdbi.ti = 1;</span><br><span>         rdbi.cv = 0;</span><br><span>@@ -454,7 +450,7 @@</span><br><span> </span><br><span>       /* Like TS 44.060, B.2, first RLC block but with TLLI */</span><br><span>     cs = CS1;</span><br><span style="color: hsl(0, 100%, 40%);">-       rdbi.data_len = cs.maxDataBlockBytes();</span><br><span style="color: hsl(120, 100%, 40%);">+       rdbi.data_len = mcs_max_data_block_bytes(cs);</span><br><span>        rdbi.e = 0;</span><br><span>  rdbi.ti = 1;</span><br><span>         rdbi.cv = 15;</span><br><span>@@ -476,7 +472,7 @@</span><br><span> </span><br><span>      /* Like TS 44.060, B.8.1 but with TLLI */</span><br><span>    cs = MCS4;</span><br><span style="color: hsl(0, 100%, 40%);">-      rdbi.data_len = cs.maxDataBlockBytes();</span><br><span style="color: hsl(120, 100%, 40%);">+       rdbi.data_len = mcs_max_data_block_bytes(cs);</span><br><span>        rdbi.e = 0;</span><br><span>  rdbi.ti = 1;</span><br><span>         rdbi.cv = 15;</span><br><span>@@ -528,7 +524,7 @@</span><br><span> static void test_rlc_unit_encoder()</span><br><span> {</span><br><span>      struct gprs_rlc_data_block_info rdbi = {0};</span><br><span style="color: hsl(0, 100%, 40%);">-     GprsCodingScheme cs;</span><br><span style="color: hsl(120, 100%, 40%);">+  CodingScheme cs;</span><br><span>     uint8_t data[74];</span><br><span>    uint8_t llc_data[1500] = {0,};</span><br><span>       int num_chunks = 0;</span><br><span>@@ -1088,17 +1084,17 @@</span><br><span>                scheme < NUM_SCHEMES;</span><br><span>             scheme = CodingScheme(scheme + 1))</span><br><span>   {</span><br><span style="color: hsl(0, 100%, 40%);">-               GprsCodingScheme cs(scheme);</span><br><span style="color: hsl(120, 100%, 40%);">+          CodingScheme cs(scheme);</span><br><span> </span><br><span>                 for (pattern = 0; pattern <= 0xff; pattern += 0xff) {</span><br><span>                     /* prepare test block */</span><br><span>                     test_block[0] = pattern ^ 0xff;</span><br><span style="color: hsl(0, 100%, 40%);">-                 for (i = 1; i + 1 < cs.maxDataBlockBytes(); i++)</span><br><span style="color: hsl(120, 100%, 40%);">+                   for (i = 1; i + 1 < mcs_max_data_block_bytes(cs); i++)</span><br><span>                            test_block[i] = i;</span><br><span style="color: hsl(0, 100%, 40%);">-                      test_block[cs.maxDataBlockBytes()-1] = pattern ^ 0xff;</span><br><span style="color: hsl(120, 100%, 40%);">+                        test_block[mcs_max_data_block_bytes(cs)-1] = pattern ^ 0xff;</span><br><span> </span><br><span>                     for (block_idx = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                             block_idx < num_data_blocks(cs.headerTypeData());</span><br><span style="color: hsl(120, 100%, 40%);">+                          block_idx < num_data_blocks(mcs_header_type(cs));</span><br><span>                                 block_idx++)</span><br><span>                         {</span><br><span>                            struct gprs_rlc_data_info rlc;</span><br><span>@@ -1110,7 +1106,7 @@</span><br><span> </span><br><span>                           fprintf(stderr,</span><br><span>                                      "Test data block: %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                                      osmo_hexdump(test_block, cs.maxDataBlockBytes()));</span><br><span style="color: hsl(120, 100%, 40%);">+                                    osmo_hexdump(test_block, mcs_max_data_block_bytes(cs)));</span><br><span> </span><br><span>                                 Encoding::rlc_copy_from_aligned_buffer(</span><br><span>                                      &rlc, block_idx, bits, test_block);</span><br><span>@@ -1119,20 +1115,20 @@</span><br><span>                                    "Encoded message block, %s, idx %d, "</span><br><span>                                      "pattern %02x: %s\n",</span><br><span>                                      mcs_name(rlc.cs), block_idx, pattern,</span><br><span style="color: hsl(0, 100%, 40%);">-                                   osmo_hexdump(bits, cs.sizeDL()));</span><br><span style="color: hsl(120, 100%, 40%);">+                                     osmo_hexdump(bits, mcs_size_dl(cs)));</span><br><span> </span><br><span>                            Decoding::rlc_copy_to_aligned_buffer(</span><br><span>                                        &rlc, block_idx, bits, out_block);</span><br><span> </span><br><span>                           fprintf(stderr,</span><br><span>                                      "Out data block: %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                                       osmo_hexdump(out_block, cs.maxDataBlockBytes()));</span><br><span style="color: hsl(120, 100%, 40%);">+                                     osmo_hexdump(out_block, mcs_max_data_block_bytes(cs)));</span><br><span>                              /* restore original bits */</span><br><span>                          Encoding::rlc_copy_from_aligned_buffer(</span><br><span>                                      &rlc, block_idx, bits, saved_block);</span><br><span> </span><br><span>                                 OSMO_ASSERT(memcmp(test_block, out_block,</span><br><span style="color: hsl(0, 100%, 40%);">-                                               rlc.cs.maxDataBlockBytes()) == 0);</span><br><span style="color: hsl(120, 100%, 40%);">+                                            mcs_max_data_block_bytes(rlc.cs)) == 0);</span><br><span> </span><br><span>                                 for (i = 0; i < sizeof(bits); i++)</span><br><span>                                        OSMO_ASSERT(bits[i] == pattern);</span><br><span>@@ -1147,13 +1143,13 @@</span><br><span> </span><br><span>       printf("=== start %s ===\n", __func__);</span><br><span>    gprs_rlc_data_info_init_dl(&rlc,</span><br><span style="color: hsl(0, 100%, 40%);">-                    GprsCodingScheme(CS1), false, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+                     CodingScheme(CS1), false, 0);</span><br><span>        OSMO_ASSERT(rlc.num_data_blocks == 1);</span><br><span>       OSMO_ASSERT(rlc.data_offs_bits[0] == 24);</span><br><span>    OSMO_ASSERT(rlc.block_info[0].data_len == 20);</span><br><span> </span><br><span>   gprs_rlc_data_info_init_dl(&rlc,</span><br><span style="color: hsl(0, 100%, 40%);">-                    GprsCodingScheme(MCS1), false, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+                    CodingScheme(MCS1), false, 0);</span><br><span>       OSMO_ASSERT(rlc.num_data_blocks == 1);</span><br><span>       OSMO_ASSERT(rlc.data_offs_bits[0] == 33);</span><br><span>    OSMO_ASSERT(rlc.block_info[0].data_len == 22);</span><br><span>@@ -1188,7 +1184,7 @@</span><br><span>       tfi = 1;</span><br><span> </span><br><span>         struct gprs_rlc_data_info rlc;</span><br><span style="color: hsl(0, 100%, 40%);">-  GprsCodingScheme cs;</span><br><span style="color: hsl(120, 100%, 40%);">+  CodingScheme cs;</span><br><span>     int rc, offs;</span><br><span> </span><br><span>    /*without padding*/</span><br><span>@@ -1289,7 +1285,7 @@</span><br><span>  uint8_t data[155] = {0};</span><br><span>     struct gprs_rlc_ul_header_egprs_1 *egprs1  = NULL;</span><br><span>   struct gprs_rlc_data_info rlc;</span><br><span style="color: hsl(0, 100%, 40%);">-  GprsCodingScheme cs;</span><br><span style="color: hsl(120, 100%, 40%);">+  CodingScheme cs;</span><br><span>     int rc;</span><br><span> </span><br><span>  egprs1 = (struct gprs_rlc_ul_header_egprs_1 *) data;</span><br><span>diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp</span><br><span>index 36f9ced..f934c6c 100644</span><br><span>--- a/tests/tbf/TbfTest.cpp</span><br><span>+++ b/tests/tbf/TbfTest.cpp</span><br><span>@@ -32,6 +32,7 @@</span><br><span> </span><br><span> extern "C" {</span><br><span> #include "pcu_vty.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "coding_scheme.h"</span><br><span> </span><br><span> #include <osmocom/core/application.h></span><br><span> #include <osmocom/core/msgb.h></span><br><span>@@ -656,7 +657,6 @@</span><br><span>     gprs_rlcmac_bts *bts;</span><br><span>        RlcMacUplink_t ulreq = {0};</span><br><span>  struct gprs_rlc_ul_header_egprs_3 *egprs3  = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-      GprsCodingScheme cs;</span><br><span> </span><br><span>     bts = the_bts->bts_data();</span><br><span> </span><br><span>@@ -732,7 +732,6 @@</span><br><span>       * TS 44.060, B.8.1</span><br><span>   * first seg received first, later second seg</span><br><span>         */</span><br><span style="color: hsl(0, 100%, 40%);">-     cs = MCS3;</span><br><span>   egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;</span><br><span>     egprs3->si = 0;</span><br><span>   egprs3->r = 1;</span><br><span>@@ -805,7 +804,6 @@</span><br><span>      gprs_rlcmac_bts *bts;</span><br><span>        RlcMacUplink_t ulreq = {0};</span><br><span>  struct gprs_rlc_ul_header_egprs_3 *egprs3  = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-      GprsCodingScheme cs;</span><br><span> </span><br><span>     bts = the_bts->bts_data();</span><br><span> </span><br><span>@@ -882,7 +880,6 @@</span><br><span>       * TS 44.060, B.8.1</span><br><span>   * first seg received first, later second seg</span><br><span>         */</span><br><span style="color: hsl(0, 100%, 40%);">-     cs = MCS3;</span><br><span>   egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;</span><br><span>     egprs3->si = 1;</span><br><span>   egprs3->r = 1;</span><br><span>@@ -937,7 +934,6 @@</span><br><span>       */</span><br><span>  memset(data_msg, 0, sizeof(data_msg));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      cs = MCS3;</span><br><span>   egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;</span><br><span>     egprs3->si = 1;</span><br><span>   egprs3->r = 1;</span><br><span>@@ -990,7 +986,6 @@</span><br><span>       * TS 44.060, B.8.1</span><br><span>   * Error scenario with spb as 1</span><br><span>       */</span><br><span style="color: hsl(0, 100%, 40%);">-     cs = MCS3;</span><br><span>   egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;</span><br><span>     egprs3->si = 1;</span><br><span>   egprs3->r = 1;</span><br><span>@@ -1027,7 +1022,6 @@</span><br><span>    for (i = 0; i < 42; i++)</span><br><span>          data_msg[i] = i;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    cs = MCS3;</span><br><span>   egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;</span><br><span>     egprs3->si = 1;</span><br><span>   egprs3->r = 1;</span><br><span>@@ -1051,7 +1045,6 @@</span><br><span>    OSMO_ASSERT(block->spb_status.block_status_ul ==</span><br><span>                          EGPRS_RESEG_FIRST_SEG_RXD);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- cs = MCS3;</span><br><span>   egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;</span><br><span>     egprs3->si = 1;</span><br><span>   egprs3->r = 1;</span><br><span>@@ -1079,7 +1072,6 @@</span><br><span>    OSMO_ASSERT(block->cs_last ==</span><br><span>                     MCS6);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      cs = MCS3;</span><br><span>   egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;</span><br><span>     egprs3->si = 1;</span><br><span>   egprs3->r = 1;</span><br><span>@@ -1103,7 +1095,6 @@</span><br><span>    OSMO_ASSERT(block->spb_status.block_status_ul ==</span><br><span>                          EGPRS_RESEG_FIRST_SEG_RXD);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- cs = MCS3;</span><br><span>   egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;</span><br><span>     egprs3->si = 1;</span><br><span>   egprs3->r = 1;</span><br><span>@@ -1127,7 +1118,6 @@</span><br><span>    OSMO_ASSERT(block->spb_status.block_status_ul ==</span><br><span>                          EGPRS_RESEG_FIRST_SEG_RXD);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- cs = MCS3;</span><br><span>   egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;</span><br><span>     egprs3->si = 1;</span><br><span>   egprs3->r = 1;</span><br><span>@@ -1155,7 +1145,6 @@</span><br><span>    /* Assembled MCS is MCS6. so the size is 74 */</span><br><span>       OSMO_ASSERT(block->len == 74);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   cs = MCS3;</span><br><span>   egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;</span><br><span>     egprs3->si = 1;</span><br><span>   egprs3->r = 1;</span><br><span>@@ -1179,7 +1168,6 @@</span><br><span>    OSMO_ASSERT(block->spb_status.block_status_ul ==</span><br><span>                          EGPRS_RESEG_SECOND_SEG_RXD);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        cs = MCS3;</span><br><span>   egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;</span><br><span>     egprs3->si = 1;</span><br><span>   egprs3->r = 1;</span><br><span>@@ -1251,7 +1239,6 @@</span><br><span>    gprs_rlcmac_ul_tbf *ul_tbf;</span><br><span>  gprs_rlcmac_bts *bts;</span><br><span>        RlcMacUplink_t ulreq = {0};</span><br><span style="color: hsl(0, 100%, 40%);">-     GprsCodingScheme cs;</span><br><span> </span><br><span>     bts = the_bts->bts_data();</span><br><span> </span><br><span>@@ -1318,8 +1305,6 @@</span><br><span>    uint8_t trx_no = 0;</span><br><span>  int tfi = 0;</span><br><span>         struct gprs_rlcmac_pdch *pdch;</span><br><span style="color: hsl(0, 100%, 40%);">-  GprsCodingScheme cs;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> </span><br><span>     /* send fake data with cv=0*/</span><br><span>        struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;</span><br><span>@@ -1400,7 +1385,6 @@</span><br><span>      uint8_t trx_no = 0;</span><br><span>  int tfi = 0;</span><br><span>         struct gprs_rlcmac_pdch *pdch;</span><br><span style="color: hsl(0, 100%, 40%);">-  GprsCodingScheme cs;</span><br><span> </span><br><span>     check_tbf(ul_tbf);</span><br><span>   /* send fake data with cv=0*/</span><br><span>@@ -1482,8 +1466,6 @@</span><br><span>        int tfi = 0;</span><br><span>         gprs_rlcmac_ul_tbf *ul_tbf;</span><br><span>  struct gprs_rlcmac_pdch *pdch;</span><br><span style="color: hsl(0, 100%, 40%);">-  GprsCodingScheme cs;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> </span><br><span>     /* check the TBF */</span><br><span>  ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);</span><br><span>@@ -2363,7 +2345,6 @@</span><br><span>      gprs_rlcmac_bts *bts;</span><br><span>        RlcMacUplink_t ulreq = {0};</span><br><span>  struct gprs_rlc_ul_header_egprs_3 *egprs3  = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-      GprsCodingScheme cs;</span><br><span>         Packet_Resource_Request_t *presreq = NULL;</span><br><span>   MS_Radio_Access_capability_t *pmsradiocap = NULL;</span><br><span>    Multislot_capability_t *pmultislotcap = NULL;</span><br><span>@@ -2428,7 +2409,6 @@</span><br><span>        OSMO_ASSERT(ms->ta() == qta/4);</span><br><span>   OSMO_ASSERT(ms->ul_tbf() == ul_tbf);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     cs = MCS4;</span><br><span>   egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;</span><br><span>     egprs3->si = 0;</span><br><span>   egprs3->r = 1;</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-pcu/+/18351">change 18351</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-pcu/+/18351"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-pcu </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Ie9ce2144ba9e8dbba9704d4e0000a2929e3e41df </div>
<div style="display:none"> Gerrit-Change-Number: 18351 </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>