ms: Merge ms_storage into bts.cpp

That class is mostly a C++ class holding a llist plus some callbacks.
Having that in a separate class makes code more complex for no good
reason. This patch moves the llist into bts and allocates stuff directly
from within bts.
This will allow further cleanup of MS lieficyle in future patches.

Change-Id: I627f5db5073189c23ddf2b7f09c90abb24846f62
diff --git a/debian/copyright b/debian/copyright
index bb471cd..aa6d0e2 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -10,9 +10,7 @@
            2015 by Yves Godin <support@nuranwireless.com>
 License:   AGPL-3.0+
 
-Files:     src/gprs_ms_storage.h
-           src/gprs_ms_storage.cpp
-           src/gprs_ms.h
+Files:     src/gprs_ms.h
            src/gprs_coding_scheme.cpp
            src/gprs_coding_scheme.h
            src/coding_scheme.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 9df0caa..6153aa0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -54,7 +54,6 @@
 	gprs_rlcmac_sched.cpp \
 	gprs_rlcmac_meas.cpp \
 	gprs_ms.c \
-	gprs_ms_storage.cpp \
 	gprs_pcu.c \
 	pcu_l1_if.cpp \
 	pcu_vty.c \
@@ -100,7 +99,6 @@
 	gprs_bssgp_rim.h \
 	gprs_rlcmac.h \
 	gprs_ms.h \
-	gprs_ms_storage.h \
 	gprs_pcu.h \
 	pcu_l1_if.h \
 	pcu_l1_if_phy.h \
diff --git a/src/bts.cpp b/src/bts.cpp
index e3a5eeb..84eea08 100644
--- a/src/bts.cpp
+++ b/src/bts.cpp
@@ -30,7 +30,6 @@
 #include <gprs_debug.h>
 #include <cxx_linuxlist.h>
 #include <pdch.h>
-#include <gprs_ms_storage.h>
 #include <sba.h>
 #include <bts_pch_timer.h>
 
@@ -241,10 +240,14 @@
 
 static int bts_talloc_destructor(struct gprs_rlcmac_bts* bts)
 {
-	/* this can cause counter updates and must not be left to the
-	 * m_ms_store's destructor */
-	bts->ms_store->cleanup();
-	delete bts->ms_store;
+	struct GprsMs *ms;
+	while ((ms = llist_first_entry_or_null(&bts->ms_list, struct GprsMs, list))) {
+		ms_set_callback(ms, NULL);
+		ms_set_timeout(ms, 0);
+		llist_del(&ms->list);
+		bts_stat_item_dec(bts, STAT_MS_PRESENT);
+		talloc_free(ms);
+	}
 
 	gprs_bssgp_destroy(bts);
 
@@ -282,8 +285,6 @@
 	bts->pcu = pcu;
 	bts->nr = bts_nr;
 
-	bts->ms_store = new GprsMsStorage(bts);
-
 	bts->cur_fn = FN_UNSET;
 	bts->cur_blk_fn = -1;
 	bts->max_cs_dl = MAX_GPRS_CS;
@@ -332,6 +333,7 @@
 	llist_add_tail(&bts->list, &pcu->bts_list);
 
 	INIT_LLIST_HEAD(&bts->pch_timer);
+	INIT_LLIST_HEAD(&bts->ms_list);
 
 	return bts;
 }
@@ -460,7 +462,7 @@
 	 * Don't mark, if TBF uses a different slot that is already marked. */
 	memset(slot_mask, 0, sizeof(slot_mask));
 
