ms: Add support for slot reservation

In contrast to the slots currently used by existing TBFs, the
reserved slots refer to the time slots that can be used for newly
allocated TBFs without causing conflicts (given that the first common
TS does not change). They correspond to the potential use of the
PDCHs and can be used to achieve a more uniform slot allocation.

This commit adds bit set based methods to GprsMs and gprs_rlcmac_trx
and a counter to gprs_rlcmac_pdch. The current TRX will also be
stored in the MS object.

Sponsored-by: On-Waves ehf
diff --git a/src/gprs_ms.cpp b/src/gprs_ms.cpp
index 4c0ecfd..f62facf 100644
--- a/src/gprs_ms.cpp
+++ b/src/gprs_ms.cpp
@@ -91,7 +91,10 @@
 	m_ref(0),
 	m_list(this),
 	m_delay(0),
-	m_nack_rate_dl(0)
+	m_nack_rate_dl(0),
+	m_reserved_dl_slots(0),
+	m_reserved_ul_slots(0),
+	m_current_trx(NULL)
 {
 	LOGP(DRLCMAC, LOGL_INFO, "Creating MS object, TLLI = 0x%08x\n", tlli);
 
@@ -115,6 +118,8 @@
 {
 	LOGP(DRLCMAC, LOGL_INFO, "Destroying MS object, TLLI = 0x%08x\n", tlli());
 
+	set_reserved_slots(NULL, 0, 0);
+
 	if (osmo_timer_pending(&m_timer))
 		osmo_timer_del(&m_timer);
 
@@ -240,8 +245,12 @@
 	if (tbf->ms() == this)
 		tbf->set_ms(NULL);
 
-	if (!m_dl_tbf && !m_ul_tbf && tlli() != 0)
-		start_timer();
+	if (!m_dl_tbf && !m_ul_tbf) {
+		set_reserved_slots(NULL, 0, 0);
+
+		if (tlli() != 0)
+			start_timer();
+	}
 
 	update_status();
 }
@@ -529,6 +538,28 @@
 	return -1;
 }
 
+void GprsMs::set_reserved_slots(gprs_rlcmac_trx *trx,
+	uint8_t ul_slots, uint8_t dl_slots)
+{
+	if (m_current_trx) {
+		m_current_trx->unreserve_slots(GPRS_RLCMAC_DL_TBF,
+			m_reserved_dl_slots);
+		m_current_trx->unreserve_slots(GPRS_RLCMAC_UL_TBF,
+			m_reserved_ul_slots);
+		m_reserved_dl_slots = 0;
+		m_reserved_ul_slots = 0;
+	}
+	m_current_trx = trx;
+	if (trx) {
+		m_reserved_dl_slots = dl_slots;
+		m_reserved_ul_slots = ul_slots;
+		m_current_trx->reserve_slots(GPRS_RLCMAC_DL_TBF,
+			m_reserved_dl_slots);
+		m_current_trx->reserve_slots(GPRS_RLCMAC_UL_TBF,
+			m_reserved_ul_slots);
+	}
+}
+
 gprs_rlcmac_tbf *GprsMs::tbf(enum gprs_rlcmac_tbf_direction dir) const
 {
 	switch (dir) {