tbf: Pass the MS object around instead of old_tbf

Currently the old TBF (either uplink or downlink) is passed around at
TBF allocation mainly to get information about the MS. To implement
more complex allocation algorithms, the MS object itself will be
needed anyway.

This commit replaces the old_tbf arguments by MS object arguments.

Sponsored-by: On-Waves ehf
diff --git a/src/bts.cpp b/src/bts.cpp
index 4ca53d5..8e56543 100644
--- a/src/bts.cpp
+++ b/src/bts.cpp
@@ -894,7 +894,7 @@
 
 		/* This call will register the new TBF with the MS on success */
 		tbf_alloc_ul(bts_data(), tbf->trx->trx_no, tbf->ms_class(),
-			tbf->tlli(), tbf->ta(), tbf);
+			tbf->tlli(), tbf->ta(), tbf->ms());
 
 		/* schedule uplink assignment */
 		tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS;
diff --git a/src/bts.h b/src/bts.h
index 2ed5030..f2db318 100644
--- a/src/bts.h
+++ b/src/bts.h
@@ -37,6 +37,7 @@
 #include <stdint.h>
 
 struct BTS;
+struct GprsMs;
 
 /*
  * PDCH instance
@@ -138,7 +139,7 @@
 	uint8_t n3105;
 	struct gprs_rlcmac_trx trx[8];
 	int (*alloc_algorithm)(struct gprs_rlcmac_bts *bts,
-		struct gprs_rlcmac_tbf *old_tbf,
+		struct GprsMs *ms,
 		struct gprs_rlcmac_tbf *tbf, uint32_t cust, uint8_t single);
 	uint32_t alloc_algorithm_curst; /* options to customize algorithm */
 	uint8_t force_two_phase;
diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h
index 6f8a7a4..dab3338 100644
--- a/src/gprs_rlcmac.h
+++ b/src/gprs_rlcmac.h
@@ -42,6 +42,7 @@
 struct gprs_rlcmac_tbf;
 struct gprs_rlcmac_bts;
 struct BTS;
+struct GprsMs;
 
 #ifdef __cplusplus
 /*
@@ -95,11 +96,11 @@
 extern "C" {
 #endif
 int alloc_algorithm_a(struct gprs_rlcmac_bts *bts,
-	struct gprs_rlcmac_tbf *old_tbf,
+	struct GprsMs *ms,
 	struct gprs_rlcmac_tbf *tbf, uint32_t cust, uint8_t single);
 
 int alloc_algorithm_b(struct gprs_rlcmac_bts *bts,
-	struct gprs_rlcmac_tbf *old_tbf,
+	struct GprsMs *ms,
 	struct gprs_rlcmac_tbf *tbf, uint32_t cust, uint8_t single);
 #ifdef __cplusplus
 }
diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp
index e8bedad..bae1ea5 100644
--- a/src/gprs_rlcmac_ts_alloc.cpp
+++ b/src/gprs_rlcmac_ts_alloc.cpp
@@ -23,6 +23,7 @@
 #include <gprs_debug.h>
 #include <bts.h>
 #include <tbf.h>
+#include <gprs_ms.h>
 
 #include <errno.h>
 
@@ -139,7 +140,7 @@
  * Assign single slot for uplink and downlink
  */
 int alloc_algorithm_a(struct gprs_rlcmac_bts *bts,
-	struct gprs_rlcmac_tbf *old_tbf,
+	GprsMs *ms,
 	struct gprs_rlcmac_tbf *tbf, uint32_t cust, uint8_t single)
 {
 	struct gprs_rlcmac_pdch *pdch;
@@ -261,16 +262,21 @@
 	return rx_window;
 }
 