-	llist_for_each(tmp, bts_ms_store(bts)->ms_list()) {
+	llist_for_each(tmp, &bts->ms_list) {
 		ms = llist_entry(tmp, typeof(*ms), list);
 		struct gprs_rlcmac_tbf *tbfs[] = { ms->ul_tbf, ms->dl_tbf };
 		for (l = 0; l < ARRAY_SIZE(tbfs); l++) {
@@ -1197,29 +1199,74 @@
 	}
 }
 
+static void bts_ms_idle_cb(struct GprsMs *ms)
+{
+	llist_del(&ms->list);
+	bts_stat_item_dec(ms->bts, STAT_MS_PRESENT);
+	if (ms_is_idle(ms))
+		talloc_free(ms);
+}
+
+static void bts_ms_active_cb(struct GprsMs *ms)
+{
+	/* Nothing to do */
+}
+
 GprsMs *bts_alloc_ms(struct gprs_rlcmac_bts* bts)
 {
-	GprsMs *ms;
-	ms = bts_ms_store(bts)->create_ms();
+	struct GprsMs *ms;
 
+	static struct gpr_ms_callback bts_ms_cb = {
+		.ms_idle = bts_ms_idle_cb,
+		.ms_active = bts_ms_active_cb,
+	};
+
+	ms = ms_alloc(bts);
+
+	ms_set_callback(ms, &bts_ms_cb);
 	ms_set_timeout(ms, osmo_tdef_get(bts->pcu->T_defs, -2030, OSMO_TDEF_S, -1));
+	llist_add(&ms->list, &bts->ms_list);
 
+	bts_stat_item_inc(bts, STAT_MS_PRESENT);
 	return ms;
 }
 
-struct GprsMsStorage *bts_ms_store(const struct gprs_rlcmac_bts *bts)
+struct GprsMs *bts_get_ms(const struct gprs_rlcmac_bts *bts, uint32_t tlli, uint32_t old_tlli,
+			  const char *imsi)
 {
-	return bts->ms_store;
+	struct llist_head *tmp;
+
+	if (tlli != GSM_RESERVED_TMSI || old_tlli != GSM_RESERVED_TMSI) {
+		llist_for_each(tmp, &bts->ms_list) {
+			struct GprsMs *ms = llist_entry(tmp, typeof(*ms), list);
+			if (ms_check_tlli(ms, tlli))
+				return ms;
+			if (ms_check_tlli(ms, old_tlli))
+				return ms;
+		}
+	}
+
+	/* not found by TLLI */
+
+	if (imsi && imsi[0] != '\0') {
+		llist_for_each(tmp, &bts->ms_list) {
+			struct GprsMs *ms = llist_entry(tmp, typeof(*ms), list);
+			if (ms_imsi_is_valid(ms) && strcmp(imsi, ms_imsi(ms)) == 0)
+				return ms;
+		}
+	}
+
+	return NULL;
 }
 
 struct GprsMs *bts_get_ms_by_tlli(const struct gprs_rlcmac_bts *bts, uint32_t tlli, uint32_t old_tlli)
 {
-	return bts_ms_store(bts)->get_ms(tlli, old_tlli);
+	return bts_get_ms(bts, tlli, old_tlli, NULL);
 }
 
 struct GprsMs *bts_get_ms_by_imsi(const struct gprs_rlcmac_bts *bts, const char *imsi)
 {
-	return bts_ms_store(bts)->get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, imsi);
+	return bts_get_ms(bts, GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, imsi);
 }
 
 /* update TA based on TA provided by PH-DATA-IND */
@@ -1427,11 +1474,6 @@
 	bts_set_max_mcs_ul(bts, mcs_ul);
 }
 
-const struct llist_head* bts_ms_list(struct gprs_rlcmac_bts *bts)
-{
-	return bts_ms_store(bts)->ms_list();
-}
-
 uint8_t bts_get_ms_pwr_alpha(const struct gprs_rlcmac_bts *bts)
 {
 	if (bts->pcu->vty.force_alpha != (uint8_t)-1)
diff --git a/src/bts.h b/src/bts.h
index 7f6be73..5644b44 100644
--- a/src/bts.h
+++ b/src/bts.h
@@ -44,6 +44,10 @@
 #include "tbf.h"
 #include "coding_scheme.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 struct GprsMs;
 struct gprs_rlcmac_bts;
 
@@ -64,9 +68,6 @@
 };
 
 
