Unify BTS into a C usable structure

Previous work on BTS class started to get stuff out of the C++ struct
 into a C struct (BTS -> struct gprs_glcmac_bts) so that some parts of
it were accessible from C code. Doing so, however, ended up being messy
too, since all code needs to be switching from one object to another,
which actually refer to the same logical component.

Let's instead rejoin the structures and make sure the struct is
accessible and usable from both C and C++ code by rewriting all methods
to be C compatible and converting 3 allocated suboject as pointers.
This way BTS can internally still use those C++ objects while providing
a clean APi to both C and C++ code.

Change-Id: I7d12c896c5ded659ca9d3bff4cf3a3fc857db9dd
diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp
index 249c268..20f5286 100644
--- a/tests/alloc/AllocTest.cpp
+++ b/tests/alloc/AllocTest.cpp
@@ -21,7 +21,9 @@
 #include "gprs_debug.h"
 #include "tbf.h"
 #include "tbf_ul.h"
+#include "tbf_dl.h"
 #include "bts.h"
+#include "gprs_ms.h"
 
 #include <string.h>
 #include <stdio.h>
@@ -51,17 +53,17 @@
 		return tbf_alloc_dl_tbf(bts, ms, use_trx, single_slot);
 }
 
-static void check_tfi_usage(BTS *the_bts)
+static void check_tfi_usage(struct gprs_rlcmac_bts *bts)
 {
 	int pdch_no;
 
 	struct gprs_rlcmac_tbf *tfi_usage[8][8][2][32] = {{{{NULL}}}};
-	LListHead<gprs_rlcmac_tbf> *tbf_lists[2] = {
-		&the_bts->ul_tbfs(),
-		&the_bts->dl_tbfs()
+	struct llist_head *tbf_lists[2] = {
+		&bts->ul_tbfs,
+		&bts->dl_tbfs
 	};
 
-	LListHead<gprs_rlcmac_tbf> *pos;
+	struct llist_item *pos;
 	gprs_rlcmac_tbf *tbf;
 	unsigned list_idx;
 	struct gprs_rlcmac_tbf **tbf_var;
@@ -69,8 +71,8 @@
 	for (list_idx = 0; list_idx < ARRAY_SIZE(tbf_lists); list_idx += 1)
 	{
 
-		llist_for_each(pos, tbf_lists[list_idx]) {
-			tbf = pos->entry();
+		llist_for_each_entry(pos, tbf_lists[list_idx], list) {
+			tbf = (struct gprs_rlcmac_tbf *)pos->entry;
 			for (pdch_no = 0; pdch_no < 8; pdch_no += 1) {
 				struct gprs_rlcmac_pdch *pdch = tbf->pdch[pdch_no];
 				if (pdch == NULL)
@@ -86,14 +88,14 @@
 				if (tbf->direction == GPRS_RLCMAC_DL_TBF) {
 					OSMO_ASSERT(pdch->dl_tbf_by_tfi(
 							tbf->tfi()) == tbf);
-					OSMO_ASSERT(the_bts->dl_tbf_by_tfi(
+					OSMO_ASSERT(bts_dl_tbf_by_tfi(bts,
 							tbf->tfi(),
 							tbf->trx->trx_no,
 							pdch_no) == tbf);
 				} else {
 					OSMO_ASSERT(pdch->ul_tbf_by_tfi(
 							tbf->tfi()) == tbf);
-					OSMO_ASSERT(the_bts->ul_tbf_by_tfi(
+					OSMO_ASSERT(bts_ul_tbf_by_tfi(bts,
 							tbf->tfi(),
 							tbf->trx->trx_no,
 							pdch_no) == tbf);
@@ -112,14 +114,12 @@
 	int tfi;
 	int i;
 	uint8_t used_trx, tmp_trx;
-	BTS the_bts(the_pcu);
+	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
 	GprsMs *ms;
-	struct gprs_rlcmac_bts *bts;
 	struct gprs_rlcmac_tbf *tbfs[32*8+1] = { 0, };
 
 	printf("Testing alloc_a direction(%d)\n", dir);
 
-	bts = the_bts.bts_data();
 	the_pcu->alloc_algorithm = alloc_algorithm_a;
 
 	struct gprs_rlcmac_trx *trx = &bts->trx[0];
@@ -136,17 +136,17 @@
 	 * least this part is working okay.
 	 */
 	for (i = 0; i < (int)ARRAY_SIZE(tbfs); ++i) {
-		ms = bts->bts->ms_alloc(0, 0);
+		ms = bts_alloc_ms(bts, 0, 0);
 		tbfs[i] = tbf_alloc(bts, ms, dir, -1, 0);
 		if (tbfs[i] == NULL)
 			break;
 
 		used_trx = tbfs[i]->trx->trx_no;
-		tfi = the_bts.tfi_find_free(dir, &tmp_trx, used_trx);
+		tfi = bts_tfi_find_free(bts, dir, &tmp_trx, used_trx);
 		OSMO_ASSERT(tbfs[i]->tfi() != tfi);
 	}
 
-	check_tfi_usage(&the_bts);
+	check_tfi_usage(bts);
 
 	OSMO_ASSERT(i == count);
 
@@ -154,10 +154,11 @@
 		if (tbfs[i])
 			tbf_free(tbfs[i]);
 
-	ms = bts->bts->ms_alloc(0, 0);
+	ms = bts_alloc_ms(bts, 0, 0);
 	tbfs[0] = tbf_alloc(bts, ms, dir, -1, 0);
 	OSMO_ASSERT(tbfs[0]);
 	tbf_free(tbfs[0]);
+	talloc_free(bts);
 }
 
 static void test_alloc_a()
@@ -205,8 +206,7 @@
 static inline bool test_alloc_b_ul_dl(bool ts0, bool ts1, bool ts2, bool ts3, bool ts4, bool ts5, bool ts6, bool ts7,
 				      uint8_t ms_class, bool verbose)
 {
-	BTS the_bts(the_pcu);
-	struct gprs_rlcmac_bts *bts = the_bts.bts_data();
+	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
 	GprsMs *ms;
 	gprs_rlcmac_ul_tbf *ul_tbf;
 	gprs_rlcmac_dl_tbf *dl_tbf;
@@ -218,7 +218,7 @@
 
 	enable_ts_on_bts(bts, ts0, ts1, ts2, ts3, ts4, ts5, ts6, ts7);
 
-	ms = the_bts.ms_alloc(ms_class, 0);
+	ms = bts_alloc_ms(bts, ms_class, 0);
 	/* Avoid delaying free to avoid tons of to-be-freed ms objects queuing */
 	ms_set_timeout(ms, 0);
 	ul_tbf = tbf_alloc_ul_tbf(bts, ms, -1, true);
@@ -239,19 +239,18 @@
 
 	OSMO_ASSERT(dl_tbf->first_common_ts == ul_tbf->first_common_ts);
 
-	check_tfi_usage(&the_bts);
+	check_tfi_usage(bts);
 
 	tbf_free(dl_tbf);
 	tbf_free(ul_tbf);
-
+	talloc_free(bts);
 	return true;
 }
 
 static inline bool test_alloc_b_dl_ul(bool ts0, bool ts1, bool ts2, bool ts3, bool ts4, bool ts5, bool ts6, bool ts7,
 				      uint8_t ms_class, bool verbose)
 {
-	BTS the_bts(the_pcu);
-	struct gprs_rlcmac_bts *bts = the_bts.bts_data();
+	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
 	GprsMs *ms;
 	gprs_rlcmac_ul_tbf *ul_tbf;
 	gprs_rlcmac_dl_tbf *dl_tbf;
@@ -263,7 +262,7 @@
 
 	enable_ts_on_bts(bts, ts0, ts1, ts2, ts3, ts4, ts5, ts6, ts7);
 
-	ms = the_bts.ms_alloc(ms_class, 0);
+	ms = bts_alloc_ms(bts, ms_class, 0);
 	/* Avoid delaying free to avoid tons of to-be-freed ms objects queuing */
 	ms_set_timeout(ms, 0);
 	dl_tbf = tbf_alloc_dl_tbf(bts, ms, -1, true);
@@ -292,18 +291,17 @@
 	dump_assignment(dl_tbf, "DL", verbose);
 	OSMO_ASSERT(dl_tbf->first_common_ts == ul_tbf->first_common_ts);
 
-	check_tfi_usage(&the_bts);
+	check_tfi_usage(bts);
 
 	tbf_free(dl_tbf);
 	tbf_free(ul_tbf);
-
+	talloc_free(bts);
 	return true;
 }
 
 static inline bool test_alloc_b_jolly(uint8_t ms_class)
 {
-	BTS the_bts(the_pcu);
-	struct gprs_rlcmac_bts *bts = the_bts.bts_data();
+	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
 	GprsMs *ms;
 	int tfi;
 	uint8_t trx_no;
@@ -315,9 +313,9 @@
 
 	enable_ts_on_bts(bts, false, true, true, true, true, false, false, false);
 
-	tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
+	tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
 	OSMO_ASSERT(tfi >= 0);
-	ms = the_bts.ms_alloc(ms_class, 0);
+	ms = bts_alloc_ms(bts, ms_class, 0);
 	/* Avoid delaying free to avoid tons of to-be-freed ms objects queuing */
 	ms_set_timeout(ms, 0);
 	ul_tbf = tbf_alloc_ul_tbf(bts, ms, -1, false);
@@ -338,11 +336,11 @@
 
 	OSMO_ASSERT(dl_tbf->first_common_ts == ul_tbf->first_common_ts);
 
-	check_tfi_usage(&the_bts);
+	check_tfi_usage(bts);
 
 	tbf_free(dl_tbf);
 	tbf_free(ul_tbf);
-
+	talloc_free(bts);
 	return true;
 }
 
@@ -459,16 +457,13 @@
 	}
 }
 
-static GprsMs *alloc_tbfs(BTS *the_bts, struct GprsMs *old_ms, enum test_mode mode)
+static GprsMs *alloc_tbfs(struct gprs_rlcmac_bts *bts, struct GprsMs *old_ms, enum test_mode mode)
 {
-	struct gprs_rlcmac_bts *bts;
 	struct GprsMs *ms, *new_ms;
 	uint8_t trx_no = -1;
 
 	OSMO_ASSERT(old_ms != NULL);
 
-	bts = the_bts->bts_data();
-
 	gprs_rlcmac_tbf *tbf = NULL;
 
 	if (ms_current_trx(old_ms))
@@ -517,12 +512,12 @@
 
 	case TEST_MODE_DL_AFTER_UL:
 	case TEST_MODE_UL_AND_DL:
-		new_ms = alloc_tbfs(the_bts, ms, TEST_MODE_DL_ONLY);
+		new_ms = alloc_tbfs(bts, ms, TEST_MODE_DL_ONLY);
 		break;
 
 	case TEST_MODE_UL_AFTER_DL:
 	case TEST_MODE_DL_AND_UL:
-		new_ms = alloc_tbfs(the_bts, ms, TEST_MODE_UL_ONLY);
+		new_ms = alloc_tbfs(bts, ms, TEST_MODE_UL_ONLY);
 		break;
 	}
 
@@ -546,7 +541,7 @@
 	return new_ms;
 }
 
-static unsigned alloc_many_tbfs(BTS *the_bts, unsigned min_class,
+static unsigned alloc_many_tbfs(struct gprs_rlcmac_bts *bts, unsigned min_class,
 	unsigned max_class, enum test_mode mode)
 {
 	unsigned counter;
@@ -566,11 +561,11 @@
 		enum gprs_rlcmac_tbf_direction dir;
 		uint32_t tlli = counter + 0xc0000000;
 
-		ms = the_bts->ms_by_tlli(tlli);
+		ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
 		if (!ms)
-			ms = the_bts->ms_alloc(0, 0);
+			ms = bts_alloc_ms(bts, 0, 0);
 		ms_set_ms_class(ms, ms_class);
-		ms = alloc_tbfs(the_bts, ms, mode);
+		ms = alloc_tbfs(bts, ms, mode);
 		if (!ms)
 			break;
 
@@ -630,7 +625,7 @@
 
 		if (tfi >= 0) {
 			OSMO_ASSERT(ms_current_trx(ms));
-			tfi2 = the_bts->tfi_find_free(dir, &trx_no2,
+			tfi2 = bts_tfi_find_free(bts, dir, &trx_no2,
 				ms_current_trx(ms)->trx_no);
 			OSMO_ASSERT(tfi != tfi2);
 			OSMO_ASSERT(tfi2 < 0 ||
@@ -649,15 +644,13 @@
 	unsigned max_class, enum test_mode mode,
 	unsigned expect_num, const char *text)
 {
-	BTS the_bts(the_pcu);
-	struct gprs_rlcmac_bts *bts;
+	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
 	struct gprs_rlcmac_trx *trx;
 	unsigned counter;
 
 	printf("Going to test assignment with many TBF, algorithm %s class %u..%u (%s)\n",
 	       text, min_class, max_class, test_mode_descr(mode));
 
-	bts = the_bts.bts_data();
 	the_pcu->alloc_algorithm = algo;
 
 	trx = &bts->trx[0];
@@ -667,7 +660,7 @@
 	trx->pdch[6].enable();
 	trx->pdch[7].enable();
 
-	counter = alloc_many_tbfs(&the_bts, min_class, max_class, mode);
+	counter = alloc_many_tbfs(bts, min_class, max_class, mode);
 
 	printf("  Successfully allocated %u UL TBFs, algorithm %s class %u..%u (%s)\n",
 	       counter, text, min_class, max_class, test_mode_descr(mode));
@@ -677,14 +670,14 @@
 
 	OSMO_ASSERT(counter == expect_num);
 
-	check_tfi_usage(&the_bts);
+	check_tfi_usage(bts);
+	talloc_free(bts);
 }
 
 static void test_many_connections(algo_t algo, unsigned expect_num,
 	const char *text)
 {
-	BTS the_bts(the_pcu);
-	struct gprs_rlcmac_bts *bts;
+	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
 	struct gprs_rlcmac_trx *trx;
 	int counter1, counter2 = -1;
 	unsigned i;
@@ -697,7 +690,6 @@
 
 	printf("Going to test assignment with many connections, algorithm %s\n", text);
 
-	bts = the_bts.bts_data();
 	the_pcu->alloc_algorithm = algo;
 
 	trx = &bts->trx[0];
@@ -708,11 +700,11 @@
 	trx->pdch[7].enable();
 
 	for (i = 0; i < ARRAY_SIZE(mode_seq); i += 1) {
-		counter1 = alloc_many_tbfs(&the_bts, 1, mslot_class_max(), mode_seq[i]);
+		counter1 = alloc_many_tbfs(bts, 1, mslot_class_max(), mode_seq[i]);
 		fprintf(stderr, "  Allocated %d TBFs (previously %d)\n",
 			counter1, counter2);
 
-		check_tfi_usage(&the_bts);
+		check_tfi_usage(bts);
 
 		/* This will stop earlier due to USF shortage */
 		if (mode_seq[i] == TEST_MODE_UL_ONLY)
@@ -733,6 +725,7 @@
 		fprintf(stderr, "  Expected %d TBFs (got %d) for algorithm %s\n", expect_num, counter1, text);
 
 	OSMO_ASSERT(expect_num == (unsigned)counter1);
+	talloc_free(bts);
 }
 
 static inline void test_a_b_dyn(enum test_mode mode, uint8_t exp_A, uint8_t exp_B, uint8_t exp_dyn)
@@ -761,9 +754,8 @@
 
 static void test_2_consecutive_dl_tbfs()
 {
-	BTS the_bts(the_pcu);
+	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
 	GprsMs *ms;
-	struct gprs_rlcmac_bts *bts;
 	struct gprs_rlcmac_trx *trx;
 	uint8_t ms_class = 11;
 	uint8_t egprs_ms_class = 11;
@@ -772,7 +764,6 @@
 
 	printf("Testing DL TS allocation for Multi UEs\n");
 
-	bts = the_bts.bts_data();
 	the_pcu->alloc_algorithm = alloc_algorithm_b;
 
 	trx = &bts->trx[0];
@@ -781,7 +772,7 @@
 	trx->pdch[6].enable();
 	trx->pdch[7].enable();
 
-	ms = the_bts.ms_alloc(ms_class, egprs_ms_class);
+	ms = bts_alloc_ms(bts, ms_class, egprs_ms_class);
 	dl_tbf1 = tbf_alloc_dl_tbf(bts, ms, 0, false);
 	OSMO_ASSERT(dl_tbf1);
 
@@ -792,7 +783,7 @@
 	OSMO_ASSERT(numTs1 == 4);
 	printf("TBF1: numTs(%d)\n", numTs1);
 
-	ms = the_bts.ms_alloc(ms_class, egprs_ms_class);
+	ms = bts_alloc_ms(bts, ms_class, egprs_ms_class);
 	dl_tbf2 = tbf_alloc_dl_tbf(bts, ms, 0, false);
 	OSMO_ASSERT(dl_tbf2);
 
@@ -810,6 +801,7 @@
 
 	tbf_free(dl_tbf1);
 	tbf_free(dl_tbf2);
+	talloc_free(bts);
 }
 
 int main(int argc, char **argv)
diff --git a/tests/alloc/MslotTest.cpp b/tests/alloc/MslotTest.cpp
index e354641..b32a828 100644
--- a/tests/alloc/MslotTest.cpp
+++ b/tests/alloc/MslotTest.cpp
@@ -62,15 +62,12 @@
 
 static inline void test_multislot_total_ascending(bool seq)
 {
-	BTS the_bts(the_pcu);
-	struct gprs_rlcmac_bts *bts;
+	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
 	struct gprs_rlcmac_trx *trx;
 	int i;
 
 	printf("%s(): %s\n", __func__, seq ? "sequential" : "accumulative");
 
-	bts = the_bts.bts_data();
-
 	trx = &bts->trx[0];
 
 	for (i = 0; i < 8; i++) {
@@ -79,19 +76,17 @@
 
 		test_all_classes(trx, seq);
 	}
+	talloc_free(bts);
 }
 
 static inline void test_multislot_total_descending(bool seq)
 {
-	BTS the_bts(the_pcu);
-	struct gprs_rlcmac_bts *bts;
+	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
 	struct gprs_rlcmac_trx *trx;
 	int i;
 
 	printf("%s(): %s\n", __func__, seq ? "sequential" : "accumulative");
 
-	bts = the_bts.bts_data();
-
 	trx = &bts->trx[0];
 
 	for (i = 7; i >= 0; i--) {
@@ -100,18 +95,16 @@
 
 		test_all_classes(trx, seq);
 	}
+	talloc_free(bts);
 }
 
 static inline void test_multislot_middle(bool seq)
 {
-	BTS the_bts(the_pcu);
-	struct gprs_rlcmac_bts *bts;
+	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
 	struct gprs_rlcmac_trx *trx;
 
 	printf("%s(): %s\n", __func__, seq ? "sequential" : "accumulative");
 
-	bts = the_bts.bts_data();
-
 	trx = &bts->trx[0];
 
 	trx->pdch[2].enable();
@@ -119,24 +112,23 @@
 	trx->pdch[4].enable();
 
 	test_all_classes(trx, seq);
+	talloc_free(bts);
 }
 
 static inline void test_multislot_ends(bool seq)
 {
-	BTS the_bts(the_pcu);
-	struct gprs_rlcmac_bts *bts;
+	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
 	struct gprs_rlcmac_trx *trx;
 
 	printf("%s(): %s\n", __func__, seq ? "sequential" : "accumulative");
 
-	bts = the_bts.bts_data();
-
 	trx = &bts->trx[0];
 
 	trx->pdch[0].enable();
 	trx->pdch[7].enable();
 
 	test_all_classes(trx, seq);
+	talloc_free(bts);
 }
 
 static inline void test_window_wrapper()
diff --git a/tests/app_info/AppInfoTest.cpp b/tests/app_info/AppInfoTest.cpp
index 962ead4..e0b2853 100644
--- a/tests/app_info/AppInfoTest.cpp
+++ b/tests/app_info/AppInfoTest.cpp
@@ -20,6 +20,7 @@
 #include <assert.h>
 #include "gprs_rlcmac.h"
 #include "bts.h"
+#include "tbf_dl.h"
 
 extern "C" {
 #include <osmocom/vty/telnet_interface.h>
@@ -77,25 +78,23 @@
 
 void prepare_bts_with_two_dl_tbf_subscr()
 {
-	BTS *bts = BTS::main_bts();
-	struct gprs_rlcmac_bts *bts_data;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	struct gprs_rlcmac_trx *trx;
 
 	fprintf(stderr, "--- %s ---\n",  __func__);
 
-	bts_data = bts->bts_data();
 	the_pcu->alloc_algorithm = alloc_algorithm_b;
 
-	trx = bts_data->trx;
+	trx = bts->trx;
 	trx->pdch[4].enable();
 	trx->pdch[5].enable();
 	trx->pdch[6].enable();
 	trx->pdch[7].enable();
 
-	ms1 = bts->ms_alloc(10, 11);
-	tbf1 = tbf_alloc_dl_tbf(bts_data, ms1, 0, false);
-	ms2 = bts->ms_alloc(12, 13);
-	tbf2 = tbf_alloc_dl_tbf(bts_data, ms2, 0, false);
+	ms1 = bts_alloc_ms(bts, 10, 11);
+	tbf1 = tbf_alloc_dl_tbf(bts, ms1, 0, false);
+	ms2 = bts_alloc_ms(bts, 12, 13);
+	tbf2 = tbf_alloc_dl_tbf(bts, ms2, 0, false);
 
 	fprintf(stderr, "\n");
 }
@@ -122,15 +121,15 @@
 
 void test_sched_app_info_missing_app_info_in_bts(const struct gsm_pcu_if_app_info_req *req)
 {
-	struct gprs_rlcmac_bts *bts_data = BTS::main_bts()->bts_data();
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	struct gsm_pcu_if pcu_prim = {PCU_IF_MSG_APP_INFO_REQ, };
 
 	fprintf(stderr, "--- %s ---\n",  __func__);
 	pcu_prim.u.app_info_req = *req;
 	pcu_rx(PCU_IF_MSG_APP_INFO_REQ, &pcu_prim);
 
-	msgb_free(bts_data->app_info);
-	bts_data->app_info = NULL;
+	msgb_free(bts->app_info);
+	bts->app_info = NULL;
 
 	assert(sched_app_info(tbf1) == NULL);
 
@@ -154,8 +153,8 @@
 
 	tbf_free(tbf1);
 	tbf_free(tbf2);
-	BTS::main_bts()->cleanup();
-	/* FIXME: talloc report disabled, because bts->ms_alloc() in prepare_bts_with_two_dl_tbf_subscr() causes leak */
+	TALLOC_FREE(the_pcu->bts);
+	/* FIXME: talloc report disabled, because bts_alloc_ms(bts, ) in prepare_bts_with_two_dl_tbf_subscr() causes leak */
 	/* talloc_report_full(tall_pcu_ctx, stderr); */
 	talloc_free(the_pcu);
 	talloc_free(tall_pcu_ctx);
diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp
index c5ce730..d67646e 100644
--- a/tests/edge/EdgeTest.cpp
+++ b/tests/edge/EdgeTest.cpp
@@ -1151,19 +1151,17 @@
 	printf("=== end %s ===\n", __func__);
 }
 
-static void setup_bts(BTS *the_bts, uint8_t ts_no, uint8_t cs = 1)
+static void setup_bts(struct gprs_rlcmac_bts *bts, uint8_t ts_no, uint8_t cs = 1)
 {
-	gprs_rlcmac_bts *bts;
 	gprs_rlcmac_trx *trx;
 
-	bts = the_bts->bts_data();
 	the_pcu->alloc_algorithm = alloc_algorithm_a;
 	bts->initial_cs_dl = cs;
 	bts->initial_cs_ul = cs;
 	trx = &bts->trx[0];
 	trx->pdch[ts_no].enable();
 }
-static void uplink_header_type_2_parsing_test(BTS *the_bts,
+static void uplink_header_type_2_parsing_test(struct gprs_rlcmac_bts *bts,
 	uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
 	uint8_t ms_class)
 {
@@ -1254,7 +1252,7 @@
 
 static void uplink_header_type2_test(void)
 {
-	BTS the_bts(the_pcu);
+	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
 	int ts_no = 7;
 	uint32_t fn = 2654218;
 	uint16_t qta = 31;
@@ -1262,14 +1260,15 @@
 	uint8_t ms_class = 1;
 
 	printf("=== start %s ===\n", __func__);
-	setup_bts(&the_bts, ts_no, 10);
+	setup_bts(bts, ts_no, 10);
 
-	uplink_header_type_2_parsing_test(&the_bts, ts_no,
+	uplink_header_type_2_parsing_test(bts, ts_no,
 			tlli, &fn, qta, ms_class);
 	printf("=== end %s ===\n", __func__);
+	talloc_free(bts);
 }
 
-static void uplink_header_type_1_parsing_test(BTS *the_bts,
+static void uplink_header_type_1_parsing_test(struct gprs_rlcmac_bts *bts,
 	uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
 	uint8_t ms_class)
 {
@@ -1371,7 +1370,7 @@
 
 void uplink_header_type1_test(void)
 {
-	BTS the_bts(the_pcu);
+	struct gprs_rlcmac_bts  *bts = bts_alloc(the_pcu);
 	int ts_no = 7;
 	uint32_t fn = 2654218;
 	uint16_t qta = 31;
@@ -1379,8 +1378,8 @@
 	uint8_t ms_class = 1;
 
 	printf("=== start %s ===\n", __func__);
-	setup_bts(&the_bts, ts_no, 12);
-	uplink_header_type_1_parsing_test(&the_bts, ts_no, tlli, &fn,
+	setup_bts(bts, ts_no, 12);
+	uplink_header_type_1_parsing_test(bts, ts_no, tlli, &fn,
 			qta, ms_class);
 	printf("=== end %s ===\n", __func__);
 }
diff --git a/tests/emu/pcu_emu.cpp b/tests/emu/pcu_emu.cpp
index 2336e67..ab2804b 100644
--- a/tests/emu/pcu_emu.cpp
+++ b/tests/emu/pcu_emu.cpp
@@ -142,7 +142,7 @@
 	init_pcu(pcu);
 	init_main_bts();
 	bssgp_set_bssgp_callback(gprs_gp_send_cb, pcu->nsi);
-	create_and_connect_bssgp(bts_data(pcu->bts), INADDR_LOOPBACK, 23000);
+	create_and_connect_bssgp(pcu->bts, INADDR_LOOPBACK, 23000);
 
 	for (;;)
 		osmo_select_main(0);
diff --git a/tests/fn/FnTest.cpp b/tests/fn/FnTest.cpp
index 3185bd5..dd30b34 100644
--- a/tests/fn/FnTest.cpp
+++ b/tests/fn/FnTest.cpp
@@ -36,24 +36,24 @@
 int16_t spoof_mnc = 0, spoof_mcc = 0;
 bool spoof_mnc_3_digits = false;
 
-static uint32_t calc_fn(BTS * bts, uint32_t rfn)
+static uint32_t calc_fn(struct gprs_rlcmac_bts * bts, uint32_t rfn)
 {
 	uint32_t fn;
-	fn = bts->rfn_to_fn(rfn);
+	fn = bts_rfn_to_fn(bts, rfn);
 	printf("rfn=%i ==> fn=%i\n", rfn, fn);
 	return fn;
 }
 
-static void set_fn(BTS * bts, uint32_t fn)
+static void set_fn(struct gprs_rlcmac_bts * bts, uint32_t fn)
 {
 	printf("\n");
-	bts->set_current_frame_number(fn);
+	bts_set_current_frame_number(bts, fn);
 	printf("bts: fn=%i\n", fn);
 }
 
 static void run_test()
 {
-	BTS bts(the_pcu);
+	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
 	uint32_t fn;
 
 	printf("RFN_MODULUS=%i\n",RFN_MODULUS);
@@ -63,20 +63,20 @@
 	/* Test with a collection of real world examples,
 	 * all all of them are not critical and do not
 	 * assume the occurence of any race contions */
-	set_fn(&bts, 1320462);
-	fn = calc_fn(&bts, 5066);
+	set_fn(bts, 1320462);
+	fn = calc_fn(bts, 5066);
 	OSMO_ASSERT(fn == 1320458);
 
-	set_fn(&bts, 8246);
-	fn = calc_fn(&bts, 8244);
+	set_fn(bts, 8246);
+	fn = calc_fn(bts, 8244);
 	OSMO_ASSERT(fn == 8244);
 
-	set_fn(&bts, 10270);
-	fn = calc_fn(&bts, 10269);
+	set_fn(bts, 10270);
+	fn = calc_fn(bts, 10269);
 	OSMO_ASSERT(fn == 10269);
 
-	set_fn(&bts, 311276);
-	fn = calc_fn(&bts, 14250);
+	set_fn(bts, 311276);
+	fn = calc_fn(bts, 14250);
 	OSMO_ASSERT(fn == 311274);
 
 
@@ -84,20 +84,20 @@
 	 * just wrapped over a little bit above the
 	 * modulo 42432 raster, but the rach request
 	 * occurred before the wrapping */
-	set_fn(&bts, RFN_MODULUS + 30);
-	fn = calc_fn(&bts, RFN_MODULUS - 10);
+	set_fn(bts, RFN_MODULUS + 30);
+	fn = calc_fn(bts, RFN_MODULUS - 10);
 	OSMO_ASSERT(fn == 42422);
 
-	set_fn(&bts, RFN_MODULUS + 1);
-	fn = calc_fn(&bts, RFN_MODULUS - 1);
+	set_fn(bts, RFN_MODULUS + 1);
+	fn = calc_fn(bts, RFN_MODULUS - 1);
 	OSMO_ASSERT(fn == 42431);
 
-	set_fn(&bts, RFN_MODULUS * 123 + 16);
-	fn = calc_fn(&bts, RFN_MODULUS - 4);
+	set_fn(bts, RFN_MODULUS * 123 + 16);
+	fn = calc_fn(bts, RFN_MODULUS - 4);
 	OSMO_ASSERT(fn == 5219132);
 
-	set_fn(&bts, RFN_MODULUS * 123 + 451);
-	fn = calc_fn(&bts, RFN_MODULUS - 175);
+	set_fn(bts, RFN_MODULUS * 123 + 451);
+	fn = calc_fn(bts, RFN_MODULUS - 175);
 	OSMO_ASSERT(fn == 5218961);
 
 
@@ -105,41 +105,42 @@
 	 * the BTS just wrapped its internal frame number
 	 * but we still get rach requests with high relative
 	 * frame numbers. */
-	set_fn(&bts, 0);
-	fn = calc_fn(&bts, RFN_MODULUS - 13);
+	set_fn(bts, 0);
+	fn = calc_fn(bts, RFN_MODULUS - 13);
 	OSMO_ASSERT(fn == 2715635);
 
-	set_fn(&bts, 453);
-	fn = calc_fn(&bts, RFN_MODULUS - 102);
+	set_fn(bts, 453);
+	fn = calc_fn(bts, RFN_MODULUS - 102);
 	OSMO_ASSERT(fn == 2715546);
 
-	set_fn(&bts, 10);
-	fn = calc_fn(&bts, RFN_MODULUS - 10);
+	set_fn(bts, 10);
+	fn = calc_fn(bts, RFN_MODULUS - 10);
 	OSMO_ASSERT(fn == 2715638);
 
-	set_fn(&bts, 23);
-	fn = calc_fn(&bts, RFN_MODULUS - 42);
+	set_fn(bts, 23);
+	fn = calc_fn(bts, RFN_MODULUS - 42);
 	OSMO_ASSERT(fn == 2715606);
 
 
 	/* Also check with some corner case
 	 * values where Fn and RFn reach its
 	 * maximum/minimum valid range */
-	set_fn(&bts, GSM_MAX_FN);
-	fn = calc_fn(&bts, RFN_MODULUS-1);
+	set_fn(bts, GSM_MAX_FN);
+	fn = calc_fn(bts, RFN_MODULUS-1);
 	OSMO_ASSERT(fn == GSM_MAX_FN-1);
 
-	set_fn(&bts, 0);
-	fn = calc_fn(&bts, RFN_MODULUS-1);
+	set_fn(bts, 0);
+	fn = calc_fn(bts, RFN_MODULUS-1);
 	OSMO_ASSERT(fn == GSM_MAX_FN-1);
 
-	set_fn(&bts, GSM_MAX_FN);
-	fn = calc_fn(&bts, 0);
+	set_fn(bts, GSM_MAX_FN);
+	fn = calc_fn(bts, 0);
 	OSMO_ASSERT(fn == GSM_MAX_FN);
 
-	set_fn(&bts, 0);
-	fn = calc_fn(&bts, 0);
+	set_fn(bts, 0);
+	fn = calc_fn(bts, 0);
 	OSMO_ASSERT(fn == 0);
+	talloc_free(bts);
 }
 
 int main(int argc, char **argv)
diff --git a/tests/ms/MsTest.cpp b/tests/ms/MsTest.cpp
index d6c8f18..58579f8 100644
--- a/tests/ms/MsTest.cpp
+++ b/tests/ms/MsTest.cpp
@@ -51,18 +51,18 @@
 	uint32_t tlli = 0xffeeddbb;
 	gprs_rlcmac_dl_tbf *dl_tbf;
 	gprs_rlcmac_ul_tbf *ul_tbf;
-	BTS the_bts(the_pcu);
+	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
 	GprsMs *ms;
 
 	printf("=== start %s ===\n", __func__);
 
-	ms = ms_alloc(&the_bts, tlli);
+	ms = ms_alloc(bts, tlli);
 	OSMO_ASSERT(ms_is_idle(ms));
 
 	dl_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);
-	new (dl_tbf) gprs_rlcmac_dl_tbf(&the_bts, ms);
+	new (dl_tbf) gprs_rlcmac_dl_tbf(bts, ms);
 	ul_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);
-	new (ul_tbf) gprs_rlcmac_ul_tbf(&the_bts, ms);
+	new (ul_tbf) gprs_rlcmac_ul_tbf(bts, ms);
 
 	ms_attach_tbf(ms, ul_tbf);
 	OSMO_ASSERT(!ms_is_idle(ms));
@@ -88,7 +88,7 @@
 
 	talloc_free(dl_tbf);
 	talloc_free(ul_tbf);
-
+	talloc_free(bts);
 	printf("=== end %s ===\n", __func__);
 }
 
@@ -114,21 +114,21 @@
 	uint32_t tlli = 0xffeeddbb;
 	gprs_rlcmac_dl_tbf *dl_tbf;
 	gprs_rlcmac_ul_tbf *ul_tbf;
-	BTS the_bts(the_pcu);
+	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
 	GprsMs *ms;
 	last_cb = CB_UNKNOWN;
 
 	printf("=== start %s ===\n", __func__);
 
-	ms = ms_alloc(&the_bts, tlli);
+	ms = ms_alloc(bts, tlli);
 	ms_set_callback(ms, &ms_cb);
 
 	OSMO_ASSERT(ms_is_idle(ms));
 
 	dl_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);
-	new (dl_tbf) gprs_rlcmac_dl_tbf(&the_bts, ms);
+	new (dl_tbf) gprs_rlcmac_dl_tbf(bts, ms);
 	ul_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);
-	new (ul_tbf) gprs_rlcmac_ul_tbf(&the_bts, ms);
+	new (ul_tbf) gprs_rlcmac_ul_tbf(bts, ms);
 
 	OSMO_ASSERT(last_cb == CB_UNKNOWN);
 
@@ -163,7 +163,7 @@
 
 	talloc_free(dl_tbf);
 	talloc_free(ul_tbf);
-
+	talloc_free(bts);
 	printf("=== end %s ===\n", __func__);
 }
 
@@ -188,23 +188,23 @@
 	uint32_t tlli = 0xffeeddbb;
 	gprs_rlcmac_dl_tbf *dl_tbf[2];
 	gprs_rlcmac_ul_tbf *ul_tbf;
-	BTS the_bts(the_pcu);
+	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
 	GprsMs *ms;
 
 	printf("=== start %s ===\n", __func__);
 
-	ms = ms_alloc(&the_bts, tlli);
+	ms = ms_alloc(bts, tlli);
 	ms_set_callback(ms, &ms_replace_tbf_cb);
 
 	OSMO_ASSERT(ms_is_idle(ms));
 	was_idle = false;
 
 	dl_tbf[0] = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);
-	new (dl_tbf[0]) gprs_rlcmac_dl_tbf(&the_bts, ms);
+	new (dl_tbf[0]) gprs_rlcmac_dl_tbf(bts, ms);
 	dl_tbf[1] = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);
-	new (dl_tbf[1]) gprs_rlcmac_dl_tbf(&the_bts, ms);
+	new (dl_tbf[1]) gprs_rlcmac_dl_tbf(bts, ms);
 	ul_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);
-	new (ul_tbf) gprs_rlcmac_ul_tbf(&the_bts, ms);
+	new (ul_tbf) gprs_rlcmac_ul_tbf(bts, ms);
 
 	ms_attach_tbf(ms, dl_tbf[0]);
 	OSMO_ASSERT(!ms_is_idle(ms));
@@ -253,7 +253,7 @@
 	talloc_free(dl_tbf[0]);
 	talloc_free(dl_tbf[1]);
 	talloc_free(ul_tbf);
-
+	talloc_free(bts);
 	printf("=== end %s ===\n", __func__);
 }
 
@@ -262,12 +262,12 @@
 	uint32_t start_tlli = 0xaa000000;
 	uint32_t new_ms_tlli = 0xff001111;
 	uint32_t other_sgsn_tlli = 0xff00eeee;
-	BTS the_bts(the_pcu);
+	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
 	GprsMs *ms;
 
 	printf("=== start %s ===\n", __func__);
 
-	ms = ms_alloc(&the_bts, start_tlli);
+	ms = ms_alloc(bts, start_tlli);
 
 	OSMO_ASSERT(ms_is_idle(ms));
 
@@ -347,7 +347,7 @@
 	OSMO_ASSERT(!ms_check_tlli(ms, start_tlli));
 
 	talloc_free(ms);
-
+	talloc_free(bts);
 	printf("=== end %s ===\n", __func__);
 }
 
@@ -374,9 +374,9 @@
 	const char *imsi2 = "001001987654322";
 
 	gprs_rlcmac_ul_tbf *ul_tbf;
-	BTS the_bts(the_pcu);
+	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
 	GprsMs *ms, *ms_tmp;
-	GprsMsStorage store(&the_bts);
+	GprsMsStorage store(bts);
 
 	printf("=== start %s ===\n", __func__);
 
@@ -420,7 +420,7 @@
 	ms = store.get_ms(tlli + 0);
 	OSMO_ASSERT(ms != NULL);
 	ul_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);
-	new (ul_tbf) gprs_rlcmac_ul_tbf(&the_bts, ms);
+	new (ul_tbf) gprs_rlcmac_ul_tbf(bts, ms);
 	ms_attach_tbf(ms, ul_tbf);
 	ms_detach_tbf(ms, ul_tbf);
 	ms = store.get_ms(tlli + 0);
@@ -437,7 +437,7 @@
 	OSMO_ASSERT(ms == NULL);
 
 	talloc_free(ul_tbf);
-
+	talloc_free(bts);
 	printf("=== end %s ===\n", __func__);
 }
 
@@ -446,22 +446,22 @@
 	uint32_t tlli = 0xffeeddbb;
 	gprs_rlcmac_dl_tbf *dl_tbf;
 	gprs_rlcmac_ul_tbf *ul_tbf;
-	BTS the_bts(the_pcu);
+	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
 	GprsMs *ms;
 	last_cb = CB_UNKNOWN;
 
 	printf("=== start %s ===\n", __func__);
 
-	ms = ms_alloc(&the_bts, tlli);
+	ms = ms_alloc(bts, tlli);
 	ms_set_callback(ms, &ms_cb);
 	ms_set_timeout(ms, 1);
 
 	OSMO_ASSERT(ms_is_idle(ms));
 
 	dl_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);
-	new (dl_tbf) gprs_rlcmac_dl_tbf(&the_bts, ms);
+	new (dl_tbf) gprs_rlcmac_dl_tbf(bts, ms);
 	ul_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);
-	new (ul_tbf) gprs_rlcmac_ul_tbf(&the_bts, ms);
+	new (ul_tbf) gprs_rlcmac_ul_tbf(bts, ms);
 
 	OSMO_ASSERT(last_cb == CB_UNKNOWN);
 
@@ -493,14 +493,13 @@
 	talloc_free(ms);
 	talloc_free(dl_tbf);
 	talloc_free(ul_tbf);
-
+	talloc_free(bts);
 	printf("=== end %s ===\n", __func__);
 }
 
 static void test_ms_cs_selection()
 {
-	BTS the_bts(the_pcu);
-	gprs_rlcmac_bts *bts = the_bts.bts_data();
+	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
 	uint32_t tlli = 0xffeeddbb;
 
 	gprs_rlcmac_dl_tbf *dl_tbf;
@@ -513,12 +512,12 @@
 	the_pcu->vty.cs_downgrade_threshold = 0;
 	the_pcu->vty.cs_adj_lower_limit = 0;
 
-	ms = ms_alloc(&the_bts, tlli);
+	ms = ms_alloc(bts, tlli);
 
 	OSMO_ASSERT(ms_is_idle(ms));
 
 	dl_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);
-	new (dl_tbf) gprs_rlcmac_dl_tbf(&the_bts, ms);
+	new (dl_tbf) gprs_rlcmac_dl_tbf(bts, ms);
 	ms_attach_tbf(ms, dl_tbf);
 
 	OSMO_ASSERT(!ms_is_idle(ms));
@@ -530,7 +529,7 @@
 	OSMO_ASSERT(mcs_chan_code(ms_current_cs_dl(ms)) == 2);
 
 	talloc_free(dl_tbf);
-
+	talloc_free(bts);
 	printf("=== end %s ===\n", __func__);
 }
 
@@ -545,8 +544,7 @@
 
 static void test_ms_mcs_mode()
 {
-	BTS the_bts(the_pcu);
-	gprs_rlcmac_bts *bts = the_bts.bts_data();
+	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
 	uint32_t tlli = 0xdeadbeef;
 
 	gprs_rlcmac_dl_tbf *dl_tbf;
@@ -554,18 +552,18 @@
 
 	printf("=== start %s ===\n", __func__);
 
-	ms1 = ms_alloc(&the_bts, tlli);
+	ms1 = ms_alloc(bts, tlli);
 	dump_ms(ms1, "1: no BTS defaults  ");
 
 	bts->initial_cs_dl = 4;
 	bts->initial_cs_ul = 1;
 	the_pcu->vty.cs_downgrade_threshold = 0;
 
-	ms2 = ms_alloc(&the_bts, tlli + 1);
+	ms2 = ms_alloc(bts, tlli + 1);
 	dump_ms(ms2, "2: with BTS defaults");
 
 	dl_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);
-	new (dl_tbf) gprs_rlcmac_dl_tbf(&the_bts, ms2);
+	new (dl_tbf) gprs_rlcmac_dl_tbf(bts, ms2);
 	ms_attach_tbf(ms2, dl_tbf);
 
 	dump_ms(ms2, "2: after TBF attach ");
@@ -599,7 +597,7 @@
 	dump_ms(ms2, "2: after mode set   ");
 
 	talloc_free(dl_tbf);
-
+	talloc_free(bts);
 	printf("=== end %s ===\n", __func__);
 }
 
diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp
index 1b85201..ef26862 100644
--- a/tests/tbf/TbfTest.cpp
+++ b/tests/tbf/TbfTest.cpp
@@ -22,8 +22,11 @@
 
 #include "bts.h"
 #include "tbf.h"
+#include "tbf_dl.h"
 #include "tbf_ul.h"
+#include "gprs_ms.h"
 #include "gprs_debug.h"
+#include "gprs_ms_storage.h"
 #include "pcu_utils.h"
 #include "gprs_bssgp_pcu.h"
 #include "pcu_l1_if.h"
@@ -54,7 +57,7 @@
 /* Measurements shared by all unit tests */
 static struct pcu_l1_meas meas;
 
-static int bts_handle_rach(BTS *bts, uint16_t ra, uint32_t Fn, int16_t qta)
+static int bts_handle_rach(struct gprs_rlcmac_bts *bts, uint16_t ra, uint32_t Fn, int16_t qta)
 {
 	struct rach_ind_params rip = {
 		.burst_type = GSM_L1_BURST_TYPE_ACCESS_0,
@@ -66,7 +69,7 @@
 		.qta = qta,
 	};
 
-	return bts->rcv_rach(&rip);
+	return bts_rcv_rach(bts, &rip);
 }
 
 static void check_tbf(gprs_rlcmac_tbf *tbf)
@@ -93,20 +96,20 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	GprsMs *ms, *ms_new;
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
 	the_pcu->alloc_algorithm = alloc_algorithm_a;
-	the_bts->bts_data()->trx[0].pdch[2].enable();
-	the_bts->bts_data()->trx[0].pdch[3].enable();
+	bts->trx[0].pdch[2].enable();
+	bts->trx[0].pdch[3].enable();
 
 	/*
 	 * Make a uplink and downlink allocation
 	 */
-	ms = the_bts->ms_alloc(0, 0);
-	gprs_rlcmac_tbf *dl_tbf = tbf_alloc_dl_tbf(the_bts->bts_data(),
+	ms = bts_alloc_ms(bts, 0, 0);
+	gprs_rlcmac_tbf *dl_tbf = tbf_alloc_dl_tbf(bts,
 						ms, 0, false);
 	OSMO_ASSERT(dl_tbf != NULL);
 	dl_tbf->update_ms(0x2342, GPRS_RLCMAC_DL_TBF);
@@ -114,14 +117,14 @@
 	OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf);
 	OSMO_ASSERT(dl_tbf->ms() == ms);
 
-	gprs_rlcmac_tbf *ul_tbf = tbf_alloc_ul_tbf(the_bts->bts_data(),
+	gprs_rlcmac_tbf *ul_tbf = tbf_alloc_ul_tbf(bts,
 						   ms, 0, false);
 	OSMO_ASSERT(ul_tbf != NULL);
 	ul_tbf->update_ms(0x2342, GPRS_RLCMAC_UL_TBF);
 	OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
 	OSMO_ASSERT(ul_tbf->ms() == ms);
 
-	OSMO_ASSERT(the_bts->ms_by_tlli(0x2342) == ms);
+	OSMO_ASSERT(bts_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI) == ms);
 
 	/*
 	 * Now check.. that DL changes and that the timing advance
@@ -130,20 +133,20 @@
 	dl_tbf->update_ms(0x4232, GPRS_RLCMAC_DL_TBF);
 
 	/* It is still there, since the new TLLI has not been used for UL yet */
-	ms_new = the_bts->ms_by_tlli(0x2342);
+	ms_new = bts_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms == ms_new);
 
