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/gprs_ms.h b/src/gprs_ms.h
index f9b63f2..246f71e 100644
--- a/src/gprs_ms.h
+++ b/src/gprs_ms.h
@@ -74,6 +74,8 @@
 	bool check_tlli(uint32_t tlli);
 
 	void reset();
+	GprsCodingScheme::Mode mode() const;
+	void set_mode(GprsCodingScheme::Mode mode);
 
 	const char *imsi() const;
 	void set_imsi(const char *imsi);
@@ -85,8 +87,10 @@
 	void set_ms_class(uint8_t ms_class);
 	void set_egprs_ms_class(uint8_t ms_class);
 
-	uint8_t current_cs_ul() const;
-	uint8_t current_cs_dl() const;
+	GprsCodingScheme current_cs_ul() const;
+	GprsCodingScheme current_cs_dl() const;
+	GprsCodingScheme max_cs_ul() const;
+	GprsCodingScheme max_cs_dl() const;
 
 	int first_common_ts() const;
 	uint8_t dl_slots() const;
@@ -134,6 +138,7 @@
 	void unref();
 	void start_timer();
 	void stop_timer();
+	void update_cs_ul(const pcu_l1_meas*);
 
 private:
 	BTS *m_bts;
@@ -152,8 +157,8 @@
 	uint8_t m_ms_class;
 	uint8_t m_egprs_ms_class;
 	/* current coding scheme */
-	uint8_t m_current_cs_ul;
-	uint8_t m_current_cs_dl;
+	GprsCodingScheme m_current_cs_ul;
+	GprsCodingScheme m_current_cs_dl;
 
 	gprs_llc_queue m_llc_queue;
 
@@ -172,6 +177,7 @@
 	gprs_rlcmac_trx *m_current_trx;
 
 	struct gprs_codel *m_codel_state;
+	GprsCodingScheme::Mode m_mode;
 };
 
 inline bool GprsMs::is_idle() const
@@ -220,11 +226,16 @@
 	return m_egprs_ms_class;
 }
 
-inline uint8_t GprsMs::current_cs_ul() const
+inline GprsCodingScheme GprsMs::current_cs_ul() const
 {
 	return m_current_cs_ul;
 }
 
+inline GprsCodingScheme::Mode GprsMs::mode() const
+{
+	return m_mode;
+}
+
 inline void GprsMs::set_timeout(unsigned secs)
 {
 	m_delay = secs;