-#ifdef __cplusplus
-extern "C" {
-#endif
 void bts_trx_init(struct gprs_rlcmac_trx *trx, struct gprs_rlcmac_bts *bts, uint8_t trx_no);
 void bts_trx_reserve_slots(struct gprs_rlcmac_trx *trx, enum gprs_rlcmac_tbf_direction dir, uint8_t slots);
 void bts_trx_unreserve_slots(struct gprs_rlcmac_trx *trx, enum gprs_rlcmac_tbf_direction dir, uint8_t slots);
@@ -74,11 +75,6 @@
 
 void bts_update_tbf_ta(struct gprs_rlcmac_bts *bts, const char *p, uint32_t fn,
 		       uint8_t trx_no, uint8_t ts, int8_t ta, bool is_rach);
-#ifdef __cplusplus
-}
-#endif
-
-
 
 enum {
 	CTR_PDCH_ALL_ALLOCATED,
@@ -272,7 +268,7 @@
 	struct rate_ctr_group *ratectrs;
 	struct osmo_stat_item_group *statg;
 
-	struct GprsMsStorage *ms_store;
+	struct llist_head ms_list; /* list of struct GprsMs */
 
 	/* List of struct bts_pch_timer for active PCH pagings */
 	struct llist_head pch_timer;
@@ -280,10 +276,6 @@
 	struct osmo_time_cc all_allocated_pdch;
 };
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 struct paging_req_cs {
 	uint8_t chan_needed;
 	uint32_t tlli; /* GSM_RESERVED_TMSI if not present */
@@ -329,8 +321,8 @@
 			  enum pcu_gsmtap_category categ, uint8_t channel,
 			  const struct rach_ind_params *rip);
 
-struct GprsMsStorage *bts_ms_store(const struct gprs_rlcmac_bts *bts);
-
+struct GprsMs *bts_get_ms(const struct gprs_rlcmac_bts *bts, uint32_t tlli, uint32_t old_tlli,
+			  const char *imsi);
 struct GprsMs *bts_get_ms_by_tlli(const struct gprs_rlcmac_bts *bts, uint32_t tlli, uint32_t old_tlli);
 struct GprsMs *bts_get_ms_by_imsi(const struct gprs_rlcmac_bts *bts, const char *imsi);
 
@@ -379,7 +371,6 @@
 void bts_set_max_mcs_dl(struct gprs_rlcmac_bts *bts, uint8_t mcs_dl);
 void bts_set_max_mcs_ul(struct gprs_rlcmac_bts *bts, uint8_t mcs_ul);
 bool bts_cs_dl_is_supported(const struct gprs_rlcmac_bts *bts, enum CodingScheme cs);
-const struct llist_head* bts_ms_list(struct gprs_rlcmac_bts *bts);
 uint8_t bts_get_ms_pwr_alpha(const struct gprs_rlcmac_bts *bts);
 bool bts_all_pdch_allocated(const struct gprs_rlcmac_bts *bts);
 #ifdef __cplusplus
diff --git a/src/gprs_bssgp_rim.c b/src/gprs_bssgp_rim.c
index 033426b..aa636b6 100644
--- a/src/gprs_bssgp_rim.c
+++ b/src/gprs_bssgp_rim.c
@@ -152,7 +152,7 @@
 	}
 	entry = si_cache_add(bts->pcu->si_cache, &nacc->reprt_cell, &val);
 