-	ms_new = the_bts->ms_by_tlli(0x4232);
+	ms_new = bts_ms_by_tlli(bts, 0x4232, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms == ms_new);
 	OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf);
 	OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
 
 	/* Now use the new TLLI for UL */
 	ul_tbf->update_ms(0x4232, GPRS_RLCMAC_UL_TBF);
-	ms_new = the_bts->ms_by_tlli(0x2342);
+	ms_new = bts_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms_new == NULL);
 
-	ms_new = the_bts->ms_by_tlli(0x4232);
+	ms_new = bts_ms_by_tlli(bts, 0x4232, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms_new != NULL);
 	OSMO_ASSERT(ms_ta(ms_new) == 4);
 
@@ -168,12 +171,10 @@
 	return 0;
 }
 
-static void setup_bts(BTS *the_bts, uint8_t ts_no, uint8_t cs = 1)
+static void setup_bts(struct gprs_rlcmac_bts *bts, uint8_t ts_no, uint8_t cs = 1)
 {
-	gprs_rlcmac_bts *bts;
 	gprs_rlcmac_trx *trx;
 
-	bts = the_bts->bts_data();
 	the_pcu->alloc_algorithm = alloc_algorithm_a;
 	bts->initial_cs_dl = cs;
 	bts->initial_cs_ul = cs;
@@ -182,22 +183,20 @@
 	trx = &bts->trx[0];
 
 	trx->pdch[ts_no].enable();
-	the_bts->set_current_frame_number(DUMMY_FN);
+	bts_set_current_frame_number(bts, DUMMY_FN);
 }
 