-static int reduce_rx_window(const int ms_type, const struct gprs_rlcmac_tbf *old_tbf,
+static int reduce_rx_window(const int ms_type, const GprsMs *ms,
 				const int Tt, const int Tr,
 				int *rx_window,
 				uint8_t *rx_win_min, uint8_t *rx_win_max)
 {
+	gprs_rlcmac_ul_tbf *ul_tbf;
+
 	if (ms_type != 1)
 		return 0;
-	if (!old_tbf)
+	if (!ms)
 		return 0;
-	if (old_tbf->direction != GPRS_RLCMAC_UL_TBF)
+
+	ul_tbf = ms->ul_tbf();
+
+	if (!ul_tbf)
 		return 0;
 
 	uint8_t collide = 0, ul_usage = 0;
@@ -278,7 +284,7 @@
 	/* calculate mask of colliding slots */
 	for (uint8_t ts_no = 0; ts_no < 8; ts_no++) {
 		int j;
-		if (!old_tbf->pdch[ts_no])
+		if (!ul_tbf->pdch[ts_no])
 			continue;
 
 		ul_usage |= (1 << ts_no);
@@ -525,7 +531,7 @@
  *
  */
 int alloc_algorithm_b(struct gprs_rlcmac_bts *bts,
-	struct gprs_rlcmac_tbf *old_tbf,
+	GprsMs *ms,
 	struct gprs_rlcmac_tbf *tbf, uint32_t cust, uint8_t single)
 {
 	const struct gprs_ms_multislot_class *ms_class;
@@ -592,7 +598,7 @@
 
 
 	/* reduce window, if existing uplink slots collide RX window */
-	int rc = reduce_rx_window(ms_class->type, old_tbf, Tt, Tr,
+	int rc = reduce_rx_window(ms_class->type, ms, Tt, Tr,
 				&rx_window, &rx_win_min, &rx_win_max);
 	if (rc < 0)
 		return rc;
diff --git a/src/tbf.cpp b/src/tbf.cpp
index 3252d0a..5eda01e 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -184,7 +184,7 @@
 
 gprs_rlcmac_ul_tbf *tbf_alloc_ul(struct gprs_rlcmac_bts *bts,
 	int8_t use_trx, uint8_t ms_class,
-	uint32_t tlli, uint8_t ta, struct gprs_rlcmac_tbf *dl_tbf)
+	uint32_t tlli, uint8_t ta, GprsMs *ms)
 {
 	uint8_t trx;
 	struct gprs_rlcmac_ul_tbf *tbf;
@@ -199,7 +199,7 @@
 		return NULL;
 	}
 	/* use multislot class of downlink TBF */
-	tbf = tbf_alloc_ul_tbf(bts, dl_tbf, tfi, trx, ms_class, 0);
+	tbf = tbf_alloc_ul_tbf(bts, ms, tfi, trx, ms_class, 0);
 	if (!tbf) {
 		LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n");
 		/* FIXME: send reject */
@@ -274,7 +274,6 @@
 
 int gprs_rlcmac_tbf::update()
 {
-	struct gprs_rlcmac_tbf *ul_tbf = NULL;
 	struct gprs_rlcmac_bts *bts_data = bts->bts_data();
 	int rc;
 
@@ -283,11 +282,8 @@
 	if (direction != GPRS_RLCMAC_DL_TBF)
 		return -EINVAL;
 
-	if (ms())
-		ul_tbf = ms()->ul_tbf();
-
 	tbf_unlink_pdch(this);
-	rc = bts_data->alloc_algorithm(bts_data, ul_tbf, this, bts_data->alloc_algorithm_curst, 0);
+	rc = bts_data->alloc_algorithm(bts_data, ms(), this, bts_data->alloc_algorithm_curst, 0);
 	/* if no resource */
 	if (rc < 0) {
 		LOGP(DRLCMAC, LOGL_ERROR, "No resource after update???\n");
@@ -450,7 +446,7 @@
 }
 
 static int setup_tbf(struct gprs_rlcmac_tbf *tbf, struct gprs_rlcmac_bts *bts,
-	struct gprs_rlcmac_tbf *old_tbf, uint8_t tfi, uint8_t trx,
+	GprsMs *ms, uint8_t tfi, uint8_t trx,
 	uint8_t ms_class, uint8_t single_slot)
 {
 	int rc;
@@ -470,7 +466,7 @@
 	tbf->trx = &bts->trx[trx];
 	tbf->set_ms_class(ms_class);
 	/* select algorithm */
-	rc = bts->alloc_algorithm(bts, old_tbf, tbf, bts->alloc_algorithm_curst,
+	rc = bts->alloc_algorithm(bts, ms, tbf, bts->alloc_algorithm_curst,
 		single_slot);
 	/* if no resource */
 	if (rc < 0) {
@@ -493,7 +489,7 @@
 
 
 struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts,
-	struct gprs_rlcmac_tbf *old_tbf, uint8_t tfi, uint8_t trx,
+	GprsMs *ms, uint8_t tfi, uint8_t trx,
 	uint8_t ms_class, uint8_t single_slot)
 {
 	struct gprs_rlcmac_ul_tbf *tbf;
@@ -512,7 +508,7 @@
 		return NULL;
 
 	tbf->direction = GPRS_RLCMAC_UL_TBF;
-	rc = setup_tbf(tbf, bts, old_tbf, tfi, trx, ms_class, single_slot);
+	rc = setup_tbf(tbf, bts, ms, tfi, trx, ms_class, single_slot);
 	/* if no resource */
 	if (rc < 0) {
 		talloc_free(tbf);
@@ -522,8 +518,8 @@
 	llist_add(&tbf->list.list, &bts->ul_tbfs);
 	tbf->bts->tbf_ul_created();
 
-	if (old_tbf && old_tbf->ms())
-		tbf->set_ms(old_tbf->ms());
+	if (ms)
+		tbf->set_ms(ms);
 
 	if (tbf->ms())
 		tbf->ms()->attach_ul_tbf(tbf);
@@ -532,7 +528,7 @@
 }
 
 struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts,
-	struct gprs_rlcmac_tbf *old_tbf, uint8_t tfi, uint8_t trx,
+	GprsMs *ms, uint8_t tfi, uint8_t trx,
 	uint8_t ms_class, uint8_t single_slot)
 {
 	struct gprs_rlcmac_dl_tbf *tbf;
@@ -551,7 +547,7 @@
 		return NULL;
 
 	tbf->direction = GPRS_RLCMAC_DL_TBF;
-	rc = setup_tbf(tbf, bts, old_tbf, tfi, trx, ms_class, single_slot);
+	rc = setup_tbf(tbf, bts, ms, tfi, trx, ms_class, single_slot);
 	/* if no resource */
 	if (rc < 0) {
 		talloc_free(tbf);
@@ -567,8 +563,7 @@
 	gettimeofday(&tbf->m_bw.dl_bw_tv, NULL);
 	gettimeofday(&tbf->m_bw.dl_loss_tv, NULL);
 
-	if (old_tbf && old_tbf->ms())
-		tbf->set_ms(old_tbf->ms());
+	tbf->set_ms(ms);
 
 	if (tbf->ms())
 		tbf->ms()->attach_dl_tbf(tbf);
diff --git a/src/tbf.h b/src/tbf.h
index 0f53a27..cf8cdfc 100644
--- a/src/tbf.h
+++ b/src/tbf.h
@@ -240,16 +240,15 @@
 
 struct gprs_rlcmac_ul_tbf *tbf_alloc_ul(struct gprs_rlcmac_bts *bts,
 	int8_t use_trx, uint8_t ms_class,
-	uint32_t tlli, uint8_t ta, struct gprs_rlcmac_tbf *dl_tbf);
+	uint32_t tlli, uint8_t ta, GprsMs *ms);
 
 struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts,
-	struct gprs_rlcmac_tbf *old_tbf,
+	GprsMs *ms,
 	uint8_t tfi, uint8_t trx,
 	uint8_t ms_class, uint8_t single_slot);
 
 struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts,
-	struct gprs_rlcmac_tbf *old_tbf,
-	uint8_t tfi, uint8_t trx,
+	GprsMs *ms, uint8_t tfi, uint8_t trx,
 	uint8_t ms_class, uint8_t single_slot);
 
 void tbf_free(struct gprs_rlcmac_tbf *tbf);
diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp
index 853821c..c7a04bf 100644
--- a/src/tbf_dl.cpp
+++ b/src/tbf_dl.cpp
@@ -155,6 +155,7 @@
 		ul_tbf = ms->ul_tbf();
 		ta = ms->ta();
 	}
+	/* TODO: if (!ms) create MS before tbf_alloc is called? */
 
 	if (ul_tbf && ul_tbf->m_contention_resolution_done
 	 && !ul_tbf->m_final_ack_sent) {
@@ -172,7 +173,7 @@
 	tfi = bts->bts->tfi_find_free(GPRS_RLCMAC_DL_TBF, &trx, use_trx);
 	if (tfi >= 0)
 		/* set number of downlink slots according to multislot class */
-		dl_tbf = tbf_alloc_dl_tbf(bts, ul_tbf, tfi, trx, ms_class, ss);
+		dl_tbf = tbf_alloc_dl_tbf(bts, ms, tfi, trx, ms_class, ss);
 
 	if (!dl_tbf) {
 		LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n");
diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp
index 2211e92..ebd57c5 100644
--- a/tests/alloc/AllocTest.cpp
+++ b/tests/alloc/AllocTest.cpp
@@ -37,14 +37,14 @@
 int16_t spoof_mnc = 0, spoof_mcc = 0;
 
 static gprs_rlcmac_tbf *tbf_alloc(struct gprs_rlcmac_bts *bts,
-		struct gprs_rlcmac_tbf *old_tbf, gprs_rlcmac_tbf_direction dir,
+		GprsMs *ms, gprs_rlcmac_tbf_direction dir,
 		uint8_t tfi, uint8_t trx,
 		uint8_t ms_class, uint8_t single_slot)
 {
 	if (dir == GPRS_RLCMAC_UL_TBF)
-		return tbf_alloc_ul_tbf(bts, old_tbf, tfi, trx, ms_class, single_slot);
+		return tbf_alloc_ul_tbf(bts, ms, tfi, trx, ms_class, single_slot);
 	else
-		return tbf_alloc_dl_tbf(bts, old_tbf, tfi, trx, ms_class, single_slot);
+		return tbf_alloc_dl_tbf(bts, ms, tfi, trx, ms_class, single_slot);
 }
 
 static void test_alloc_a(gprs_rlcmac_tbf_direction dir, const int count)
@@ -152,7 +152,7 @@
 		/* assume final ack has not been sent */
 		tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
 		OSMO_ASSERT(tfi >= 0);
-		dl_tbf = tbf_alloc_dl_tbf(bts, ul_tbf, tfi, trx_no, ms_class, 0);
+		dl_tbf = tbf_alloc_dl_tbf(bts, ul_tbf->ms(), tfi, trx_no, ms_class, 0);
 		OSMO_ASSERT(dl_tbf);
 		dump_assignment(dl_tbf, "DL");
 
@@ -194,7 +194,7 @@
 
 		tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
 		OSMO_ASSERT(tfi >= 0);
-		ul_tbf = tbf_alloc_ul_tbf(bts, dl_tbf, tfi, trx_no, ms_class, 0);
+		ul_tbf = tbf_alloc_ul_tbf(bts, dl_tbf->ms(), tfi, trx_no, ms_class, 0);
 		ul_tbf->update_ms(0x23, GPRS_RLCMAC_UL_TBF);
 		ul_tbf->m_contention_resolution_done = 1;
 		OSMO_ASSERT(ul_tbf);
@@ -241,7 +241,7 @@
 		/* assume final ack has not been sent */
 		tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
 		OSMO_ASSERT(tfi >= 0);
-		dl_tbf = tbf_alloc_dl_tbf(bts, ul_tbf, tfi, trx_no, ms_class, 0);
+		dl_tbf = tbf_alloc_dl_tbf(bts, ul_tbf->ms(), tfi, trx_no, ms_class, 0);
 		OSMO_ASSERT(dl_tbf);
 		dump_assignment(dl_tbf, "DL");
 
@@ -304,7 +304,7 @@
 		/* assume final ack has not been sent */
 		tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
 		OSMO_ASSERT(tfi >= 0);
-		dl_tbf = tbf_alloc_dl_tbf(bts, ul_tbf, tfi, trx_no, ms_class, 0);
+		dl_tbf = tbf_alloc_dl_tbf(bts, ul_tbf->ms(), tfi, trx_no, ms_class, 0);
 		OSMO_ASSERT(dl_tbf);
 
 		/* verify that both are on the same ts */
@@ -348,7 +348,7 @@
 
 		tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
 		OSMO_ASSERT(tfi >= 0);
-		ul_tbf = tbf_alloc_ul_tbf(bts, dl_tbf, tfi, trx_no, ms_class, 0);
+		ul_tbf = tbf_alloc_ul_tbf(bts, dl_tbf->ms(), tfi, trx_no, ms_class, 0);
 		OSMO_ASSERT(ul_tbf);
 		ul_tbf->update_ms(0x23, GPRS_RLCMAC_UL_TBF);
 		ul_tbf->m_contention_resolution_done = 1;
diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp
index b963e37..99686b9 100644
--- a/tests/tbf/TbfTest.cpp
+++ b/tests/tbf/TbfTest.cpp
@@ -80,7 +80,7 @@
 	dl_tbf->set_ta(4);
 
 	gprs_rlcmac_tbf *ul_tbf = tbf_alloc_ul_tbf(the_bts.bts_data(),
-						dl_tbf, 0,
+						dl_tbf->ms(), 0,
 						0, 0, 0);
 	ul_tbf->update_ms(0x2342, GPRS_RLCMAC_UL_TBF);