-	llist_for_each(tmp, bts_ms_list(bts)) {
+	llist_for_each(tmp, &bts->ms_list) {
 		struct GprsMs *ms = llist_entry(tmp, typeof(*ms), list);
 		if (ms->nacc && nacc_fsm_is_waiting_si_resolution(ms->nacc, &nacc->reprt_cell))
 			osmo_fsm_inst_dispatch(ms->nacc->fi, NACC_EV_RX_SI, entry);
diff --git a/src/gprs_ms.c b/src/gprs_ms.c
index 909e7f8..7ee697e 100644
--- a/src/gprs_ms.c
+++ b/src/gprs_ms.c
@@ -24,7 +24,6 @@
 #include "pcu_utils.h"
 #include "nacc_fsm.h"
 #include "tbf_ul_ack_fsm.h"
-#include "gprs_ms_storage.h"
 
 #include <time.h>
 
@@ -430,7 +429,7 @@
 	 * MS object that belongs to that TLLI and if yes make sure one of them
 	 * gets deleted. */
 	if (!ms_check_tlli(ms, tlli))
-		old_ms = ms_store_get_ms(bts_ms_store(ms->bts), tlli, GSM_RESERVED_TMSI, NULL);
+		old_ms = bts_get_ms_by_tlli(ms->bts, tlli, GSM_RESERVED_TMSI);
 
 	ms_set_tlli(ms, tlli);
 
diff --git a/src/gprs_ms_storage.cpp b/src/gprs_ms_storage.cpp
deleted file mode 100644
index 4741a2d..0000000
--- a/src/gprs_ms_storage.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/* gprs_ms_storage.cpp
- *
- * Copyright (C) 2015 by Sysmocom s.f.m.c. GmbH
- * Author: Jacob Erlbeck <jerlbeck@sysmocom.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-
-#include "gprs_ms_storage.h"
-
-#include "tbf.h"
-#include "bts.h"
-
-extern "C" {
-	#include <osmocom/core/linuxlist.h>
-	#include <osmocom/gsm/gsm48.h>
-}
-
-static void ms_storage_ms_idle_cb(struct GprsMs *ms)
-{
-	llist_del(&ms->list);
-	bts_stat_item_dec(ms->bts, STAT_MS_PRESENT);
-	if (ms_is_idle(ms))
-		talloc_free(ms);
-}
-
-static void ms_storage_ms_active_cb(struct GprsMs *ms)
-{
-	/* Nothing to do */
-}
-
-static struct gpr_ms_callback ms_storage_ms_cb = {
-	.ms_idle = ms_storage_ms_idle_cb,
-	.ms_active = ms_storage_ms_active_cb,
-};
-
-GprsMsStorage::GprsMsStorage(struct gprs_rlcmac_bts *bts) :
-	m_bts(bts)
-{
-	INIT_LLIST_HEAD(&m_list);
-}
-
-GprsMsStorage::~GprsMsStorage()
-{
-	cleanup();
-}
-
-void GprsMsStorage::cleanup()
-{
-	struct llist_head *pos, *tmp;
-
-	llist_for_each_safe(pos, tmp, &m_list) {
-		struct GprsMs *ms = llist_entry(pos, typeof(*ms), list);
-		ms_set_callback(ms, NULL);
-		ms_set_timeout(ms, 0);
-		llist_del(&ms->list);
-		bts_stat_item_dec(ms->bts, STAT_MS_PRESENT);
-		talloc_free(ms);
-	}
-}
-
-GprsMs *GprsMsStorage::get_ms(uint32_t tlli, uint32_t old_tlli, const char *imsi) const
-{
-	struct llist_head *tmp;
-	GprsMs *ms;
-
-	if (tlli != GSM_RESERVED_TMSI || old_tlli != GSM_RESERVED_TMSI) {
-		llist_for_each(tmp, &m_list) {
-			ms = llist_entry(tmp, typeof(*ms), list);
-			if (ms_check_tlli(ms, tlli))
-				return ms;
-			if (ms_check_tlli(ms, old_tlli))
-				return ms;
-		}
-	}
-
-	/* not found by TLLI */
-
-	if (imsi && imsi[0] != '\0') {
-		llist_for_each(tmp, &m_list) {
-			ms = llist_entry(tmp, typeof(*ms), list);
-			if (ms_imsi_is_valid(ms) && strcmp(imsi, ms_imsi(ms)) == 0)
-				return ms;
-		}
-	}
-
-	return NULL;
-}
-
-GprsMs *GprsMsStorage::create_ms()
-{
-	GprsMs *ms;
-
-	ms = ms_alloc(m_bts);
-
-	ms_set_callback(ms, &ms_storage_ms_cb);
-	llist_add(&ms->list, &m_list);
-	if (m_bts)
-		bts_stat_item_inc(m_bts, STAT_MS_PRESENT);
-
-	return ms;
-}
-
-struct GprsMs *ms_store_get_ms(struct GprsMsStorage *ms_store, uint32_t tlli, uint32_t old_tlli, const char *imsi)
-{
-	return ms_store->get_ms(tlli, old_tlli, imsi);
-}
diff --git a/src/gprs_ms_storage.h b/src/gprs_ms_storage.h
deleted file mode 100644
index 45238cf..0000000
--- a/src/gprs_ms_storage.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* gprs_ms_storage.h
- *
- * Copyright (C) 2015 by Sysmocom s.f.m.c. GmbH
- * Author: Jacob Erlbeck <jerlbeck@sysmocom.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#pragma once
-
-#include "gprs_ms.h"
-#include "tbf.h"
-#include <stdint.h>
-#include <stddef.h>
-
-struct gprs_rlcmac_bts;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-struct GprsMsStorage;
-struct GprsMs *ms_store_get_ms(struct GprsMsStorage *ms_store, uint32_t tlli, uint32_t old_tlli, const char *imsi);
-#ifdef __cplusplus
-}
-#endif
-
-#ifdef __cplusplus
-
-struct GprsMsStorage {
-public:
-	GprsMsStorage(struct gprs_rlcmac_bts *bts);
-	~GprsMsStorage();
-
-	void cleanup();
-
-	GprsMs *get_ms(uint32_t tlli, uint32_t old_tlli = GSM_RESERVED_TMSI, const char *imsi = NULL) const;
-	GprsMs *create_ms();
-
-	const struct llist_head* ms_list() const {return &m_list;}
-private:
-	struct gprs_rlcmac_bts *m_bts;
-	struct llist_head m_list; /* list of struct GprsMs */
-};
-
-#endif
diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp
index 7068083..4aae9c4 100644
--- a/src/pcu_l1_if.cpp
+++ b/src/pcu_l1_if.cpp
@@ -55,7 +55,7 @@
 #include <pdch.h>
 #include <tbf_ul.h>
 #include <tbf_dl.h>