-static gprs_rlcmac_dl_tbf *create_dl_tbf(BTS *the_bts, uint8_t ms_class,
+static gprs_rlcmac_dl_tbf *create_dl_tbf(struct gprs_rlcmac_bts *bts, uint8_t ms_class,
 	uint8_t egprs_ms_class, uint8_t *trx_no_)
 {
-	gprs_rlcmac_bts *bts;
 	int tfi;
 	uint8_t trx_no;
 	GprsMs *ms;
 	gprs_rlcmac_dl_tbf *dl_tbf;
 
-	bts = the_bts->bts_data();
-	ms = the_bts->ms_alloc(ms_class, egprs_ms_class);
+	ms = bts_alloc_ms(bts, ms_class, egprs_ms_class);
 
-	tfi = the_bts->tfi_find_free(GPRS_RLCMAC_DL_TBF, &trx_no, -1);
+	tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_DL_TBF, &trx_no, -1);
 	OSMO_ASSERT(tfi >= 0);
 	dl_tbf = tbf_alloc_dl_tbf(bts, ms, trx_no, true);
 	OSMO_ASSERT(dl_tbf);
@@ -243,7 +242,7 @@
 static void request_dl_rlc_block(struct gprs_rlcmac_tbf *tbf,
 	uint32_t *fn, uint8_t *block_nr = NULL)
 {
-	request_dl_rlc_block(tbf->bts->bts_data(), tbf->trx->trx_no,
+	request_dl_rlc_block(tbf->bts, tbf->trx->trx_no,
 		tbf->control_ts, fn, block_nr);
 }
 
@@ -256,7 +255,7 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	uint8_t ts_no = 4;
 	unsigned i;
 	uint8_t ms_class = 45;
@@ -273,8 +272,8 @@
 	gprs_rlcmac_dl_tbf *dl_tbf;
 	gprs_rlcmac_tbf *new_tbf;
 
-	setup_bts(the_bts, ts_no);
-	dl_tbf = create_dl_tbf(the_bts, ms_class, 0, &trx_no);
+	setup_bts(bts, ts_no);
+	dl_tbf = create_dl_tbf(bts, ms_class, 0, &trx_no);
 	dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
 	ms = dl_tbf->ms();
 
@@ -342,7 +341,7 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	uint8_t ts_no = 4;
 	unsigned i;
 	uint8_t ms_class = 45;
@@ -357,10 +356,10 @@
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
-	setup_bts(the_bts, ts_no);
+	setup_bts(bts, ts_no);
 	OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
 
-	dl_tbf = create_dl_tbf(the_bts, ms_class, 0, &trx_no);
+	dl_tbf = create_dl_tbf(bts, ms_class, 0, &trx_no);
 	dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
 
 	for (i = 0; i < sizeof(llc_data); i++)
@@ -413,7 +412,7 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	uint8_t ts_no = 4;
 	uint8_t ms_class = 45;
 	uint8_t trx_no;
@@ -423,27 +422,27 @@
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
-	setup_bts(the_bts, ts_no);
+	setup_bts(bts, ts_no);
 
-	dl_tbf[0] = create_dl_tbf(the_bts, ms_class, 0, &trx_no);
-	dl_tbf[1] = create_dl_tbf(the_bts, ms_class, 0, &trx_no);
+	dl_tbf[0] = create_dl_tbf(bts, ms_class, 0, &trx_no);
+	dl_tbf[1] = create_dl_tbf(bts, ms_class, 0, &trx_no);
 
 	dl_tbf[0]->update_ms(0xf1000001, GPRS_RLCMAC_DL_TBF);
 	dl_tbf[1]->update_ms(0xf1000002, GPRS_RLCMAC_DL_TBF);
 
 	ms_set_imsi(dl_tbf[0]->ms(), "001001000000001");
-	ms1 = the_bts->ms_store().get_ms(0, 0, "001001000000001");
+	ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000001");
 	OSMO_ASSERT(ms1 != NULL);
-	ms2 = the_bts->ms_store().get_ms(0xf1000001);
+	ms2 = bts_ms_store(bts)->get_ms(0xf1000001);
 	OSMO_ASSERT(ms2 != NULL);
 	OSMO_ASSERT(strcmp(ms_imsi(ms2), "001001000000001") == 0);
 	OSMO_ASSERT(ms1 == ms2);
 
 	/* change the IMSI on TBF 0 */
 	ms_set_imsi(dl_tbf[0]->ms(), "001001000000002");
-	ms1 = the_bts->ms_store().get_ms(0, 0, "001001000000001");
+	ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000001");
 	OSMO_ASSERT(ms1 == NULL);
-	ms1 = the_bts->ms_store().get_ms(0, 0, "001001000000002");
+	ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000002");
 	OSMO_ASSERT(ms1 != NULL);
 	OSMO_ASSERT(strcmp(ms_imsi(ms2), "001001000000002") == 0);
 	OSMO_ASSERT(ms1 == ms2);
@@ -452,7 +451,7 @@
 	{
 		ms_ref(ms2);
 		ms_set_imsi(dl_tbf[1]->ms(), "001001000000002");
-		ms1 = the_bts->ms_store().get_ms(0, 0, "001001000000002");
+		ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000002");
 		OSMO_ASSERT(ms1 != NULL);
 		OSMO_ASSERT(ms1 != ms2);
 		OSMO_ASSERT(strcmp(ms_imsi(ms1), "001001000000002") == 0);
@@ -460,11 +459,11 @@
 		ms_unref(ms2);
 	}
 
-	ms2 = the_bts->ms_store().get_ms(0xf1000001);
+	ms2 = bts_ms_store(bts)->get_ms(0xf1000001);
 	OSMO_ASSERT(ms2 == NULL);
 
 	tbf_free(dl_tbf[1]);
-	ms1 = the_bts->ms_store().get_ms(0, 0, "001001000000002");
+	ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000002");
 	OSMO_ASSERT(ms1 == NULL);
 
 	TALLOC_FREE(the_pcu);
@@ -475,8 +474,7 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
-	gprs_rlcmac_bts *bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	unsigned i;
 	uint8_t ts_no = 4;
 	uint8_t ms_class = 45;
@@ -486,14 +484,13 @@
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
-	bts = the_bts->bts_data();
-	the_bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
-	if (!the_bts->pcu->nsi) {
+	bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
+	if (!bts->pcu->nsi) {
 		LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
 		abort();
 	}
 
-	setup_bts(the_bts, ts_no);
+	setup_bts(bts, ts_no);
 	gprs_bssgp_init(bts, 1234, 1234, 1, 1, false, 0, 0, 0);
 
 	for (i = 0; i < 1024; i++) {
@@ -521,8 +518,7 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
-	gprs_rlcmac_bts *bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	uint8_t ts_no = 4;
 	uint8_t ms_class = 45;
 	int rc = 0;
@@ -533,16 +529,15 @@
 
 	uint8_t buf[19];
 
-	bts = the_bts->bts_data();
-	the_bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
-	if (!the_bts->pcu->nsi) {
+	bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
+	if (!bts->pcu->nsi) {
 		LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
 		abort();
 	}
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
-	setup_bts(the_bts, ts_no);
+	setup_bts(bts, ts_no);
 	/* keep the MS object 10 seconds */
 	OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2030, 10, OSMO_TDEF_S) == 0);
 
@@ -554,7 +549,7 @@
 		delay_csec, buf, sizeof(buf));
 	OSMO_ASSERT(rc >= 0);
 
-	ms = the_bts->ms_store().get_ms(0, 0, imsi);
+	ms = bts_ms_store(bts)->get_ms(0, 0, imsi);
 	OSMO_ASSERT(ms != NULL);
 	OSMO_ASSERT(ms_dl_tbf(ms) != NULL);
 	ms_dl_tbf(ms)->set_ta(0);
@@ -605,7 +600,7 @@
 	TALLOC_FREE(the_pcu);
 }
 
-static gprs_rlcmac_ul_tbf *establish_ul_tbf_single_phase(BTS *the_bts,
+static gprs_rlcmac_ul_tbf *establish_ul_tbf_single_phase(struct gprs_rlcmac_bts *bts,
 	uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta)
 {
 	GprsMs *ms;
@@ -614,11 +609,11 @@
 	uint8_t trx_no = 0;
 	struct gprs_rlcmac_pdch *pdch;
 
-	tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
+	tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
 
-	bts_handle_rach(the_bts, 0x03, *fn, qta);
+	bts_handle_rach(bts, 0x03, *fn, qta);
 
-	ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
+	ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
 	OSMO_ASSERT(ul_tbf != NULL);
 
 	OSMO_ASSERT(ul_tbf->ta() == qta / 4);
@@ -631,16 +626,16 @@
 		uint8_t(tlli >> 8), uint8_t(tlli), /* TLLI */
 	};
 
-	pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
+	pdch = &bts->trx[trx_no].pdch[ts_no];
 	pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
 
-	ms = the_bts->ms_by_tlli(tlli);
+	ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms != NULL);
 
 	return ul_tbf;
 }
 
