edge: Replace integer cs by GprsCodingScheme

Currently the TBF and MS object use a plain integer value
(current_cs) to manage the coding scheme. This makes it difficult to
support the MCS schemes. GprsCodingScheme supports a partial ordering
of these values (CS and MCS) and provides safe increment and
decrement methods.

Use the GprsCodingScheme type instead of integer for cs fields and
variables. Add a 'mode' to GprsMs which can be set to either GPRS,
EGPRS, or EGPRS_GMSK which also set the initial values of
current_cs_ul/dl. Select the mode based on max_mcs_ul and max_mcs_dl.

Sponsored-by: On-Waves ehf
diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp
index e805992..9e73a0e 100644
--- a/src/tbf_dl.cpp
+++ b/src/tbf_dl.cpp
@@ -425,21 +425,15 @@
 	uint16_t space, chunk;
 	gprs_rlc_data *rlc_data;
 	const uint16_t bsn = m_window.v_s();
-	uint8_t cs_n = 1;
+	GprsCodingScheme cs = current_cs();
 
 	if (m_llc.frame_length() == 0)
 		schedule_next_frame();
 
-	cs_n = current_cs();
+	LOGP(DRLCMACDL, LOGL_DEBUG, "- Sending new block at BSN %d, CS=%s\n",
+		m_window.v_s(), cs.name());
 
-	LOGP(DRLCMACDL, LOGL_DEBUG, "- Sending new block at BSN %d, CS=%d\n",
-		m_window.v_s(), cs_n);
-
-	OSMO_ASSERT(cs_n >= 1);
-	OSMO_ASSERT(cs_n <= 4);
-
-	/* TODO: Use GprsCodingScheme everywhere and remove cast */
-	GprsCodingScheme cs((GprsCodingScheme::Scheme)cs_n);
+	OSMO_ASSERT(cs.isValid());
 
 	/* total length of block, including spare bits */
 	const uint8_t block_length = cs.sizeDL();
@@ -748,8 +742,7 @@
 
 		/* Get statistics for current CS */
 
-		/* TODO: Use GprsCodingScheme everywhere and remove cast */
-		if (rlc_data->cs != GprsCodingScheme((GprsCodingScheme::Scheme)current_cs())) {
+		if (rlc_data->cs != current_cs()) {
 			/* This block has already been encoded with a different
 			 * CS, so it doesn't help us to decide, whether the
 			 * current CS is ok. Ignore it. */