-#include <gprs_ms_storage.h>
+#include <gprs_ms.h>
 
 extern void *tall_pcu_ctx;
 
@@ -1094,7 +1094,7 @@
 	LOGP(DL1IF, LOGL_INFO, "GPRS Suspend request received: TLLI=0x%08x RAI=%s\n",
 		susp_req->tlli, osmo_rai_name(&ra_id));
 
-	if ((ms = bts_ms_store(bts)->get_ms(susp_req->tlli))) {
+	if ((ms = bts_get_ms_by_tlli(bts, susp_req->tlli, GSM_RESERVED_TMSI))) {
 		/* We need to catch both pointers here since MS may become freed
 		   after first tbf_free(dl_tbf) if only DL TBF was available */
 		dl_tbf = ms_dl_tbf(ms);
@@ -1119,8 +1119,8 @@
 	     app_info_req->application_type, app_info_req->len);
 
 	bts->app_info_pending = 0;
-	llist_for_each(tmp, bts_ms_store(bts)->ms_list()) {
-		GprsMs *ms = llist_entry(tmp, typeof(*ms), list);
+	llist_for_each(tmp, &bts->ms_list) {
+		struct GprsMs *ms = llist_entry(tmp, typeof(*ms), list);
 		if (!ms_dl_tbf(ms))
 			continue;
 		bts->app_info_pending++;
@@ -1177,8 +1177,8 @@
 		     NEIGH_CACHE_ENTRY_KEY_ARGS(&neigh_key), naddr_cnf->err_code);
 	}
 
-	llist_for_each(tmp, bts_ms_store(bts)->ms_list()) {
-		GprsMs *ms = llist_entry(tmp, typeof(*ms), list);
+	llist_for_each(tmp, &bts->ms_list) {
+		struct GprsMs *ms = llist_entry(tmp, typeof(*ms), list);
 		if (ms->nacc && nacc_fsm_is_waiting_addr_resolution(ms->nacc, &neigh_key))
 			osmo_fsm_inst_dispatch(ms->nacc->fi, NACC_EV_RX_RAC_CI, cgi_ps_ptr);
 	}
diff --git a/src/pcu_vty_functions.cpp b/src/pcu_vty_functions.cpp
index 5cdfda3..fe51203 100644
--- a/src/pcu_vty_functions.cpp
+++ b/src/pcu_vty_functions.cpp
@@ -20,7 +20,6 @@
 #include <stdlib.h>
 #include "pcu_vty_functions.h"
 #include "bts.h"
-#include "gprs_ms_storage.h"
 #include "gprs_ms.h"
 #include "cxx_linuxlist.h"
 #include <llc.h>
@@ -229,8 +228,8 @@
 {
 	struct llist_head *tmp;
 
-	llist_for_each(tmp, bts_ms_store(bts)->ms_list()) {
-		GprsMs *ms_iter = llist_entry(tmp, typeof(*ms_iter), list);
+	llist_for_each(tmp, &bts->ms_list) {
+		struct GprsMs *ms_iter = llist_entry(tmp, typeof(*ms_iter), list);
 		show_ms(vty, ms_iter);
 	}
 
@@ -240,7 +239,7 @@
 int pcu_vty_show_ms_by_tlli(struct vty *vty, struct gprs_rlcmac_bts *bts,
 	uint32_t tlli)
 {
-	GprsMs *ms = bts_ms_store(bts)->get_ms(tlli);
+	struct GprsMs *ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
 	if (!ms) {
 		vty_out(vty, "Unknown TLLI %08x.%s", tlli, VTY_NEWLINE);
 		return CMD_WARNING;
@@ -252,7 +251,7 @@
 int pcu_vty_show_ms_by_imsi(struct vty *vty, struct gprs_rlcmac_bts *bts,
 	const char *imsi)
 {
-	GprsMs *ms = bts_ms_store(bts)->get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, imsi);
+	struct GprsMs *ms = bts_get_ms_by_imsi(bts, imsi);
 	if (!ms) {
 		vty_out(vty, "Unknown IMSI '%s'.%s", imsi, VTY_NEWLINE);
 		return CMD_WARNING;
diff --git a/src/pdch.cpp b/src/pdch.cpp
index 081c306..43b3936 100644
--- a/src/pdch.cpp
+++ b/src/pdch.cpp
@@ -27,7 +27,6 @@
 #include <gprs_debug.h>
 #include <coding_scheme.h>
 #include <gprs_ms.h>
-#include <gprs_ms_storage.h>
 #include <pcu_l1_if.h>
 #include <rlc.h>
 #include <sba.h>
@@ -139,7 +138,7 @@
 	uint8_t ts_rm_mask = (~(1 << pdch->ts_no));
 	struct gprs_rlcmac_trx *trx = pdch->trx;
 
-	llist_for_each(tmp, bts_ms_list(trx->bts)) {
+	llist_for_each(tmp, &trx->bts->ms_list) {
 		struct GprsMs *ms = llist_entry(tmp, typeof(*ms), list);
 		if (ms->current_trx != trx)
 			continue;
diff --git a/src/tbf.cpp b/src/tbf.cpp
index 9648c71..e972bd0 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -28,7 +28,6 @@
 #include <gprs_debug.h>
 #include <gprs_ms.h>
 #include <pcu_utils.h>
-#include <gprs_ms_storage.h>
 #include <sba.h>
 #include <pdch.h>
 
diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp
index 8980d8e..cca059a 100644
--- a/src/tbf_dl.cpp
+++ b/src/tbf_dl.cpp
@@ -27,7 +27,6 @@
 #include <decoding.h>
 #include <encoding.h>
 #include <gprs_ms.h>
-#include <gprs_ms_storage.h>
 #include <llc.h>
 #include "pcu_utils.h"
 
@@ -199,12 +198,12 @@
 	GprsMs *ms, *ms_old;
 
 	/* check for existing TBF */
-	ms = bts_ms_store(bts)->get_ms(tlli, tlli_old, imsi);
+	ms = bts_get_ms(bts, tlli, tlli_old, imsi);
 
 	/* If we got MS by TLLI above let's see if we already have another MS
 	 * object identified by IMSI and merge them */
 	if (ms && !ms_imsi_is_valid(ms) && imsi) {
-		ms_old = bts_ms_store(bts)->get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, imsi);
+		ms_old = bts_get_ms_by_imsi(bts, imsi);
 		if (ms_old && ms_old != ms) {
 			/* The TLLI has changed (RAU), so there are two MS
 			 * objects for the same MS */
diff --git a/tests/ms/MsTest.cpp b/tests/ms/MsTest.cpp
index ec1672a..45051d4 100644
--- a/tests/ms/MsTest.cpp
+++ b/tests/ms/MsTest.cpp
@@ -24,7 +24,6 @@
 #include "tbf_ul.h"
 #include "gprs_debug.h"
 #include "gprs_ms.h"
-#include "gprs_ms_storage.h"
 #include "bts.h"
 
 extern "C" {
@@ -375,13 +374,13 @@
 	printf("=== end %s ===\n", __func__);
 }
 
-static GprsMs *prepare_ms(GprsMsStorage *st, uint32_t tlli, enum gprs_rlcmac_tbf_direction dir)
+static GprsMs *prepare_ms(struct gprs_rlcmac_bts *bts, uint32_t tlli, enum gprs_rlcmac_tbf_direction dir)
 {
-	GprsMs *ms = st->get_ms(tlli);
+	GprsMs *ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
 	if (ms)
 		return ms;
 
-	ms = st->create_ms();
+	ms = bts_alloc_ms(bts);
 
 	if (dir == GPRS_RLCMAC_UL_TBF)
 		ms_set_tlli(ms, tlli);
@@ -400,63 +399,62 @@
 	gprs_rlcmac_ul_tbf *ul_tbf;
 	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
 	GprsMs *ms, *ms_tmp;
-	GprsMsStorage store(bts);
 
 	printf("=== start %s ===\n", __func__);
 
-	ms = store.get_ms(tlli + 0);
+	ms = bts_get_ms_by_tlli(bts, tlli + 0, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms == NULL);
 
-	ms = prepare_ms(&store, tlli + 0, GPRS_RLCMAC_UL_TBF);
+	ms = prepare_ms(bts, tlli + 0, GPRS_RLCMAC_UL_TBF);
 	OSMO_ASSERT(ms != NULL);
 	OSMO_ASSERT(ms_tlli(ms) == tlli + 0);
 	ms_set_imsi(ms, imsi1);
 	OSMO_ASSERT(strcmp(ms_imsi(ms), imsi1) == 0);
 
-	ms_tmp = store.get_ms(tlli + 0);
+	ms_tmp = bts_get_ms_by_tlli(bts, tlli + 0, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms == ms_tmp);
 	OSMO_ASSERT(ms_tlli(ms) == tlli + 0);
 
-	ms_tmp = store.get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, imsi1);
+	ms_tmp = bts_get_ms_by_imsi(bts, imsi1);
 	OSMO_ASSERT(ms == ms_tmp);
 	OSMO_ASSERT(strcmp(ms_imsi(ms), imsi1) == 0);
-	ms_tmp = store.get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, imsi2);
+	ms_tmp = bts_get_ms_by_imsi(bts, imsi2);
 	OSMO_ASSERT(ms_tmp == NULL);
 
-	ms = prepare_ms(&store, tlli + 1, GPRS_RLCMAC_UL_TBF);
+	ms = prepare_ms(bts, tlli + 1, GPRS_RLCMAC_UL_TBF);
 	OSMO_ASSERT(ms != NULL);
 	OSMO_ASSERT(ms_tlli(ms) == tlli + 1);
 	ms_set_imsi(ms, imsi2);
 	OSMO_ASSERT(strcmp(ms_imsi(ms), imsi2) == 0);
 
-	ms_tmp = store.get_ms(tlli + 1);
+	ms_tmp = bts_get_ms_by_tlli(bts, tlli + 1, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms == ms_tmp);
 	OSMO_ASSERT(ms_tlli(ms) == tlli + 1);
 
-	ms_tmp = store.get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, imsi1);
+	ms_tmp = bts_get_ms_by_imsi(bts, imsi1);
 	OSMO_ASSERT(ms_tmp != NULL);
 	OSMO_ASSERT(ms_tmp != ms);
-	ms_tmp = store.get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, imsi2);
+	ms_tmp = bts_get_ms_by_imsi(bts, imsi2);
 	OSMO_ASSERT(ms == ms_tmp);
 	OSMO_ASSERT(strcmp(ms_imsi(ms), imsi2) == 0);
 
 	/* delete ms */
-	ms = store.get_ms(tlli + 0);
+	ms = bts_get_ms_by_tlli(bts, tlli + 0, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms != NULL);
 	ul_tbf = alloc_ul_tbf(bts, ms);
 	ms_attach_tbf(ms, ul_tbf);
 	ms_detach_tbf(ms, ul_tbf);
-	ms = store.get_ms(tlli + 0);
+	ms = bts_get_ms_by_tlli(bts, tlli + 0, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms == NULL);
-	ms = store.get_ms(tlli + 1);
+	ms = bts_get_ms_by_tlli(bts, tlli + 1, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms != NULL);
 
 	/* delete ms */
-	ms = store.get_ms(tlli + 1);
+	ms = bts_get_ms_by_tlli(bts, tlli + 1, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms != NULL);
 	ms_attach_tbf(ms, ul_tbf);
 	ms_detach_tbf(ms, ul_tbf);
-	ms = store.get_ms(tlli + 1);
+	ms = bts_get_ms_by_tlli(bts, tlli + 1, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms == NULL);
 
 	talloc_free(ul_tbf);
@@ -646,6 +644,8 @@
 	vty_init(&pcu_vty_info);
 	pcu_vty_init();
 
+	osmo_tdef_set(the_pcu->T_defs, -2030, 0, OSMO_TDEF_S);
+
 	test_ms_state();
 	test_ms_callback();
 	test_ms_replace_tbf();
diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp
index 42b6d29..d493e6c 100644
--- a/tests/tbf/TbfTest.cpp
+++ b/tests/tbf/TbfTest.cpp
@@ -26,7 +26,6 @@
 #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"
@@ -452,18 +451,18 @@
 	ms_confirm_tlli(dl_tbf[1]->ms(), 0xf1000002);
 
 	ms_set_imsi(dl_tbf[0]->ms(), "001001000000001");
-	ms1 = bts_ms_store(bts)->get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000001");
+	ms1 = bts_get_ms(bts, GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000001");
 	OSMO_ASSERT(ms1 != NULL);
-	ms2 = bts_ms_store(bts)->get_ms(0xf1000001);
+	ms2 = bts_get_ms_by_tlli(bts, 0xf1000001, GSM_RESERVED_TMSI);
 	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 = bts_ms_store(bts)->get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000001");
+	ms1 = bts_get_ms(bts, GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000001");
 	OSMO_ASSERT(ms1 == NULL);
-	ms1 = bts_ms_store(bts)->get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000002");
+	ms1 = bts_get_ms(bts, GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000002");
 	OSMO_ASSERT(ms1 != NULL);
 	OSMO_ASSERT(strcmp(ms_imsi(ms2), "001001000000002") == 0);
 	OSMO_ASSERT(ms1 == ms2);
@@ -472,7 +471,7 @@
 	{
 		ms_ref(ms2);
 		ms_set_imsi(dl_tbf[1]->ms(), "001001000000002");
-		ms1 = bts_ms_store(bts)->get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000002");
+		ms1 = bts_get_ms(bts, GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000002");
 		OSMO_ASSERT(ms1 != NULL);
 		OSMO_ASSERT(ms1 != ms2);
 		OSMO_ASSERT(strcmp(ms_imsi(ms1), "001001000000002") == 0);
@@ -480,11 +479,11 @@
 		ms_unref(ms2);
 	}
 
-	ms2 = bts_ms_store(bts)->get_ms(0xf1000001);
+	ms2 = bts_get_ms_by_tlli(bts, 0xf1000001, GSM_RESERVED_TMSI);
 	OSMO_ASSERT(ms2 == NULL);
 
 	tbf_free(dl_tbf[1]);
-	ms1 = bts_ms_store(bts)->get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000002");
+	ms1 = bts_get_ms(bts, GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000002");
 	OSMO_ASSERT(ms1 == NULL);
 
 	TALLOC_FREE(the_pcu);
@@ -569,7 +568,7 @@
 		delay_csec, buf, sizeof(buf));
 	OSMO_ASSERT(rc >= 0);
 
-	ms = bts_ms_store(bts)->get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, imsi);
+	ms = bts_get_ms(bts, GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, imsi);
 	OSMO_ASSERT(ms != NULL);
 	OSMO_ASSERT(ms_dl_tbf(ms) != NULL);
 	ms_dl_tbf(ms)->set_ta(0);
@@ -1683,7 +1682,7 @@
 {
 	GprsMs *ms, *ms2;
 
-	ms = bts_ms_store(bts)->get_ms(tlli, GSM_RESERVED_TMSI, imsi);
+	ms = bts_get_ms(bts, tlli, GSM_RESERVED_TMSI, imsi);
 
 	dl_tbf_handle(bts, tlli, 0, imsi, 0, 0,
 		1000, data, data_size);
@@ -2464,7 +2463,7 @@
 			   delay_csec, llc_buf, sizeof(llc_buf));
 	OSMO_ASSERT(rc >= 0);
 
-	first_ms = bts_ms_store(bts)->get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, imsi);
+	first_ms = bts_get_ms(bts, GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, imsi);
 	OSMO_ASSERT(first_ms);
 	dl_tbf = ms_dl_tbf(first_ms);
 	OSMO_ASSERT(dl_tbf);