-static void send_ul_mac_block(BTS *the_bts, unsigned trx_no, unsigned ts_no,
+static void send_ul_mac_block(struct gprs_rlcmac_bts *bts, unsigned trx_no, unsigned ts_no,
 	RlcMacUplink_t *ulreq, unsigned fn)
 {
 	bitvec *rlc_block;
@@ -655,9 +650,9 @@
 	OSMO_ASSERT(size_t(num_bytes) < sizeof(buf));
 	bitvec_free(rlc_block);
 
-	the_bts->set_current_block_frame_number(fn, 0);
+	bts_set_current_block_frame_number(bts, fn, 0);
 
-	pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
+	pdch = &bts->trx[trx_no].pdch[ts_no];
 	pdch->rcv_block(&buf[0], num_bytes, fn, &meas);
 }
 
@@ -678,7 +673,7 @@
 		&ulreq, tbf->poll_fn);
 }
 
-static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(BTS *the_bts,
+static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(struct gprs_rlcmac_bts *bts,
 	uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
 	uint8_t ms_class, uint8_t egprs_ms_class)
 {
@@ -689,12 +684,9 @@
 	int tfi = 0;
 	gprs_rlcmac_ul_tbf *ul_tbf;
 	struct gprs_rlcmac_pdch *pdch;
-	gprs_rlcmac_bts *bts;
 	RlcMacUplink_t ulreq = {0};
 	struct gprs_rlc_ul_header_egprs_3 *egprs3  = NULL;
 
-	bts = the_bts->bts_data();
-
 	/* needed to set last_rts_fn in the PDCH object */
 	request_dl_rlc_block(bts, trx_no, ts_no, fn);
 
@@ -702,10 +694,10 @@
 	 * simulate RACH, this sends an Immediate
 	 * Assignment Uplink on the AGCH
 	 */
-	bts_handle_rach(the_bts, 0x73, rach_fn, qta);
+	bts_handle_rach(bts, 0x73, rach_fn, qta);
 
 	/* get next free TFI */
-	tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
+	tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
 
 	/* fake a resource request */
 	ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
@@ -733,10 +725,10 @@
 			Multislot_capability.EGPRS_multislot_class = ms_class;
 	}
 
-	send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
+	send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);
 
 	/* check the TBF */
-	ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
+	ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
 	OSMO_ASSERT(ul_tbf);
 	OSMO_ASSERT(ul_tbf->ta() == qta / 4);
 
@@ -755,10 +747,10 @@
 		1, /* BSN:7, E:1 */
 	};
 
-	pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
+	pdch = &bts->trx[trx_no].pdch[ts_no];
 	pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
 
-	ms = the_bts->ms_by_tlli(tlli);
+	ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms != NULL);
 	OSMO_ASSERT(ms_ta(ms) == qta/4);
 	OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
@@ -825,7 +817,7 @@
 	return ul_tbf;
 }
 
-static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(BTS *the_bts,
+static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(struct gprs_rlcmac_bts *bts,
 	uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
 	uint8_t ms_class, uint8_t egprs_ms_class)
 {
@@ -836,12 +828,9 @@
 	int tfi = 0, i = 0;
 	gprs_rlcmac_ul_tbf *ul_tbf;
 	struct gprs_rlcmac_pdch *pdch;
-	gprs_rlcmac_bts *bts;
 	RlcMacUplink_t ulreq = {0};
 	struct gprs_rlc_ul_header_egprs_3 *egprs3  = NULL;
 
-	bts = the_bts->bts_data();
-
 	/* needed to set last_rts_fn in the PDCH object */
 	request_dl_rlc_block(bts, trx_no, ts_no, fn);
 
@@ -849,10 +838,10 @@
 	 * simulate RACH, this sends an Immediate
 	 * Assignment Uplink on the AGCH
 	 */
-	bts_handle_rach(the_bts, 0x73, rach_fn, qta);
+	bts_handle_rach(bts, 0x73, rach_fn, qta);
 
 	/* get next free TFI */
-	tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
+	tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
 
 	/* fake a resource request */
 	ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
@@ -880,10 +869,10 @@
 			Multislot_capability.EGPRS_multislot_class = ms_class;
 	}
 
-	send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
+	send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);
 
 	/* check the TBF */
-	ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
+	ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
 	OSMO_ASSERT(ul_tbf != NULL);
 	OSMO_ASSERT(ul_tbf->ta() == qta / 4);
 
@@ -903,10 +892,10 @@
 		uint8_t(1), /* BSN:7, E:1 */
 	};
 
-	pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
+	pdch = &bts->trx[trx_no].pdch[ts_no];
 	pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
 
-	ms = the_bts->ms_by_tlli(tlli);
+	ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms != NULL);
 	OSMO_ASSERT(ms_ta(ms) == qta/4);
 	OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
@@ -1263,7 +1252,7 @@
 	return ul_tbf;
 }
 
-static gprs_rlcmac_ul_tbf *establish_ul_tbf(BTS *the_bts,
+static gprs_rlcmac_ul_tbf *establish_ul_tbf(struct gprs_rlcmac_bts *bts,
 	uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
 	uint8_t ms_class, uint8_t egprs_ms_class)
 {
@@ -1272,11 +1261,8 @@
 	uint8_t trx_no = 0;
 	int tfi = 0;
 	gprs_rlcmac_ul_tbf *ul_tbf;
-	gprs_rlcmac_bts *bts;
 	RlcMacUplink_t ulreq = {0};
 
-	bts = the_bts->bts_data();
-
 	/* needed to set last_rts_fn in the PDCH object */
 	request_dl_rlc_block(bts, trx_no, ts_no, fn);
 
@@ -1284,10 +1270,10 @@
 	 * simulate RACH, this sends an Immediate
 	 * Assignment Uplink on the AGCH
 	 */
-	bts_handle_rach(the_bts, 0x73, rach_fn, qta);
+	bts_handle_rach(bts, 0x73, rach_fn, qta);
 
 	/* get next free TFI */
-	tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
+	tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
 
 	/* fake a resource request */
 	ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
@@ -1314,10 +1300,10 @@
 			MS_RA_capability_value[0].u.Content.
 			Multislot_capability.EGPRS_multislot_class = ms_class;
 	}
-	send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
+	send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);
 
 	/* check the TBF */
-	ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
+	ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
 	/* send packet uplink assignment */
 	*fn = sba_fn;
 	request_dl_rlc_block(ul_tbf, fn);
@@ -1330,7 +1316,7 @@
 	return ul_tbf;
 }
 
-static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_no_length(BTS *the_bts,
+static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_no_length(struct gprs_rlcmac_bts *bts,
 	uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
 	uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)
 {
@@ -1369,7 +1355,7 @@
 		data[5] = 0x0;
 		data[6] = 0x2b;
 		data[7] = 0x2b;
-		pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
+		pdch = &bts->trx[trx_no].pdch[ts_no];
 		pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
 	}
 	ul_tbf->create_ul_ack(*fn, ts_no);
@@ -1394,7 +1380,7 @@
 	data[6] = 0x2b;
 	data[7] = 0x2b;
 
-	pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
+	pdch = &bts->trx[trx_no].pdch[ts_no];
 	pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
 
 	request_dl_rlc_block(ul_tbf, fn);
@@ -1402,7 +1388,7 @@
 	check_tbf(ul_tbf);
 	OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));
 
-	ms = the_bts->ms_by_tlli(tlli);
+	ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms != NULL);
 	OSMO_ASSERT(ms_ta(ms) == qta/4);
 	OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
@@ -1410,7 +1396,7 @@
 	return ul_tbf;
 }
 
-static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_with_length(BTS *the_bts,
+static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_with_length(struct gprs_rlcmac_bts *bts,
 	uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
 	uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)
 {
@@ -1451,7 +1437,7 @@
 		data[5] = 0x0;
 		data[6] = 0x2b;
 		data[7] = 0x2b;
-		pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
+		pdch = &bts->trx[trx_no].pdch[ts_no];
 		pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
 	}
 	ul_tbf->create_ul_ack(*fn, ts_no);
@@ -1476,7 +1462,7 @@
 	data[6] = 0x2b;
 	data[7] = 0x2b;
 
-	pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
+	pdch = &bts->trx[trx_no].pdch[ts_no];
 	pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
 	ul_tbf->create_ul_ack(*fn, ts_no);
 
@@ -1485,7 +1471,7 @@
 	check_tbf(ul_tbf);
 	OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));
 
-	ms = the_bts->ms_by_tlli(tlli);
+	ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms != NULL);
 	OSMO_ASSERT(ms_ta(ms) == qta/4);
 	OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
@@ -1493,7 +1479,7 @@
 	return ul_tbf;
 }
 
-static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_CRBB(BTS *the_bts,
+static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_CRBB(struct gprs_rlcmac_bts *bts,
 	uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
 	uint8_t ms_class, uint8_t egprs_ms_class)
 {
@@ -1504,7 +1490,7 @@
 	struct gprs_rlcmac_pdch *pdch;
 
 	/* check the TBF */
-	ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
+	ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
 	OSMO_ASSERT(ul_tbf);
 	OSMO_ASSERT(ul_tbf->ta() == qta / 4);
 
@@ -1537,7 +1523,7 @@
 		data[5] = 0x0;
 		data[6] = 0x2b;
 		data[7] = 0x2b;
-		pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
+		pdch = &bts->trx[trx_no].pdch[ts_no];
 		pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
 	}
 	ul_tbf->create_ul_ack(*fn, ts_no);
@@ -1562,7 +1548,7 @@
 	data[6] = 0x2b;
 	data[7] = 0x2b;
 
-	pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
+	pdch = &bts->trx[trx_no].pdch[ts_no];
 	pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
 
 	request_dl_rlc_block(ul_tbf, fn);
@@ -1570,14 +1556,14 @@
 	check_tbf(ul_tbf);
 	OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));
 
-	ms = the_bts->ms_by_tlli(tlli);
+	ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms != NULL);
 	OSMO_ASSERT(ms_ta(ms) == qta/4);
 	OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
 
 	return ul_tbf;
 }
-static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase(BTS *the_bts,
+static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase(struct gprs_rlcmac_bts *bts,
 	uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
 	uint8_t ms_class, uint8_t egprs_ms_class)
 {
@@ -1588,19 +1574,16 @@
 	int tfi = 0;
 	gprs_rlcmac_ul_tbf *ul_tbf;
 	struct gprs_rlcmac_pdch *pdch;
-	gprs_rlcmac_bts *bts;
 	RlcMacUplink_t ulreq = {0};
 
-	bts = the_bts->bts_data();
-
 	/* needed to set last_rts_fn in the PDCH object */
 	request_dl_rlc_block(bts, trx_no, ts_no, fn);
 
 	/* simulate RACH, sends an Immediate Assignment Uplink on the AGCH */
-	bts_handle_rach(the_bts, 0x73, rach_fn, qta);
+	bts_handle_rach(bts, 0x73, rach_fn, qta);
 
 	/* get next free TFI */
-	tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
+	tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
 
 	/* fake a resource request */
 	ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
@@ -1627,10 +1610,10 @@
 			EGPRS_multislot_class = ms_class;
 	}
 
-	send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
+	send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);
 
 	/* check the TBF */
-	ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
+	ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
 	OSMO_ASSERT(ul_tbf != NULL);
 	OSMO_ASSERT(ul_tbf->ta() == qta / 4);
 
@@ -1650,10 +1633,10 @@
 		uint8_t(1), /* BSN:7, E:1 */
 	};
 
-	pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
+	pdch = &bts->trx[trx_no].pdch[ts_no];
 	pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
 
-	ms = the_bts->ms_by_tlli(tlli);
+	ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms != NULL);
 	OSMO_ASSERT(ms_ta(ms) == qta/4);
 	OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
@@ -1661,34 +1644,34 @@
 	return ul_tbf;
 }
 
-static void send_dl_data(BTS *the_bts, uint32_t tlli, const char *imsi,
+static void send_dl_data(struct gprs_rlcmac_bts *bts, uint32_t tlli, const char *imsi,
 	const uint8_t *data, unsigned data_size)
 {
 	GprsMs *ms, *ms2;
 
-	ms = the_bts->ms_store().get_ms(tlli, 0, imsi);
+	ms = bts_ms_store(bts)->get_ms(tlli, 0, imsi);
 
-	gprs_rlcmac_dl_tbf::handle(the_bts->bts_data(), tlli, 0, imsi, 0, 0,
+	gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, 0, 0,
 		1000, data, data_size);
 
-	ms = the_bts->ms_by_imsi(imsi);
+	ms = bts_ms_by_imsi(bts, imsi);
 	OSMO_ASSERT(ms != NULL);
 	OSMO_ASSERT(ms_dl_tbf(ms) != NULL);
 
 	if (imsi[0] && strcmp(imsi, "000") != 0) {
-		ms2 = the_bts->ms_by_tlli(tlli);
+		ms2 = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
 		OSMO_ASSERT(ms == ms2);
 	}
 }
 
-static void transmit_dl_data(BTS *the_bts, uint32_t tlli, uint32_t *fn,
+static void transmit_dl_data(struct gprs_rlcmac_bts *bts, uint32_t tlli, uint32_t *fn,
 	uint8_t slots = 0xff)
 {
 	gprs_rlcmac_dl_tbf *dl_tbf;
 	GprsMs *ms;
 	unsigned ts_no;
 
-	ms = the_bts->ms_by_tlli(tlli);
+	ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms);
 	dl_tbf = ms_dl_tbf(ms);
 	OSMO_ASSERT(dl_tbf);
@@ -1698,7 +1681,7 @@
 		for (ts_no = 0 ; ts_no < 8; ts_no += 1) {
 			if (!(slots & (1 << ts_no)))
 				continue;
-			gprs_rlcmac_rcv_rts_block(the_bts->bts_data(),
+			gprs_rlcmac_rcv_rts_block(bts,
 				dl_tbf->trx->trx_no, ts_no,
 				*fn, bn);
 		}
@@ -1717,7 +1700,7 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	int ts_no = 7;
 	uint32_t fn = DUMMY_FN; /* 17,25,9 */
 	uint32_t tlli = 0xf1223344;
@@ -1727,12 +1710,12 @@
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
-	setup_bts(the_bts, ts_no);
+	setup_bts(bts, ts_no);
 
-	ul_tbf = establish_ul_tbf_single_phase(the_bts, ts_no, tlli, &fn, qta);
+	ul_tbf = establish_ul_tbf_single_phase(bts, ts_no, tlli, &fn, qta);
 
 	print_ta_tlli(ul_tbf, true);
-	send_dl_data(the_bts, tlli, imsi, (const uint8_t *)"TEST", 4);
+	send_dl_data(bts, tlli, imsi, (const uint8_t *)"TEST", 4);
 
 	fprintf(stderr, "=== end %s ===\n", __func__);
 	TALLOC_FREE(the_pcu);
@@ -1742,7 +1725,7 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	int ts_no = 7;
 	uint32_t fn = 2654218;
 	uint16_t qta = 31;
@@ -1757,36 +1740,36 @@
 
 	memset(test_data, 1, sizeof(test_data));
 
-	setup_bts(the_bts, ts_no, 4);
-	the_bts->bts_data()->initial_mcs_dl = 9;
+	setup_bts(bts, ts_no, 4);
+	bts->initial_mcs_dl = 9;
 	the_pcu->vty.ws_base = 128;
 	the_pcu->vty.ws_pdch = 64;
 
-	ul_tbf = establish_ul_tbf(the_bts, ts_no, tlli, &fn, qta, ms_class, egprs_ms_class);
+	ul_tbf = establish_ul_tbf(bts, ts_no, tlli, &fn, qta, ms_class, egprs_ms_class);
 	/* Function to generate URBB with no length */
-	ul_tbf = establish_ul_tbf_two_phase_puan_URBB_no_length(the_bts, ts_no, tlli, &fn,
+	ul_tbf = establish_ul_tbf_two_phase_puan_URBB_no_length(bts, ts_no, tlli, &fn,
 		qta, ms_class, egprs_ms_class, ul_tbf);
 
 	print_ta_tlli(ul_tbf, true);
-	send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));
+	send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
 
 	static_cast<gprs_rlc_ul_window *>(ul_tbf->window())->reset_state();
 	/* Function to generate URBB with length */
-	ul_tbf = establish_ul_tbf_two_phase_puan_URBB_with_length(the_bts, ts_no, tlli, &fn,
+	ul_tbf = establish_ul_tbf_two_phase_puan_URBB_with_length(bts, ts_no, tlli, &fn,
 		qta, ms_class, egprs_ms_class, ul_tbf);
 
 	print_ta_tlli(ul_tbf, true);
-	send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));
+	send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
 
 	static_cast<gprs_rlc_ul_window *>(ul_tbf->window())->reset_state();
 	/* Function to generate CRBB */
 	the_pcu->vty.ws_base = 128;
 	the_pcu->vty.ws_pdch = 64;
-	ul_tbf = establish_ul_tbf_two_phase_puan_CRBB(the_bts, ts_no, tlli, &fn,
+	ul_tbf = establish_ul_tbf_two_phase_puan_CRBB(bts, ts_no, tlli, &fn,
 		qta, ms_class, egprs_ms_class);
 
 	print_ta_tlli(ul_tbf, true);
-	send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));
+	send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
 
 	TALLOC_FREE(the_pcu);
 	fprintf(stderr, "=== end %s ===\n", __func__);
@@ -1798,16 +1781,16 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	uint32_t fn = 2654218;
 	uint16_t qta = 31;
 	int ts_no = 7;
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
-	setup_bts(the_bts, ts_no, 4);
+	setup_bts(bts, ts_no, 4);
 
-	the_bts->bts_data()->trx[0].pdch[ts_no].disable();
+	bts->trx[0].pdch[ts_no].disable();
 
 	uint32_t rach_fn = fn - 51;
 
@@ -1817,7 +1800,7 @@
 	 * simulate RACH, sends an Immediate Assignment
 	 * Uplink reject on the AGCH
 	 */
-	rc = bts_handle_rach(the_bts, 0x70, rach_fn, qta);
+	rc = bts_handle_rach(bts, 0x70, rach_fn, qta);
 
 	OSMO_ASSERT(rc == -EINVAL);
 
@@ -1832,14 +1815,14 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	uint32_t fn = 2654218;
 	uint16_t qta = 31;
 	int ts_no = 7;
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
-	setup_bts(the_bts, ts_no, 4);
+	setup_bts(bts, ts_no, 4);
 
 	uint32_t rach_fn = fn - 51;
 
@@ -1849,14 +1832,14 @@
 	 * simulate RACH, sends an Immediate Assignment Uplink
 	 * reject on the AGCH
 	 */
-	rc = bts_handle_rach(the_bts, 0x78, rach_fn, qta);
-	rc = bts_handle_rach(the_bts, 0x79, rach_fn, qta);
-	rc = bts_handle_rach(the_bts, 0x7a, rach_fn, qta);
-	rc = bts_handle_rach(the_bts, 0x7b, rach_fn, qta);
-	rc = bts_handle_rach(the_bts, 0x7c, rach_fn, qta);
-	rc = bts_handle_rach(the_bts, 0x7d, rach_fn, qta);
-	rc = bts_handle_rach(the_bts, 0x7e, rach_fn, qta);
-	rc = bts_handle_rach(the_bts, 0x7f, rach_fn, qta);
+	rc = bts_handle_rach(bts, 0x78, rach_fn, qta);
+	rc = bts_handle_rach(bts, 0x79, rach_fn, qta);
+	rc = bts_handle_rach(bts, 0x7a, rach_fn, qta);
+	rc = bts_handle_rach(bts, 0x7b, rach_fn, qta);
+	rc = bts_handle_rach(bts, 0x7c, rach_fn, qta);
+	rc = bts_handle_rach(bts, 0x7d, rach_fn, qta);
+	rc = bts_handle_rach(bts, 0x7e, rach_fn, qta);
+	rc = bts_handle_rach(bts, 0x7f, rach_fn, qta);
 
 	OSMO_ASSERT(rc == -EBUSY);
 
@@ -1874,7 +1857,7 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	int ts_no = 7;
 	uint32_t fn = 2654218;
 	uint16_t qta = 31;
@@ -1885,13 +1868,13 @@
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
-	setup_bts(the_bts, ts_no, 4);
+	setup_bts(bts, ts_no, 4);
 
-	ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli, &fn, qta,
+	ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli, &fn, qta,
 		ms_class, 0);
 
 	print_ta_tlli(ul_tbf, true);
-	send_dl_data(the_bts, tlli, imsi, (const uint8_t *)"TEST", 4);
+	send_dl_data(bts, tlli, imsi, (const uint8_t *)"TEST", 4);
 
 	TALLOC_FREE(the_pcu);
 	fprintf(stderr, "=== end %s ===\n", __func__);
@@ -1907,7 +1890,7 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	int ts_no = 7;
 	uint32_t fn = 2654218;
 	uint16_t qta = 31;
@@ -1920,15 +1903,15 @@
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
-	setup_bts(the_bts, ts_no, 4);
+	setup_bts(bts, ts_no, 4);
 
-	ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli1, &fn, qta,
+	ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta,
 		ms_class, 0);
 
 	ms1 = ul_tbf->ms();
 	print_ta_tlli(ul_tbf, false);
 
-	send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)"RAU_ACCEPT", 10);
+	send_dl_data(bts, tlli1, imsi, (const uint8_t *)"RAU_ACCEPT", 10);
 	print_ms(ms1, true);
 
 	/* Send Packet Downlink Assignment to MS */
@@ -1939,11 +1922,11 @@
 
 	/* Make sure the RAU Accept gets sent to the MS */
 	OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 1);
-	transmit_dl_data(the_bts, tlli1, &fn);
+	transmit_dl_data(bts, tlli1, &fn);
 	OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 0);
 
 	/* Now establish a new TBF for the RA UPDATE COMPLETE (new TLLI) */
-	ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli2, &fn, qta,
+	ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli2, &fn, qta,
 		ms_class, 0);
 
 	ms2 = ul_tbf->ms();
@@ -1954,16 +1937,16 @@
 
 	/* Send some downlink data along with the new TLLI and the IMSI so that
 	 * the PCU can see, that both MS objects belong to same MS */
-	send_dl_data(the_bts, tlli2, imsi, (const uint8_t *)"DATA", 4);
+	send_dl_data(bts, tlli2, imsi, (const uint8_t *)"DATA", 4);
 
-	ms = the_bts->ms_by_imsi(imsi);
+	ms = bts_ms_by_imsi(bts, imsi);
 	OSMO_ASSERT(ms == ms2);
 
 	print_ms(ms2, false);
 
-	ms = the_bts->ms_by_tlli(tlli1);
+	ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms == NULL);
-	ms = the_bts->ms_by_tlli(tlli2);
+	ms = bts_ms_by_tlli(bts, tlli2, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms == ms2);
 
 	TALLOC_FREE(the_pcu);
@@ -1974,7 +1957,7 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	int ts_no = 7;
 	uint32_t fn = 2654218;
 	uint16_t qta = 31;
@@ -1987,16 +1970,16 @@
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
-	setup_bts(the_bts, ts_no, 1);
+	setup_bts(bts, ts_no, 1);
 
-	ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli1, &fn, qta,
+	ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta,
 		ms_class, 0);
 
 	ms1 = ul_tbf->ms();
 	print_ta_tlli(ul_tbf, false);
 
-	send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
-	send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
+	send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
+	send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
 	print_ms(ms1, true);
 
 	OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 2);
@@ -2005,11 +1988,11 @@
 
 	/* Get rid of old UL TBF */
 	tbf_free(ul_tbf);
-	ms = the_bts->ms_by_tlli(tlli1);
+	ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms1 == ms);
 
 	/* Now establish a new UL TBF, this will consume one LLC packet */
-	ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli1, &fn, qta,
+	ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta,
 		ms_class, 0);
 
 	ms2 = ul_tbf->ms();
@@ -2018,7 +2001,7 @@
 	/* This should be the same MS object */
 	OSMO_ASSERT(ms2 == ms1);
 
-	ms = the_bts->ms_by_tlli(tlli1);
+	ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms2 == ms);
 
 	/* A DL TBF should still exist */
@@ -2036,7 +2019,7 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	int ts_no = 7;
 	uint32_t fn = 2654218;
 	uint16_t qta = 31;
@@ -2049,16 +2032,16 @@
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
-	setup_bts(the_bts, ts_no, 1);
+	setup_bts(bts, ts_no, 1);
 
-	ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli1, &fn, qta,
+	ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta,
 		ms_class, 0);
 
 	ms1 = ul_tbf->ms();
 	print_ta_tlli(ul_tbf, false);
 
-	send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
-	send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
+	send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
+	send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
 	print_ms(ms1, true);
 
 	OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 2);
@@ -2067,11 +2050,11 @@
 
 	/* Get rid of old UL TBF */
 	tbf_free(ul_tbf);
-	ms = the_bts->ms_by_tlli(tlli1);
+	ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms1 == ms);
 
 	/* Now establish a new UL TBF */
-	ul_tbf = establish_ul_tbf_single_phase(the_bts, ts_no, tlli1, &fn, qta);
+	ul_tbf = establish_ul_tbf_single_phase(bts, ts_no, tlli1, &fn, qta);
 
 	ms2 = ul_tbf->ms();
 	print_ms(ms2, false);
@@ -2079,7 +2062,7 @@
 	/* There should be a different MS object */
 	OSMO_ASSERT(ms2 != ms1);
 
-	ms = the_bts->ms_by_tlli(tlli1);
+	ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms2 == ms);
 	OSMO_ASSERT(ms1 != ms);
 
@@ -2097,7 +2080,7 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	int ts_no = 7;
 	uint32_t fn = 2654218;
 	uint16_t qta = 31;
@@ -2112,9 +2095,9 @@
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
-	setup_bts(the_bts, ts_no, 1);
+	setup_bts(bts, ts_no, 1);
 
-	ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli1, &fn, qta,
+	ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta,
 		ms_class, 0);
 
 	ms1 = ul_tbf->ms();
@@ -2128,7 +2111,7 @@
 		rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i", i);
 		OSMO_ASSERT(rc > 0);
 
-		send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)buf, rc);
+		send_dl_data(bts, tlli1, imsi, (const uint8_t *)buf, rc);
 	}
 
 	print_ms(ms1, true);
@@ -2140,7 +2123,7 @@
 	send_control_ack(ul_tbf);
 
 	/* Transmit all data */
-	transmit_dl_data(the_bts, tlli1, &fn);
+	transmit_dl_data(bts, tlli1, &fn);
 	OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 0);
 	OSMO_ASSERT(ms_dl_tbf(ms1));
 	OSMO_ASSERT(ms_dl_tbf(ms1)->state_is(GPRS_RLCMAC_FINISHED));
@@ -2155,7 +2138,7 @@
 		rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i (TBF 2)", i);
 		OSMO_ASSERT(rc > 0);
 
-		send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)buf, rc);
+		send_dl_data(bts, tlli1, imsi, (const uint8_t *)buf, rc);
 	}
 
 	/* Fake Final DL Ack/Nack */
@@ -2166,13 +2149,13 @@
 	ack->DOWNLINK_TFI = dl_tbf1->tfi();
 	ack->Ack_Nack_Description.FINAL_ACK_INDICATION = 1;
 
-	send_ul_mac_block(the_bts, 0, dl_tbf1->poll_ts, &ulreq, dl_tbf1->poll_fn);
+	send_ul_mac_block(bts, 0, dl_tbf1->poll_ts, &ulreq, dl_tbf1->poll_fn);
 
 	OSMO_ASSERT(dl_tbf1->state_is(GPRS_RLCMAC_WAIT_RELEASE));
 
 	request_dl_rlc_block(dl_tbf1, &fn);
 
-	ms2 = the_bts->ms_by_tlli(tlli1);
+	ms2 = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms2 == ms1);
 	OSMO_ASSERT(ms_dl_tbf(ms2));
 	OSMO_ASSERT(ms_dl_tbf(ms2)->state_is(GPRS_RLCMAC_ASSIGN));
@@ -2185,7 +2168,7 @@
 	OSMO_ASSERT(dl_tbf2->state_is(GPRS_RLCMAC_FLOW));
 
 	/* Transmit all data */
-	transmit_dl_data(the_bts, tlli1, &fn);
+	transmit_dl_data(bts, tlli1, &fn);
 	OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms2)) == 0);
 	OSMO_ASSERT(ms_dl_tbf(ms2));
 	OSMO_ASSERT(ms_dl_tbf(ms2)->state_is(GPRS_RLCMAC_FINISHED));
@@ -2198,8 +2181,7 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
-	gprs_rlcmac_bts *bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	uint8_t ts_no = 4;
 	uint8_t ms_class = 45;
 	int rc = 0;
@@ -2211,14 +2193,13 @@
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
-	bts = the_bts->bts_data();
-	the_bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
-	if (!the_bts->pcu->nsi) {
+	bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
+	if (!bts->pcu->nsi) {
 		LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
 		abort();
 	}
 
-	setup_bts(the_bts, ts_no);
+	setup_bts(bts, ts_no);
 
 	/* EGPRS-only */
 
@@ -2238,7 +2219,7 @@
 static inline void ws_check(gprs_rlcmac_dl_tbf *dl_tbf, const char *test, uint8_t exp_slots, uint16_t exp_ws,
 			    bool free, bool end)
 {
-	gprs_rlcmac_bts *bts = dl_tbf->bts->bts_data();
+	gprs_rlcmac_bts *bts = dl_tbf->bts;
 	if (!dl_tbf) {
 		fprintf(stderr, "%s(): FAILED (NULL TBF)\n", test);
 		return;
@@ -2268,8 +2249,7 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
-	gprs_rlcmac_bts *bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	GprsMs *ms;
 	uint8_t ts_no = 4;
 	uint8_t ms_class = 12;
@@ -2277,14 +2257,13 @@
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
-	bts = the_bts->bts_data();
-	the_bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
-	if (!the_bts->pcu->nsi) {
+	bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
+	if (!bts->pcu->nsi) {
 		LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
 		abort();
 	}
 
-	setup_bts(the_bts, ts_no);
+	setup_bts(bts, ts_no);
 
 	the_pcu->vty.ws_base = 128;
 	the_pcu->vty.ws_pdch = 64;
@@ -2297,7 +2276,7 @@
 	gprs_bssgp_init(bts, 4234, 4234, 1, 1, false, 0, 0, 0);
 
 	/* Does no support EGPRS */
-	ms = the_bts->ms_alloc(ms_class, 0);
+	ms = bts_alloc_ms(bts, ms_class, 0);
 	dl_tbf = tbf_alloc_dl_tbf(bts, ms, 0, false);
 
 	ws_check(dl_tbf, __func__, 4, 64, true, false);
@@ -2305,7 +2284,7 @@
 	/* EGPRS-only */
 
 	/* Does support EGPRS */
-	ms = the_bts->ms_alloc(ms_class, ms_class);
+	ms = bts_alloc_ms(bts, ms_class, ms_class);
 	dl_tbf = tbf_alloc_dl_tbf(bts, ms, 0, false);
 
 	ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true, true);
@@ -2316,8 +2295,7 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
-	gprs_rlcmac_bts *bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	GprsMs *ms;
 	uint8_t ts_no = 4;
 	uint8_t ms_class = 11;
@@ -2325,14 +2303,13 @@
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
-	bts = the_bts->bts_data();
-	the_bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
-	if (!the_bts->pcu->nsi) {
+	bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
+	if (!bts->pcu->nsi) {
 		LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
 		abort();
 	}
 
-	setup_bts(the_bts, ts_no);
+	setup_bts(bts, ts_no);
 
 	the_pcu->vty.ws_base = 128;
 	the_pcu->vty.ws_pdch = 64;
@@ -2347,7 +2324,7 @@
 	/* EGPRS-only */
 
 	/* Does support EGPRS */
-	ms = the_bts->ms_alloc(ms_class, ms_class);
+	ms = bts_alloc_ms(bts, ms_class, ms_class);
 	dl_tbf = tbf_alloc_dl_tbf(bts, ms, 0, true);
 
 	ws_check(dl_tbf, __func__, 1, 128 + 1 * 64, false, false);
@@ -2363,7 +2340,7 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	int ts_no = 7;
 	uint32_t fn = 2654218;
 	uint16_t qta = 31;
@@ -2378,20 +2355,20 @@
 
 	memset(test_data, 1, sizeof(test_data));
 
-	setup_bts(the_bts, ts_no, 4);
-	the_bts->bts_data()->initial_mcs_dl = 9;
+	setup_bts(bts, ts_no, 4);
+	bts->initial_mcs_dl = 9;
 
-	ul_tbf = puan_urbb_len_issue(the_bts, ts_no, tlli, &fn, qta,
+	ul_tbf = puan_urbb_len_issue(bts, ts_no, tlli, &fn, qta,
 		ms_class, egprs_ms_class);
 
 	print_ta_tlli(ul_tbf, true);
-	send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));
+	send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
 
 	TALLOC_FREE(the_pcu);
 	fprintf(stderr, "=== end %s ===\n", __func__);
 }
 
-static gprs_rlcmac_ul_tbf *tbf_li_decoding(BTS *the_bts,
+static gprs_rlcmac_ul_tbf *tbf_li_decoding(struct gprs_rlcmac_bts *bts,
 	uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
 	uint8_t ms_class, uint8_t egprs_ms_class)
 {
@@ -2402,15 +2379,12 @@
 	int tfi = 0;
 	gprs_rlcmac_ul_tbf *ul_tbf;
 	struct gprs_rlcmac_pdch *pdch;
-	gprs_rlcmac_bts *bts;
 	RlcMacUplink_t ulreq = {0};
 	struct gprs_rlc_ul_header_egprs_3 *egprs3  = NULL;
 	Packet_Resource_Request_t *presreq = NULL;
 	MS_Radio_Access_capability_t *pmsradiocap = NULL;
 	Multislot_capability_t *pmultislotcap = NULL;
 
-	bts = the_bts->bts_data();
-
 	/* needed to set last_rts_fn in the PDCH object */
 	request_dl_rlc_block(bts, trx_no, ts_no, fn);
 
@@ -2418,10 +2392,10 @@
 	 * simulate RACH, this sends an Immediate
 	 * Assignment Uplink on the AGCH
 	 */
-	bts_handle_rach(the_bts, 0x73, rach_fn, qta);
+	bts_handle_rach(bts, 0x73, rach_fn, qta);
 
 	/* get next free TFI */
-	tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
+	tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
 
 	/* fake a resource request */
 	ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
@@ -2444,10 +2418,10 @@
 		pmultislotcap->EGPRS_multislot_class = ms_class;
 	}
 
-	send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
+	send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);
 
 	/* check the TBF */
-	ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
+	ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
 	OSMO_ASSERT(ul_tbf);
 	OSMO_ASSERT(ul_tbf->ta() == qta / 4);
 
@@ -2462,9 +2436,9 @@
 
 	uint8_t data_msg[49] = {0};
 
-	pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
+	pdch = &bts->trx[trx_no].pdch[ts_no];
 
-	ms = the_bts->ms_by_tlli(tlli);
+	ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms != NULL);
 	OSMO_ASSERT(ms_ta(ms) == qta/4);
 	OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
@@ -2506,7 +2480,7 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	int ts_no = 7;
 	uint32_t fn = 2654218;
 	uint16_t qta = 31;
@@ -2521,14 +2495,14 @@
 
 	memset(test_data, 1, sizeof(test_data));
 
-	setup_bts(the_bts, ts_no, 4);
-	the_bts->bts_data()->initial_mcs_dl = 9;
+	setup_bts(bts, ts_no, 4);
+	bts->initial_mcs_dl = 9;
 
-	ul_tbf = tbf_li_decoding(the_bts, ts_no, tlli, &fn, qta,
+	ul_tbf = tbf_li_decoding(bts, ts_no, tlli, &fn, qta,
 		ms_class, egprs_ms_class);
 
 	print_ta_tlli(ul_tbf, true);
-	send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));
+	send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
 
 	TALLOC_FREE(the_pcu);
 	fprintf(stderr, "=== end %s ===\n", __func__);
@@ -2543,7 +2517,7 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	uint8_t ms_class = 11;
 	uint8_t egprs_ms_class = 11;
 	uint8_t trx_no;
@@ -2564,7 +2538,7 @@
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
-	setup_bts(the_bts, ts_no);
+	setup_bts(bts, ts_no);
 	OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
 	/* ARQ II */
 	the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
@@ -2579,7 +2553,7 @@
 				0xff, 0xff, 0xfb, 0x80, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
 
-	dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no);
+	dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
 	dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
 	prlcdlwindow = static_cast<gprs_rlc_dl_window *>(dl_tbf->window());
 	prlcmvb = &prlcdlwindow->m_v_b;
@@ -2635,7 +2609,7 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	int ts_no = 7;
 	uint32_t fn = 2654218;
 	uint16_t qta = 31;
@@ -2650,14 +2624,14 @@
 
 	memset(test_data, 1, sizeof(test_data));
 
-	setup_bts(the_bts, ts_no, 4);
-	the_bts->bts_data()->initial_mcs_dl = 9;
+	setup_bts(bts, ts_no, 4);
+	bts->initial_mcs_dl = 9;
 
-	ul_tbf = establish_ul_tbf_two_phase_spb(the_bts, ts_no, tlli, &fn, qta,
+	ul_tbf = establish_ul_tbf_two_phase_spb(bts, ts_no, tlli, &fn, qta,
 		ms_class, egprs_ms_class);
 
 	print_ta_tlli(ul_tbf, true);
-	send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));
+	send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
 
 	TALLOC_FREE(the_pcu);
 	fprintf(stderr, "=== end %s ===\n", __func__);
@@ -2667,7 +2641,7 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	int ts_no = 7;
 	uint32_t fn = 2654218;
 	uint16_t qta = 31;
@@ -2682,20 +2656,20 @@
 
 	memset(test_data, 1, sizeof(test_data));
 
-	setup_bts(the_bts, ts_no, 4);
-	the_bts->bts_data()->initial_mcs_dl = 9;
+	setup_bts(bts, ts_no, 4);
+	bts->initial_mcs_dl = 9;
 
-	ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli, &fn, qta,
+	ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli, &fn, qta,
 		ms_class, egprs_ms_class);
 
 	print_ta_tlli(ul_tbf, true);
-	send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));
+	send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
 
 	TALLOC_FREE(the_pcu);
 	fprintf(stderr, "=== end %s ===\n", __func__);
 }
 
-static void establish_and_use_egprs_dl_tbf(BTS *the_bts, int mcs)
+static void establish_and_use_egprs_dl_tbf(struct gprs_rlcmac_bts *bts, int mcs)
 {
 	unsigned i;
 	uint8_t ms_class = 11;
@@ -2712,9 +2686,9 @@
 	fprintf(stderr, "Testing MCS-%d\n", mcs);
 
 	memset(test_data, 1, sizeof(test_data));
-	the_bts->bts_data()->initial_mcs_dl = mcs;
+	bts->initial_mcs_dl = mcs;
 
-	dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no);
+	dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
 	dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
 
 	for (i = 0; i < sizeof(llc_data); i++)
@@ -2753,7 +2727,7 @@
 	tbf_free(dl_tbf);
 }
 
-static gprs_rlcmac_dl_tbf *tbf_init(BTS *the_bts,
+static gprs_rlcmac_dl_tbf *tbf_init(struct gprs_rlcmac_bts *bts,
 		int mcs)
 {
 	unsigned i;
@@ -2766,9 +2740,9 @@
 	gprs_rlcmac_dl_tbf *dl_tbf;
 
 	memset(test_data, 1, sizeof(test_data));
-	the_bts->bts_data()->initial_mcs_dl = mcs;
+	bts->initial_mcs_dl = mcs;
 
-	dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no);
+	dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
 	dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
 
 	for (i = 0; i < sizeof(test_data); i++)
@@ -2830,7 +2804,7 @@
 			CHECK_NACKED(tbf, cs, 0);			\
 	} while(0)
 
-static void egprs_spb_to_normal_validation(BTS *the_bts,
+static void egprs_spb_to_normal_validation(struct gprs_rlcmac_bts *bts,
 		unsigned int mcs, unsigned int demanded_mcs)
 {
 	uint32_t fn = 0;
@@ -2842,7 +2816,7 @@
 
 	fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
 
-	dl_tbf = tbf_init(the_bts, mcs);
+	dl_tbf = tbf_init(bts, mcs);
 
 	/*
 	 * Table 10.4.8a.3.1 of 44.060.
@@ -2908,7 +2882,7 @@
 	tbf_cleanup(dl_tbf);
 }
 
-static void establish_and_use_egprs_dl_tbf_for_spb(BTS *the_bts,
+static void establish_and_use_egprs_dl_tbf_for_spb(struct gprs_rlcmac_bts *bts,
 		unsigned int mcs, unsigned int demanded_mcs)
 {
 	uint32_t fn = 0;
@@ -2918,7 +2892,7 @@
 
 	fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
 
-	dl_tbf = tbf_init(the_bts, mcs);
+	dl_tbf = tbf_init(bts, mcs);
 
 	/*
 	 * Table 10.4.8a.3.1 of 44.060.
@@ -2995,7 +2969,7 @@
 	tbf_cleanup(dl_tbf);
 }
 
-static void establish_and_use_egprs_dl_tbf_for_retx(BTS *the_bts,
+static void establish_and_use_egprs_dl_tbf_for_retx(struct gprs_rlcmac_bts *bts,
 		unsigned int mcs, unsigned int demanded_mcs)
 {
 	uint32_t fn = 0;
@@ -3004,7 +2978,7 @@
 
 	fprintf(stderr, "Testing retx for MCS %u - %u\n", mcs, demanded_mcs);
 
-	dl_tbf = tbf_init(the_bts, mcs);
+	dl_tbf = tbf_init(bts, mcs);
 
 	/* For MCS reduction cases like MCS9->MCS6, MCS7->MCS5
 	 * The MCS transition are referred from table Table 8.1.1.2
@@ -3091,26 +3065,26 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	uint8_t ts_no = 4;
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
 	the_pcu->vty.cs_downgrade_threshold = 0;
-	setup_bts(the_bts, ts_no);
+	setup_bts(bts, ts_no);
 	OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
 	/* ARQ II */
 	the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
 
 
 	/* First parameter is current MCS, second one is demanded_mcs */
-	establish_and_use_egprs_dl_tbf_for_retx(the_bts, 6, 6);
-	establish_and_use_egprs_dl_tbf_for_retx(the_bts, 1, 9);
-	establish_and_use_egprs_dl_tbf_for_retx(the_bts, 2, 8);
-	establish_and_use_egprs_dl_tbf_for_retx(the_bts, 5, 7);
-	establish_and_use_egprs_dl_tbf_for_retx(the_bts, 6, 9);
-	establish_and_use_egprs_dl_tbf_for_retx(the_bts, 7, 5);
-	establish_and_use_egprs_dl_tbf_for_retx(the_bts, 9, 6);
+	establish_and_use_egprs_dl_tbf_for_retx(bts, 6, 6);
+	establish_and_use_egprs_dl_tbf_for_retx(bts, 1, 9);
+	establish_and_use_egprs_dl_tbf_for_retx(bts, 2, 8);
+	establish_and_use_egprs_dl_tbf_for_retx(bts, 5, 7);
+	establish_and_use_egprs_dl_tbf_for_retx(bts, 6, 9);
+	establish_and_use_egprs_dl_tbf_for_retx(bts, 7, 5);
+	establish_and_use_egprs_dl_tbf_for_retx(bts, 9, 6);
 
 	TALLOC_FREE(the_pcu);
 	fprintf(stderr, "=== end %s ===\n", __func__);
@@ -3120,13 +3094,13 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	uint8_t ts_no = 4;
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
 	the_pcu->vty.cs_downgrade_threshold = 0;
-	setup_bts(the_bts, ts_no);
+	setup_bts(bts, ts_no);
 	OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
 
 	/* ARQ I resegmentation support */
@@ -3137,11 +3111,11 @@
 	 * currently only MCS5->MCS2, MCS6->3, MCS4->MCS1 is tested in UT
 	 * rest scenarios has been integration tested
 	 */
-	establish_and_use_egprs_dl_tbf_for_spb(the_bts, 6, 3);
-	establish_and_use_egprs_dl_tbf_for_spb(the_bts, 5, 2);
-	establish_and_use_egprs_dl_tbf_for_spb(the_bts, 4, 1);
+	establish_and_use_egprs_dl_tbf_for_spb(bts, 6, 3);
+	establish_and_use_egprs_dl_tbf_for_spb(bts, 5, 2);
+	establish_and_use_egprs_dl_tbf_for_spb(bts, 4, 1);
 	/* check MCS6->(MCS3+MCS3)->MCS6 case */
-	egprs_spb_to_normal_validation(the_bts, 6, 3);
+	egprs_spb_to_normal_validation(bts, 6, 3);
 
 	TALLOC_FREE(the_pcu);
 	fprintf(stderr, "=== end %s ===\n", __func__);
@@ -3151,19 +3125,19 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	uint8_t ts_no = 4;
 	int i;
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
-	setup_bts(the_bts, ts_no);
+	setup_bts(bts, ts_no);
 	OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
 	/* ARQ II */
 	the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
 
 	for (i = 1; i <= 9; i++)
-		establish_and_use_egprs_dl_tbf(the_bts, i);
+		establish_and_use_egprs_dl_tbf(bts, i);
 
 	TALLOC_FREE(the_pcu);
 	fprintf(stderr, "=== end %s ===\n", __func__);
@@ -3175,7 +3149,7 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	uint32_t fn = 2654218;
 	int ts_no = 7;
 	uint8_t trx_no = 0;
@@ -3184,11 +3158,11 @@
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
-	setup_bts(the_bts, ts_no, 4);
+	setup_bts(bts, ts_no, 4);
 
 	int rc = 0;
 
-	ul_tbf = handle_tbf_reject(the_bts->bts_data(), NULL, tlli,
+	ul_tbf = handle_tbf_reject(bts, NULL, tlli,
 				trx_no, ts_no);
 
 	OSMO_ASSERT(ul_tbf != 0);
@@ -3196,7 +3170,7 @@
 	/* trigger packet access reject */
 	uint8_t bn = fn2bn(fn);
 
-	rc = gprs_rlcmac_rcv_rts_block(the_bts->bts_data(),
+	rc = gprs_rlcmac_rcv_rts_block(bts,
 		trx_no, ts_no, fn, bn);
 
 	OSMO_ASSERT(rc == 0);
@@ -3211,7 +3185,7 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	uint32_t fn = 2654218;
 	uint16_t qta = 31;
 	int ts_no = 7;
@@ -3228,20 +3202,20 @@
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
-	setup_bts(the_bts, ts_no, 4);
+	setup_bts(bts, ts_no, 4);
 
 	int rc = 0;
 
 	/*
 	 * Trigger rach till resources(USF) exhaust
 	 */
-	rc = bts_handle_rach(the_bts, 0x78, rach_fn, qta);
-	rc = bts_handle_rach(the_bts, 0x79, rach_fn, qta);
-	rc = bts_handle_rach(the_bts, 0x7a, rach_fn, qta);
-	rc = bts_handle_rach(the_bts, 0x7b, rach_fn, qta);
-	rc = bts_handle_rach(the_bts, 0x7c, rach_fn, qta);
-	rc = bts_handle_rach(the_bts, 0x7d, rach_fn, qta);
-	rc = bts_handle_rach(the_bts, 0x7e, rach_fn, qta);
+	rc = bts_handle_rach(bts, 0x78, rach_fn, qta);
+	rc = bts_handle_rach(bts, 0x79, rach_fn, qta);
+	rc = bts_handle_rach(bts, 0x7a, rach_fn, qta);
+	rc = bts_handle_rach(bts, 0x7b, rach_fn, qta);
+	rc = bts_handle_rach(bts, 0x7c, rach_fn, qta);
+	rc = bts_handle_rach(bts, 0x7d, rach_fn, qta);
+	rc = bts_handle_rach(bts, 0x7e, rach_fn, qta);
 
 	/* fake a resource request */
 	ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
@@ -3264,12 +3238,12 @@
 		pmultislotcap->EGPRS_multislot_class = egprs_ms_class;
 	}
 
-	send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
+	send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);
 
 	/* trigger packet access reject */
 	uint8_t bn = fn2bn(fn);
 
-	rc = gprs_rlcmac_rcv_rts_block(the_bts->bts_data(),
+	rc = gprs_rlcmac_rcv_rts_block(bts,
 		trx_no, ts_no, fn, bn);
 
 	OSMO_ASSERT(rc == 0);
@@ -3282,7 +3256,7 @@
 {
 	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
 	the_pcu->bts = bts_alloc(the_pcu);
-	BTS *the_bts = the_pcu->bts;
+	struct gprs_rlcmac_bts *bts = the_pcu->bts;
 	uint32_t tlli = 0xffeeddcc;
 	static uint8_t exp[] = { 0x40, 0x84, 0x7f, 0xf7, 0x6e, 0xe6, 0x41, 0x4b,
 				 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
@@ -3290,8 +3264,8 @@
 	};
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
-	setup_bts(the_bts, 4);
-	static gprs_rlcmac_dl_tbf *dl_tbf = tbf_init(the_bts, 1);
+	setup_bts(bts, 4);
+	static gprs_rlcmac_dl_tbf *dl_tbf = tbf_init(bts, 1);
 
 	dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
 
diff --git a/tests/types/TypesTest.cpp b/tests/types/TypesTest.cpp
index 7e5d35a..2da6a64 100644
--- a/tests/types/TypesTest.cpp
+++ b/tests/types/TypesTest.cpp
@@ -23,6 +23,7 @@
 #include "bts.h"
 #include "tbf.h"
 #include "tbf_ul.h"
+#include "tbf_dl.h"
 #include "pcu_utils.h"
 #include "gprs_debug.h"
 #include "encoding.h"
@@ -352,7 +353,7 @@
 		uint16_t lost = 0, recv = 0;
 		char show_rbb[65];
 		uint8_t bits_data[8];
-		BTS dummy_bts(the_pcu);
+		struct gprs_rlcmac_bts *dummy_bts = bts_alloc(the_pcu);
 		gprs_rlc_dl_window dl_win;
 		bitvec bits;
 		int bsn_begin, bsn_end, num_blocks;
@@ -391,7 +392,7 @@
 		Decoding::extract_rbb(&bits, show_rbb);
 		printf("show_rbb: %s\n", show_rbb);
 
-		dl_win.update(&dummy_bts, &bits, 0, &lost, &recv);
+		dl_win.update(dummy_bts, &bits, 0, &lost, &recv);
 		OSMO_ASSERT(lost == 0);
 		OSMO_ASSERT(recv == 35);
 		OSMO_ASSERT(bsn_begin == 0);
@@ -423,7 +424,7 @@
 		printf("show_rbb: %s\n", show_rbb);
 
 		lost = recv = 0;
-		dl_win.update(&dummy_bts, &bits, 0, &lost, &recv);
+		dl_win.update(dummy_bts, &bits, 0, &lost, &recv);
 		OSMO_ASSERT(lost == 5);
 		OSMO_ASSERT(recv == 3);
 		OSMO_ASSERT(bitvec_get_bit_pos(&bits, 0) == 0);
@@ -431,6 +432,7 @@
 		OSMO_ASSERT(bsn_begin == 35);
 		OSMO_ASSERT(bsn_end == 43);
 		OSMO_ASSERT(num_blocks == 8);
+		talloc_free(dummy_bts);
 	}
 }
 
@@ -669,12 +671,12 @@
 
 	fprintf(stderr, "############## test_egprs_ul_ack_nack\n");
 
-	BTS the_bts(the_pcu);
+	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
 	the_pcu->alloc_algorithm = alloc_algorithm_a;
-	the_bts.bts_data()->trx[0].pdch[4].enable();
+	bts->trx[0].pdch[4].enable();
 
-	GprsMs *ms = the_bts.ms_alloc(1, 1);
-	struct gprs_rlcmac_ul_tbf *tbf = tbf_alloc_ul_tbf(the_bts.bts_data(), ms, 0, true);
+	GprsMs *ms = bts_alloc_ms(bts, 1, 1);
+	struct gprs_rlcmac_ul_tbf *tbf = tbf_alloc_ul_tbf(bts, ms, 0, true);
 	struct crbb_test crbb_test = {0};
 	bitvec *rbb = NULL;
 	unsigned int rbb_size;
@@ -722,6 +724,7 @@
 	extract_egprs_ul_ack_nack(tbf, dest, &ssn, &crbb_test, &rbb, false);
 	check_egprs_bitmap(tbf, ssn, &crbb_test, rbb, &rbb_size);
 	free_egprs_ul_ack_nack(&rbb, &crbb_test);
+	talloc_free(bts);
 }
 
 static void check_imm_ass(struct gprs_rlcmac_tbf *tbf, bool dl, enum ph_burst_type bt, const uint8_t *exp, uint8_t len,
@@ -759,13 +762,13 @@
 
 void test_immediate_assign_dl()
 {
-	BTS the_bts(the_pcu);
+	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
 	the_pcu->alloc_algorithm = alloc_algorithm_a;
-	the_bts.bts_data()->trx[0].pdch[2].enable();
-	the_bts.bts_data()->trx[0].pdch[3].enable();
-	GprsMs *ms = the_bts.ms_alloc(1, 0);
+	bts->trx[0].pdch[2].enable();
+	bts->trx[0].pdch[3].enable();
+	GprsMs *ms = bts_alloc_ms(bts, 1, 0);
 
-	struct gprs_rlcmac_tbf *tbf = tbf_alloc_dl_tbf(the_bts.bts_data(), ms, 0, false);
+	struct gprs_rlcmac_tbf *tbf = tbf_alloc_dl_tbf(bts, ms, 0, false);
 	static uint8_t res[] = { 0x06,
 				 0x3f, /* Immediate Assignment Message Type */
 				 0x30, /* §10.5.2.26 Page Mode and §10.5.2.25b Dedicated mode/TBF */
@@ -779,17 +782,18 @@
 				 0xdf, 0xff, 0xff, 0xff, 0xf8, 0x17, 0x47, 0x08, 0x0b, 0x5b, 0x2b, 0x2b, };
 
 	check_imm_ass(tbf, true, GSM_L1_BURST_TYPE_ACCESS_2, res, sizeof(res), "ia_rest_downlink");
+	talloc_free(bts);
 }
 
 void test_immediate_assign_ul0m()
 {
-	BTS the_bts(the_pcu);
+	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
 	the_pcu->alloc_algorithm = alloc_algorithm_a;
-	the_bts.bts_data()->trx[0].pdch[4].enable();
-	the_bts.bts_data()->trx[0].pdch[5].enable();
+	bts->trx[0].pdch[4].enable();
+	bts->trx[0].pdch[5].enable();
 
-	GprsMs *ms = the_bts.ms_alloc(1, 0);
-	struct gprs_rlcmac_tbf *tbf = tbf_alloc_ul_tbf(the_bts.bts_data(), ms, 0, false);
+	GprsMs *ms = bts_alloc_ms(bts, 1, 0);
+	struct gprs_rlcmac_tbf *tbf = tbf_alloc_ul_tbf(bts, ms, 0, false);
 	static uint8_t res[] = { 0x06,
 				 0x3f, /* Immediate Assignment Message Type */
 				 0x10, /* §10.5.2.26 Page Mode and §10.5.2.25b Dedicated mode/TBF */
@@ -803,6 +807,7 @@
 				 0xc8, 0x02, 0x1b, 0xa2, 0x0b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, };
 
 	check_imm_ass(tbf, false, GSM_L1_BURST_TYPE_ACCESS_0, res, sizeof(res), "ia_rest_uplink(MBA)");
+	talloc_free(bts);
 }
 
 void test_immediate_assign_ul0s()
@@ -824,13 +829,13 @@
 
 void test_immediate_assign_ul1s()
 {
-	BTS the_bts(the_pcu);
+	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
 	the_pcu->alloc_algorithm = alloc_algorithm_a;
-	the_bts.bts_data()->trx[0].pdch[1].enable();
-	the_bts.bts_data()->trx[0].pdch[2].enable();
+	bts->trx[0].pdch[1].enable();
+	bts->trx[0].pdch[2].enable();
 
-	GprsMs *ms = the_bts.ms_alloc(1, 1);
-	struct gprs_rlcmac_tbf *tbf = tbf_alloc_ul_tbf(the_bts.bts_data(), ms, 0, false);
+	GprsMs *ms = bts_alloc_ms(bts, 1, 1);
+	struct gprs_rlcmac_tbf *tbf = tbf_alloc_ul_tbf(bts, ms, 0, false);
 	static uint8_t res[] = { 0x06,
 				 0x3f, /* Immediate Assignment Message Type */
 				 0x10, /* §10.5.2.26 Page Mode and §10.5.2.25b Dedicated mode/TBF */
@@ -844,6 +849,7 @@
 				 0x46, 0xa0, 0x08, 0x00, 0x17, 0x44, 0x0b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, };
 
 	check_imm_ass(tbf, false, GSM_L1_BURST_TYPE_ACCESS_1, res, sizeof(res), "ia_rest_egprs_uplink(SBA)");
+	talloc_free(bts);
 }
 
 void test_immediate_assign_ul1m()