<p>pespin <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-pcu/+/22196">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  osmith: Looks good to me, approved
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Unify BTS into a C usable structure<br><br>Previous work on BTS class started to get stuff out of the C++ struct<br> into a C struct (BTS -> struct gprs_glcmac_bts) so that some parts of<br>it were accessible from C code. Doing so, however, ended up being messy<br>too, since all code needs to be switching from one object to another,<br>which actually refer to the same logical component.<br><br>Let's instead rejoin the structures and make sure the struct is<br>accessible and usable from both C and C++ code by rewriting all methods<br>to be C compatible and converting 3 allocated suboject as pointers.<br>This way BTS can internally still use those C++ objects while providing<br>a clean APi to both C and C++ code.<br><br>Change-Id: I7d12c896c5ded659ca9d3bff4cf3a3fc857db9dd<br>---<br>M src/bts.cpp<br>M src/bts.h<br>M src/encoding.cpp<br>M src/gprs_bssgp_pcu.cpp<br>M src/gprs_ms.c<br>M src/gprs_ms.h<br>M src/gprs_ms_storage.cpp<br>M src/gprs_ms_storage.h<br>M src/gprs_pcu.c<br>M src/gprs_pcu.h<br>M src/gprs_rlcmac_sched.cpp<br>M src/gprs_rlcmac_ts_alloc.cpp<br>M src/gsm_timer.cpp<br>M src/llc.cpp<br>M src/llc.h<br>M src/pcu_l1_if.cpp<br>M src/pcu_main.cpp<br>M src/pcu_vty_functions.cpp<br>M src/pdch.cpp<br>M src/pdch.h<br>M src/poll_controller.cpp<br>M src/poll_controller.h<br>M src/rlc.cpp<br>M src/rlc.h<br>M src/sba.cpp<br>M src/sba.h<br>M src/tbf.cpp<br>M src/tbf.h<br>M src/tbf_dl.cpp<br>M src/tbf_dl.h<br>M src/tbf_ul.cpp<br>M src/tbf_ul.h<br>M tests/alloc/AllocTest.cpp<br>M tests/alloc/MslotTest.cpp<br>M tests/app_info/AppInfoTest.cpp<br>M tests/edge/EdgeTest.cpp<br>M tests/emu/pcu_emu.cpp<br>M tests/fn/FnTest.cpp<br>M tests/ms/MsTest.cpp<br>M tests/tbf/TbfTest.cpp<br>M tests/types/TypesTest.cpp<br>41 files changed, 1,048 insertions(+), 1,194 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/bts.cpp b/src/bts.cpp</span><br><span>index a50e8ae..294739c 100644</span><br><span>--- a/src/bts.cpp</span><br><span>+++ b/src/bts.cpp</span><br><span>@@ -31,6 +31,8 @@</span><br><span> #include <gprs_debug.h></span><br><span> #include <cxx_linuxlist.h></span><br><span> #include <pdch.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <gprs_ms_storage.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <sba.h></span><br><span> </span><br><span> extern "C" {</span><br><span>        #include <osmocom/core/talloc.h></span><br><span>@@ -190,9 +192,20 @@</span><br><span>        bts_stat_item_description,</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void bts_init(struct gprs_rlcmac_bts *bts, BTS* bts_obj)</span><br><span style="color: hsl(120, 100%, 40%);">+static void bts_init(struct gprs_rlcmac_bts *bts, struct gprs_pcu *pcu)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-       memset(bts, 0, sizeof(*bts));</span><br><span style="color: hsl(120, 100%, 40%);">+ bts->pcu = pcu;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  bts->pollController = new PollController(*bts);</span><br><span style="color: hsl(120, 100%, 40%);">+    bts->sba = new SBAController(*bts);</span><br><span style="color: hsl(120, 100%, 40%);">+        bts->ms_store = new GprsMsStorage(bts);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  bts->cur_fn = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   bts->cur_blk_fn = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+      bts->max_cs_dl = MAX_GPRS_CS;</span><br><span style="color: hsl(120, 100%, 40%);">+      bts->max_cs_ul = MAX_GPRS_CS;</span><br><span style="color: hsl(120, 100%, 40%);">+      bts->max_mcs_dl = MAX_EDGE_MCS;</span><br><span style="color: hsl(120, 100%, 40%);">+    bts->max_mcs_ul = MAX_EDGE_MCS;</span><br><span>   bts->initial_cs_dl = bts->initial_cs_ul = 1;</span><br><span>   bts->initial_mcs_dl = bts->initial_mcs_ul = 1;</span><br><span>         bts->cs_mask = 1 << 0;  /* CS-1 always enabled by default */</span><br><span>@@ -202,15 +215,17 @@</span><br><span>        bts->si13_is_set = false;</span><br><span> </span><br><span>     bts->app_info = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-        bts->bts = bts_obj;</span><br><span>       bts->T_defs_bts = T_defs_bts;</span><br><span>     osmo_tdefs_reset(bts->T_defs_bts);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+     INIT_LLIST_HEAD(&bts->ul_tbfs);</span><br><span style="color: hsl(120, 100%, 40%);">+        INIT_LLIST_HEAD(&bts->dl_tbfs);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>     /* initialize back pointers */</span><br><span>       for (size_t trx_no = 0; trx_no < ARRAY_SIZE(bts->trx); ++trx_no) {</span><br><span>             struct gprs_rlcmac_trx *trx = &bts->trx[trx_no];</span><br><span>              trx->trx_no = trx_no;</span><br><span style="color: hsl(0, 100%, 40%);">-                trx->bts = bts_obj;</span><br><span style="color: hsl(120, 100%, 40%);">+                trx->bts = bts;</span><br><span> </span><br><span>               for (size_t ts_no = 0; ts_no < ARRAY_SIZE(trx->pdch); ++ts_no) {</span><br><span>                       struct gprs_rlcmac_pdch *pdch = &trx->pdch[ts_no];</span><br><span>@@ -219,89 +234,57 @@</span><br><span>                    pdch->trx = trx;</span><br><span>          }</span><br><span>    }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-BTS* BTS::main_bts()</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- return the_pcu->bts;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct gprs_rlcmac_bts *BTS::bts_data()</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        return &m_bts;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct gprs_rlcmac_bts *bts_main_data()</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     return BTS::main_bts()->bts_data();</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void bts_cleanup()</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      return BTS::main_bts()->cleanup();</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct rate_ctr_group *bts_main_data_stats()</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     return BTS::main_bts()->rate_counters();</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-BTS::BTS(struct gprs_pcu *pcu)</span><br><span style="color: hsl(0, 100%, 40%);">-      : pcu(pcu)</span><br><span style="color: hsl(0, 100%, 40%);">-      , m_cur_fn(0)</span><br><span style="color: hsl(0, 100%, 40%);">-   , m_cur_blk_fn(-1)</span><br><span style="color: hsl(0, 100%, 40%);">-      , m_max_cs_dl(MAX_GPRS_CS)</span><br><span style="color: hsl(0, 100%, 40%);">-      , m_max_cs_ul(MAX_GPRS_CS)</span><br><span style="color: hsl(0, 100%, 40%);">-      , m_max_mcs_dl(MAX_EDGE_MCS)</span><br><span style="color: hsl(0, 100%, 40%);">-    , m_max_mcs_ul(MAX_EDGE_MCS)</span><br><span style="color: hsl(0, 100%, 40%);">-    , m_pollController(*this)</span><br><span style="color: hsl(0, 100%, 40%);">-       , m_sba(*this)</span><br><span style="color: hsl(0, 100%, 40%);">-  , m_ms_store(this)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     bts_init(&m_bts, this);</span><br><span> </span><br><span>      /* The static allocator might have already registered the counter group.</span><br><span>        If this happens and we still called explicitly (in tests/ for example)</span><br><span>       than just allocate the group with different index.</span><br><span>           This shall be removed once weget rid of BTS singleton */</span><br><span>  if (rate_ctr_get_group_by_name_idx(bts_ctrg_desc.group_name_prefix, 0))</span><br><span style="color: hsl(0, 100%, 40%);">-         m_ratectrs = rate_ctr_group_alloc(tall_pcu_ctx, &bts_ctrg_desc, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+               bts->ratectrs = rate_ctr_group_alloc(tall_pcu_ctx, &bts_ctrg_desc, 1);</span><br><span>        else</span><br><span style="color: hsl(0, 100%, 40%);">-            m_ratectrs = rate_ctr_group_alloc(tall_pcu_ctx, &bts_ctrg_desc, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_ASSERT(m_ratectrs);</span><br><span style="color: hsl(120, 100%, 40%);">+              bts->ratectrs = rate_ctr_group_alloc(tall_pcu_ctx, &bts_ctrg_desc, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(bts->ratectrs);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      m_statg = osmo_stat_item_group_alloc(tall_pcu_ctx, &bts_statg_desc, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-     OSMO_ASSERT(m_statg);</span><br><span style="color: hsl(120, 100%, 40%);">+ bts->statg = osmo_stat_item_group_alloc(tall_pcu_ctx, &bts_statg_desc, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_ASSERT(bts->statg);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void BTS::cleanup()</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlcmac_bts *bts_main_data()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   return the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct rate_ctr_group *bts_main_data_stats()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return bts_rate_counters(the_pcu->bts);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void bts_cleanup(gprs_rlcmac_bts *bts)</span><br><span> {</span><br><span>  /* this can cause counter updates and must not be left to the</span><br><span>         * m_ms_store's destructor */</span><br><span style="color: hsl(0, 100%, 40%);">-       m_ms_store.cleanup();</span><br><span style="color: hsl(120, 100%, 40%);">+ bts->ms_store->cleanup();</span><br><span style="color: hsl(120, 100%, 40%);">+       delete bts->ms_store;</span><br><span style="color: hsl(120, 100%, 40%);">+      delete bts->sba;</span><br><span style="color: hsl(120, 100%, 40%);">+   delete bts->pollController;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      if (m_ratectrs) {</span><br><span style="color: hsl(0, 100%, 40%);">-               rate_ctr_group_free(m_ratectrs);</span><br><span style="color: hsl(0, 100%, 40%);">-                m_ratectrs = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (bts->ratectrs) {</span><br><span style="color: hsl(120, 100%, 40%);">+               rate_ctr_group_free(bts->ratectrs);</span><br><span style="color: hsl(120, 100%, 40%);">+                bts->ratectrs = NULL;</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   if (m_statg) {</span><br><span style="color: hsl(0, 100%, 40%);">-          osmo_stat_item_group_free(m_statg);</span><br><span style="color: hsl(0, 100%, 40%);">-             m_statg = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (bts->statg) {</span><br><span style="color: hsl(120, 100%, 40%);">+          osmo_stat_item_group_free(bts->statg);</span><br><span style="color: hsl(120, 100%, 40%);">+             bts->statg = NULL;</span><br><span>        }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   if (m_bts.app_info) {</span><br><span style="color: hsl(0, 100%, 40%);">-           msgb_free(m_bts.app_info);</span><br><span style="color: hsl(0, 100%, 40%);">-              m_bts.app_info = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+        if (bts->app_info) {</span><br><span style="color: hsl(120, 100%, 40%);">+               msgb_free(bts->app_info);</span><br><span style="color: hsl(120, 100%, 40%);">+          bts->app_info = NULL;</span><br><span>     }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-BTS::~BTS()</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  cleanup();</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void BTS::set_current_frame_number(int fn)</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_set_current_frame_number(struct gprs_rlcmac_bts *bts, int fn)</span><br><span> {</span><br><span>   /* The UL frame numbers lag 3 behind the DL frames and the data</span><br><span>       * indication is only sent after all 4 frames of the block have been</span><br><span>@@ -314,8 +297,8 @@</span><br><span>    * Values up to 50 frames have been observed under load. */</span><br><span>  const static int max_delay = 60;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    m_cur_fn = fn;</span><br><span style="color: hsl(0, 100%, 40%);">-  m_pollController.expireTimedout(m_cur_fn, max_delay);</span><br><span style="color: hsl(120, 100%, 40%);">+ bts->cur_fn = fn;</span><br><span style="color: hsl(120, 100%, 40%);">+  bts->pollController->expireTimedout(bts->cur_fn, max_delay);</span><br><span> }</span><br><span> </span><br><span> static inline int delta_fn(int fn, int to)</span><br><span>@@ -323,7 +306,7 @@</span><br><span>   return (fn + GSM_MAX_FN * 3 / 2 - to) % GSM_MAX_FN - GSM_MAX_FN/2;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void BTS::set_current_block_frame_number(int fn, unsigned max_delay)</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_set_current_block_frame_number(struct gprs_rlcmac_bts *bts, int fn, unsigned max_delay)</span><br><span> {</span><br><span>       int delay = 0;</span><br><span>       const int late_block_delay_thresh = 13;</span><br><span>@@ -332,41 +315,41 @@</span><br><span> </span><br><span>  /* frame numbers in the received blocks are assumed to be strongly</span><br><span>    * monotonic. */</span><br><span style="color: hsl(0, 100%, 40%);">-        if (m_cur_blk_fn >= 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-             int delta = delta_fn(fn, m_cur_blk_fn);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (bts->cur_blk_fn >= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+             int delta = delta_fn(fn, bts->cur_blk_fn);</span><br><span>                if (delta <= 0)</span><br><span>                   return;</span><br><span>      }</span><br><span> </span><br><span>        /* Check block delay vs. the current frame number */</span><br><span style="color: hsl(0, 100%, 40%);">-    if (current_frame_number() != 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                delay = delta_fn(fn, current_frame_number());</span><br><span style="color: hsl(120, 100%, 40%);">+ if (bts_current_frame_number(bts) != 0)</span><br><span style="color: hsl(120, 100%, 40%);">+               delay = delta_fn(fn, bts_current_frame_number(bts));</span><br><span>         if (delay <= -late_block_delay_thresh) {</span><br><span>          LOGP(DRLCMAC, LOGL_NOTICE,</span><br><span>                   "Late RLC block, FN delta: %d FN: %d curFN: %d\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                    delay, fn, current_frame_number());</span><br><span style="color: hsl(0, 100%, 40%);">-             do_rate_ctr_inc(CTR_RLC_LATE_BLOCK);</span><br><span style="color: hsl(120, 100%, 40%);">+                  delay, fn, bts_current_frame_number(bts));</span><br><span style="color: hsl(120, 100%, 40%);">+            bts_do_rate_ctr_inc(bts, CTR_RLC_LATE_BLOCK);</span><br><span>        }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   m_cur_blk_fn = fn;</span><br><span style="color: hsl(120, 100%, 40%);">+    bts->cur_blk_fn = fn;</span><br><span>     if (delay < fn_update_ok_min_delay || delay > fn_update_ok_max_delay ||</span><br><span style="color: hsl(0, 100%, 40%);">-           current_frame_number() == 0)</span><br><span style="color: hsl(0, 100%, 40%);">-            m_cur_fn = fn;</span><br><span style="color: hsl(120, 100%, 40%);">+                bts_current_frame_number(bts) == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+           bts->cur_fn = fn;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        m_pollController.expireTimedout(fn, max_delay);</span><br><span style="color: hsl(120, 100%, 40%);">+       bts->pollController->expireTimedout(fn, max_delay);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int BTS::add_paging(uint8_t chan_needed, const struct osmo_mobile_identity *mi)</span><br><span style="color: hsl(120, 100%, 40%);">+int bts_add_paging(struct gprs_rlcmac_bts *bts, uint8_t chan_needed, const struct osmo_mobile_identity *mi)</span><br><span> {</span><br><span>  uint8_t l, trx, ts, any_tbf = 0;</span><br><span>     struct gprs_rlcmac_tbf *tbf;</span><br><span style="color: hsl(0, 100%, 40%);">-    LListHead<gprs_rlcmac_tbf> *pos;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct llist_item *pos;</span><br><span>      uint8_t slot_mask[8];</span><br><span>        int8_t first_ts; /* must be signed */</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       LListHead<gprs_rlcmac_tbf> *tbfs_lists[] = {</span><br><span style="color: hsl(0, 100%, 40%);">-              &m_ul_tbfs,</span><br><span style="color: hsl(0, 100%, 40%);">-         &m_dl_tbfs,</span><br><span style="color: hsl(120, 100%, 40%);">+       struct llist_head *tbfs_lists[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+           &bts->ul_tbfs,</span><br><span style="color: hsl(120, 100%, 40%);">+         &bts->dl_tbfs,</span><br><span>                NULL</span><br><span>         };</span><br><span> </span><br><span>@@ -382,8 +365,8 @@</span><br><span>          * Don't mark, if TBF uses a different slot that is already marked. */</span><br><span>   memset(slot_mask, 0, sizeof(slot_mask));</span><br><span>     for (l = 0; tbfs_lists[l]; l++) {</span><br><span style="color: hsl(0, 100%, 40%);">-               llist_for_each(pos, tbfs_lists[l]) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    tbf = pos->entry();</span><br><span style="color: hsl(120, 100%, 40%);">+                llist_for_each_entry(pos, tbfs_lists[l], list) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      tbf = (struct gprs_rlcmac_tbf *)pos->entry;</span><br><span>                       first_ts = -1;</span><br><span>                       for (ts = 0; ts < 8; ts++) {</span><br><span>                              if (tbf->pdch[ts]) {</span><br><span>@@ -418,7 +401,7 @@</span><br><span>                for (ts = 0; ts < 8; ts++) {</span><br><span>                      if ((slot_mask[trx] & (1 << ts))) {</span><br><span>                                /* schedule */</span><br><span style="color: hsl(0, 100%, 40%);">-                          if (!m_bts.trx[trx].pdch[ts].add_paging(chan_needed, mi))</span><br><span style="color: hsl(120, 100%, 40%);">+                             if (!bts->trx[trx].pdch[ts].add_paging(chan_needed, mi))</span><br><span>                                  return -ENOMEM;</span><br><span> </span><br><span>                          LOGP(DRLCMAC, LOGL_INFO, "Paging on PACCH of TRX=%d TS=%d\n", trx, ts);</span><br><span>@@ -433,8 +416,9 @@</span><br><span>      return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void BTS::send_gsmtap_rach(enum pcu_gsmtap_category categ, uint8_t channel,</span><br><span style="color: hsl(0, 100%, 40%);">-                      const struct rach_ind_params *rip)</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_send_gsmtap_rach(struct gprs_rlcmac_bts *bts,</span><br><span style="color: hsl(120, 100%, 40%);">+                   enum pcu_gsmtap_category categ, uint8_t channel,</span><br><span style="color: hsl(120, 100%, 40%);">+                      const struct rach_ind_params *rip)</span><br><span> {</span><br><span>    struct pcu_l1_meas meas = { 0 };</span><br><span>     uint8_t ra_buf[2];</span><br><span>@@ -450,37 +434,39 @@</span><br><span>           ra_buf[0] = (uint8_t) (rip->ra & 0xff);</span><br><span>       }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   send_gsmtap_meas(categ, true, rip->trx_nr, rip->ts_nr, channel,</span><br><span style="color: hsl(0, 100%, 40%);">-                    rfn_to_fn(rip->rfn), ra_buf,</span><br><span style="color: hsl(120, 100%, 40%);">+      bts_send_gsmtap_meas(bts, categ, true, rip->trx_nr, rip->ts_nr, channel,</span><br><span style="color: hsl(120, 100%, 40%);">+                         bts_rfn_to_fn(bts, rip->rfn), ra_buf,</span><br><span>                     rip->is_11bit ? 2 : 1, &meas);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void BTS::send_gsmtap(enum pcu_gsmtap_category categ, bool uplink, uint8_t trx_no,</span><br><span style="color: hsl(0, 100%, 40%);">-                     uint8_t ts_no, uint8_t channel, uint32_t fn,</span><br><span style="color: hsl(0, 100%, 40%);">-                    const uint8_t *data, unsigned int len)</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_send_gsmtap(struct gprs_rlcmac_bts *bts,</span><br><span style="color: hsl(120, 100%, 40%);">+                    enum pcu_gsmtap_category categ, bool uplink, uint8_t trx_no,</span><br><span style="color: hsl(120, 100%, 40%);">+                  uint8_t ts_no, uint8_t channel, uint32_t fn,</span><br><span style="color: hsl(120, 100%, 40%);">+                  const uint8_t *data, unsigned int len)</span><br><span> {</span><br><span>     struct pcu_l1_meas meas = { 0 };</span><br><span style="color: hsl(0, 100%, 40%);">-        send_gsmtap_meas(categ, uplink, trx_no, ts_no, channel, fn, data, len, &meas);</span><br><span style="color: hsl(120, 100%, 40%);">+    bts_send_gsmtap_meas(bts, categ, uplink, trx_no, ts_no, channel, fn, data, len, &meas);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void BTS::send_gsmtap_meas(enum pcu_gsmtap_category categ, bool uplink, uint8_t trx_no,</span><br><span style="color: hsl(0, 100%, 40%);">-                   uint8_t ts_no, uint8_t channel, uint32_t fn,</span><br><span style="color: hsl(0, 100%, 40%);">-                    const uint8_t *data, unsigned int len, struct pcu_l1_meas *meas)</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_send_gsmtap_meas(struct gprs_rlcmac_bts *bts,</span><br><span style="color: hsl(120, 100%, 40%);">+                          enum pcu_gsmtap_category categ, bool uplink, uint8_t trx_no,</span><br><span style="color: hsl(120, 100%, 40%);">+                          uint8_t ts_no, uint8_t channel, uint32_t fn,</span><br><span style="color: hsl(120, 100%, 40%);">+                          const uint8_t *data, unsigned int len, struct pcu_l1_meas *meas)</span><br><span> {</span><br><span>      uint16_t arfcn;</span><br><span> </span><br><span>  /* check if category is activated at all */</span><br><span style="color: hsl(0, 100%, 40%);">-     if (!(pcu->gsmtap_categ_mask & (1 << categ)))</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!(bts->pcu->gsmtap_categ_mask & (1 << categ)))</span><br><span>           return;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     arfcn = m_bts.trx[trx_no].arfcn;</span><br><span style="color: hsl(120, 100%, 40%);">+      arfcn = bts->trx[trx_no].arfcn;</span><br><span>   if (uplink)</span><br><span>          arfcn |= GSMTAP_ARFCN_F_UPLINK;</span><br><span> </span><br><span>  /* GSMTAP needs the SNR here, but we only have C/I (meas->link_qual).</span><br><span>        Those are not the same, but there is no known way to convert them,</span><br><span>           let's pass C/I instead of nothing */</span><br><span style="color: hsl(0, 100%, 40%);">-     gsmtap_send(pcu->gsmtap, arfcn, ts_no, channel, 0, fn,</span><br><span style="color: hsl(120, 100%, 40%);">+     gsmtap_send(bts->pcu->gsmtap, arfcn, ts_no, channel, 0, fn,</span><br><span>                meas->rssi, meas->link_qual, data, len);</span><br><span> }</span><br><span> </span><br><span>@@ -493,48 +479,52 @@</span><br><span>  return false;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-gprs_rlcmac_dl_tbf *BTS::dl_tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts)</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlcmac_dl_tbf *bts_dl_tbf_by_poll_fn(struct gprs_rlcmac_bts *bts, uint32_t fn, uint8_t trx, uint8_t ts)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-        LListHead<gprs_rlcmac_tbf> *pos;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct llist_item *pos;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_tbf *tbf;</span><br><span> </span><br><span>     /* only one TBF can poll on specific TS/FN, because scheduler can only</span><br><span>        * schedule one downlink control block (with polling) at a FN per TS */</span><br><span style="color: hsl(0, 100%, 40%);">- llist_for_each(pos, &m_dl_tbfs) {</span><br><span style="color: hsl(0, 100%, 40%);">-           if (tbf_check(pos->entry(), fn, trx, ts))</span><br><span style="color: hsl(0, 100%, 40%);">-                    return as_dl_tbf(pos->entry());</span><br><span style="color: hsl(120, 100%, 40%);">+    llist_for_each_entry(pos, &bts->dl_tbfs, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+               tbf = (struct gprs_rlcmac_tbf *)pos->entry;</span><br><span style="color: hsl(120, 100%, 40%);">+                if (tbf_check(tbf, fn, trx, ts))</span><br><span style="color: hsl(120, 100%, 40%);">+                      return as_dl_tbf(tbf);</span><br><span>       }</span><br><span>    return NULL;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-gprs_rlcmac_ul_tbf *BTS::ul_tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts)</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlcmac_ul_tbf *bts_ul_tbf_by_poll_fn(struct gprs_rlcmac_bts *bts, uint32_t fn, uint8_t trx, uint8_t ts)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- LListHead<gprs_rlcmac_tbf> *pos;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct llist_item *pos;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_tbf *tbf;</span><br><span> </span><br><span>     /* only one TBF can poll on specific TS/FN, because scheduler can only</span><br><span>        * schedule one downlink control block (with polling) at a FN per TS */</span><br><span style="color: hsl(0, 100%, 40%);">- llist_for_each(pos, &m_ul_tbfs) {</span><br><span style="color: hsl(0, 100%, 40%);">-           if (tbf_check(pos->entry(), fn, trx, ts))</span><br><span style="color: hsl(0, 100%, 40%);">-                    return as_ul_tbf(pos->entry());</span><br><span style="color: hsl(120, 100%, 40%);">+    llist_for_each_entry(pos, &bts->ul_tbfs, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+               tbf = (struct gprs_rlcmac_tbf *)pos->entry;</span><br><span style="color: hsl(120, 100%, 40%);">+                if (tbf_check(tbf, fn, trx, ts))</span><br><span style="color: hsl(120, 100%, 40%);">+                      return as_ul_tbf(tbf);</span><br><span>       }</span><br><span>    return NULL;</span><br><span> }</span><br><span> </span><br><span> /* lookup downlink TBF Entity (by TFI) */</span><br><span style="color: hsl(0, 100%, 40%);">-gprs_rlcmac_dl_tbf *BTS::dl_tbf_by_tfi(uint8_t tfi, uint8_t trx, uint8_t ts)</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlcmac_dl_tbf *bts_dl_tbf_by_tfi(struct gprs_rlcmac_bts *bts, uint8_t tfi, uint8_t trx, uint8_t ts)</span><br><span> {</span><br><span>         if (trx >= 8 || ts >= 8)</span><br><span>               return NULL;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        return m_bts.trx[trx].pdch[ts].dl_tbf_by_tfi(tfi);</span><br><span style="color: hsl(120, 100%, 40%);">+    return bts->trx[trx].pdch[ts].dl_tbf_by_tfi(tfi);</span><br><span> }</span><br><span> </span><br><span> /* lookup uplink TBF Entity (by TFI) */</span><br><span style="color: hsl(0, 100%, 40%);">-gprs_rlcmac_ul_tbf *BTS::ul_tbf_by_tfi(uint8_t tfi, uint8_t trx, uint8_t ts)</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlcmac_ul_tbf *bts_ul_tbf_by_tfi(struct gprs_rlcmac_bts *bts, uint8_t tfi, uint8_t trx, uint8_t ts)</span><br><span> {</span><br><span>   if (trx >= 8 || ts >= 8)</span><br><span>               return NULL;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        return m_bts.trx[trx].pdch[ts].ul_tbf_by_tfi(tfi);</span><br><span style="color: hsl(120, 100%, 40%);">+    return bts->trx[trx].pdch[ts].ul_tbf_by_tfi(tfi);</span><br><span> }</span><br><span> </span><br><span> static unsigned int trx_count_free_tfi(const struct gprs_rlcmac_trx *trx, enum gprs_rlcmac_tbf_direction dir, uint8_t *first_free_tfi)</span><br><span>@@ -576,7 +566,8 @@</span><br><span>  * that is currently not used in any PDCH of a the TRX with least TFIs currently</span><br><span>  * assigned. Negative values indicate errors.</span><br><span>  */</span><br><span style="color: hsl(0, 100%, 40%);">-int BTS::tfi_find_free(enum gprs_rlcmac_tbf_direction dir, uint8_t *_trx, int8_t use_trx) const</span><br><span style="color: hsl(120, 100%, 40%);">+int bts_tfi_find_free(const struct gprs_rlcmac_bts *bts, enum gprs_rlcmac_tbf_direction dir,</span><br><span style="color: hsl(120, 100%, 40%);">+                      uint8_t *_trx, int8_t use_trx)</span><br><span> {</span><br><span>    uint8_t trx_from, trx_to, trx;</span><br><span>       uint8_t best_trx_nr = 0xff;</span><br><span>@@ -594,7 +585,7 @@</span><br><span>    for (trx = trx_from; trx <= trx_to; trx++) {</span><br><span>              uint8_t tmp_first_tfi;</span><br><span>               unsigned int tmp_cnt;</span><br><span style="color: hsl(0, 100%, 40%);">-           tmp_cnt = trx_count_free_tfi(&m_bts.trx[trx], dir, &tmp_first_tfi);</span><br><span style="color: hsl(120, 100%, 40%);">+           tmp_cnt = trx_count_free_tfi(&bts->trx[trx], dir, &tmp_first_tfi);</span><br><span>                if (tmp_cnt > best_cnt) {</span><br><span>                         best_cnt = tmp_cnt;</span><br><span>                  best_first_tfi = tmp_first_tfi;</span><br><span>@@ -615,7 +606,7 @@</span><br><span>        return best_first_tfi;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int BTS::rcv_imm_ass_cnf(const uint8_t *data, uint32_t fn)</span><br><span style="color: hsl(120, 100%, 40%);">+int bts_rcv_imm_ass_cnf(struct gprs_rlcmac_bts *bts, const uint8_t *data, uint32_t fn)</span><br><span> {</span><br><span>       struct gprs_rlcmac_dl_tbf *dl_tbf = NULL;</span><br><span>    uint8_t plen;</span><br><span>@@ -640,7 +631,7 @@</span><br><span>  tlli |= (*data++) << 4;</span><br><span>        tlli |= (*data++) >> 4;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       ms = ms_by_tlli(tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+        ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);</span><br><span>   if (ms)</span><br><span>              dl_tbf = ms_dl_tbf(ms);</span><br><span>      if (!dl_tbf) {</span><br><span>@@ -658,7 +649,7 @@</span><br><span> }</span><br><span> </span><br><span> /* Determine the full frame number from a relative frame number */</span><br><span style="color: hsl(0, 100%, 40%);">-uint32_t BTS::rfn_to_fn(int32_t rfn)</span><br><span style="color: hsl(120, 100%, 40%);">+uint32_t bts_rfn_to_fn(const struct gprs_rlcmac_bts *bts, int32_t rfn)</span><br><span> {</span><br><span>         int32_t m_cur_rfn;</span><br><span>   int32_t fn;</span><br><span>@@ -682,11 +673,11 @@</span><br><span> </span><br><span>      /* Compute an internal relative frame number from the full internal</span><br><span>     frame number */</span><br><span style="color: hsl(0, 100%, 40%);">-      m_cur_rfn = m_cur_fn % RFN_MODULUS;</span><br><span style="color: hsl(120, 100%, 40%);">+   m_cur_rfn = bts->cur_fn % RFN_MODULUS;</span><br><span> </span><br><span>        /* Compute a "rounded" version of the internal frame number, which</span><br><span>          * exactly fits in the RFN_MODULUS raster */</span><br><span style="color: hsl(0, 100%, 40%);">-    fn_rounded = m_cur_fn - m_cur_rfn;</span><br><span style="color: hsl(120, 100%, 40%);">+    fn_rounded = bts->cur_fn - m_cur_rfn;</span><br><span> </span><br><span>         /* If the delta between the internal and the external relative frame</span><br><span>          * number exceeds a certain limit, we need to assume that the incoming</span><br><span>@@ -695,7 +686,7 @@</span><br><span>         if (abs(rfn - m_cur_rfn) > RFN_THRESHOLD) {</span><br><span>               LOGP(DRLCMAC, LOGL_DEBUG,</span><br><span>                 "Race condition between rfn (%u) and m_cur_fn (%u) detected: rfn belongs to the previous modulus %u cycle, wrapping...\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                    rfn, m_cur_fn, RFN_MODULUS);</span><br><span style="color: hsl(120, 100%, 40%);">+                  rfn, bts->cur_fn, RFN_MODULUS);</span><br><span>              if (fn_rounded < RFN_MODULUS) {</span><br><span>                   LOGP(DRLCMAC, LOGL_DEBUG,</span><br><span>                    "Cornercase detected: wrapping crosses %u border\n",</span><br><span>@@ -819,7 +810,7 @@</span><br><span>         return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int BTS::rcv_rach(const struct rach_ind_params *rip)</span><br><span style="color: hsl(120, 100%, 40%);">+int bts_rcv_rach(struct gprs_rlcmac_bts *bts, const struct rach_ind_params *rip)</span><br><span> {</span><br><span>        struct chan_req_params chan_req = { 0 };</span><br><span>     struct gprs_rlcmac_ul_tbf *tbf = NULL;</span><br><span>@@ -829,16 +820,16 @@</span><br><span>       uint8_t tsc = 0;</span><br><span>     int plen, rc;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       do_rate_ctr_inc(CTR_RACH_REQUESTS);</span><br><span style="color: hsl(120, 100%, 40%);">+   bts_do_rate_ctr_inc(bts, CTR_RACH_REQUESTS);</span><br><span> </span><br><span>     if (rip->is_11bit)</span><br><span style="color: hsl(0, 100%, 40%);">-           do_rate_ctr_inc(CTR_11BIT_RACH_REQUESTS);</span><br><span style="color: hsl(120, 100%, 40%);">+             bts_do_rate_ctr_inc(bts, CTR_11BIT_RACH_REQUESTS);</span><br><span> </span><br><span>       /* Determine full frame number */</span><br><span style="color: hsl(0, 100%, 40%);">-       uint32_t Fn = rfn_to_fn(rip->rfn);</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t Fn = bts_rfn_to_fn(bts, rip->rfn);</span><br><span>       uint8_t ta = qta2ta(rip->qta);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   send_gsmtap_rach(PCU_GSMTAP_C_UL_RACH, GSMTAP_CHANNEL_RACH, rip);</span><br><span style="color: hsl(120, 100%, 40%);">+     bts_send_gsmtap_rach(bts, PCU_GSMTAP_C_UL_RACH, GSMTAP_CHANNEL_RACH, rip);</span><br><span> </span><br><span>       LOGP(DRLCMAC, LOGL_DEBUG, "MS requests Uplink resource on CCCH/RACH: "</span><br><span>          "ra=0x%02x (%d bit) Fn=%u qta=%d\n", rip->ra,</span><br><span>@@ -851,7 +842,7 @@</span><br><span> </span><br><span>    if (chan_req.single_block)</span><br><span>           LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block allocation\n");</span><br><span style="color: hsl(0, 100%, 40%);">-   else if (pcu->vty.force_two_phase) {</span><br><span style="color: hsl(120, 100%, 40%);">+       else if (bts->pcu->vty.force_two_phase) {</span><br><span>              LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block allocation, "</span><br><span>               "but we force two phase access\n");</span><br><span>           chan_req.single_block = true;</span><br><span>@@ -864,7 +855,7 @@</span><br><span> </span><br><span>      /* Should we allocate a single block or an Uplink TBF? */</span><br><span>    if (chan_req.single_block) {</span><br><span style="color: hsl(0, 100%, 40%);">-            rc = sba()->alloc(&trx_no, &ts_no, &sb_fn, ta);</span><br><span style="color: hsl(120, 100%, 40%);">+                rc = bts_sba(bts)->alloc(&trx_no, &ts_no, &sb_fn, ta);</span><br><span>                if (rc < 0) {</span><br><span>                     LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource for "</span><br><span>                              "single block allocation: rc=%d\n", rc);</span><br><span>@@ -872,12 +863,12 @@</span><br><span>                      goto send_imm_ass_rej;</span><br><span>               }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-           tsc = m_bts.trx[trx_no].pdch[ts_no].tsc;</span><br><span style="color: hsl(120, 100%, 40%);">+              tsc = bts->trx[trx_no].pdch[ts_no].tsc;</span><br><span>           LOGP(DRLCMAC, LOGL_DEBUG, "Allocated a single block at "</span><br><span>                "SBFn=%u TRX=%u TS=%u\n", sb_fn, trx_no, ts_no);</span><br><span>      } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                GprsMs *ms = ms_alloc(0, chan_req.egprs_mslot_class);</span><br><span style="color: hsl(0, 100%, 40%);">-           tbf = tbf_alloc_ul_tbf(&m_bts, ms, -1, true);</span><br><span style="color: hsl(120, 100%, 40%);">+             GprsMs *ms = bts_alloc_ms(bts, 0, chan_req.egprs_mslot_class);</span><br><span style="color: hsl(120, 100%, 40%);">+                tbf = tbf_alloc_ul_tbf(bts, ms, -1, true);</span><br><span>           if (!tbf) {</span><br><span>                  LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource for Uplink TBF\n");</span><br><span>                   /* Send RR Immediate Assignment Reject */</span><br><span>@@ -905,18 +896,18 @@</span><br><span>            LOGP(DRLCMAC, LOGL_DEBUG, "Tx Immediate Assignment Reject on AGCH\n");</span><br><span>             plen = Encoding::write_immediate_assignment_reject(</span><br><span>                  bv, rip->ra, Fn, rip->burst_type);</span><br><span style="color: hsl(0, 100%, 40%);">-                do_rate_ctr_inc(CTR_IMMEDIATE_ASSIGN_REJ);</span><br><span style="color: hsl(120, 100%, 40%);">+            bts_do_rate_ctr_inc(bts, CTR_IMMEDIATE_ASSIGN_REJ);</span><br><span>  } else {</span><br><span>             LOGP(DRLCMAC, LOGL_DEBUG, "Tx Immediate Assignment on AGCH: "</span><br><span>                   "TRX=%u (ARFCN %u) TS=%u TA=%u TSC=%u TFI=%d USF=%d\n",</span><br><span style="color: hsl(0, 100%, 40%);">-               trx_no, m_bts.trx[trx_no].arfcn & ~ARFCN_FLAG_MASK,</span><br><span style="color: hsl(120, 100%, 40%);">+               trx_no, bts->trx[trx_no].arfcn & ~ARFCN_FLAG_MASK,</span><br><span>                    ts_no, ta, tsc, tbf ? tbf->tfi() : -1, usf);</span><br><span>                 plen = Encoding::write_immediate_assignment(</span><br><span style="color: hsl(0, 100%, 40%);">-                    &m_bts.trx[trx_no].pdch[ts_no], tbf, bv,</span><br><span style="color: hsl(120, 100%, 40%);">+                  &bts->trx[trx_no].pdch[ts_no], tbf, bv,</span><br><span>                       false, rip->ra, Fn, ta, usf, false, sb_fn,</span><br><span style="color: hsl(0, 100%, 40%);">-                   pcu->vty.alpha, pcu->vty.gamma, -1,</span><br><span style="color: hsl(120, 100%, 40%);">+                     bts->pcu->vty.alpha, bts->pcu->vty.gamma, -1,</span><br><span>                    rip->burst_type);</span><br><span style="color: hsl(0, 100%, 40%);">-            do_rate_ctr_inc(CTR_IMMEDIATE_ASSIGN_UL_TBF);</span><br><span style="color: hsl(120, 100%, 40%);">+         bts_do_rate_ctr_inc(bts, CTR_IMMEDIATE_ASSIGN_UL_TBF);</span><br><span>       }</span><br><span> </span><br><span>        if (plen >= 0)</span><br><span>@@ -937,14 +928,13 @@</span><br><span>    324, 350, 376, 402,</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int BTS::rcv_ptcch_rach(const struct rach_ind_params *rip)</span><br><span style="color: hsl(120, 100%, 40%);">+int bts_rcv_ptcch_rach(struct gprs_rlcmac_bts *bts, const struct rach_ind_params *rip)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-    uint32_t fn416 = rfn_to_fn(rip->rfn) % 416;</span><br><span style="color: hsl(0, 100%, 40%);">-  struct gprs_rlcmac_bts *bts = bts_data();</span><br><span style="color: hsl(120, 100%, 40%);">+     uint32_t fn416 = bts_rfn_to_fn(bts, rip->rfn) % 416;</span><br><span>      struct gprs_rlcmac_pdch *pdch;</span><br><span>       uint8_t ss;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- send_gsmtap_rach(PCU_GSMTAP_C_UL_PTCCH, GSMTAP_CHANNEL_PTCCH, rip);</span><br><span style="color: hsl(120, 100%, 40%);">+   bts_send_gsmtap_rach(bts, PCU_GSMTAP_C_UL_PTCCH, GSMTAP_CHANNEL_PTCCH, rip);</span><br><span> </span><br><span>     /* Prevent buffer overflow */</span><br><span>        if (rip->trx_nr >= ARRAY_SIZE(bts->trx) || rip->ts_nr >= 8) {</span><br><span>@@ -979,7 +969,7 @@</span><br><span>   return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void BTS::snd_dl_ass(gprs_rlcmac_tbf *tbf, bool poll, uint16_t pgroup)</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_snd_dl_ass(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *tbf, bool poll, uint16_t pgroup)</span><br><span> {</span><br><span>     uint8_t trx_no = tbf->trx->trx_no;</span><br><span>     uint8_t ts_no = tbf->first_ts;</span><br><span>@@ -992,14 +982,14 @@</span><br><span>     * so the assignment will not conflict with possible RACH requests. */</span><br><span>       LOGP(DRLCMAC, LOGL_DEBUG, " - TRX=%d (%d) TS=%d TA=%d pollFN=%d\n",</span><br><span>                trx_no, tbf->trx->arfcn, ts_no, tbf->ta(), poll ? tbf->poll_fn : -1);</span><br><span style="color: hsl(0, 100%, 40%);">-       plen = Encoding::write_immediate_assignment(&m_bts.trx[trx_no].pdch[ts_no],</span><br><span style="color: hsl(120, 100%, 40%);">+       plen = Encoding::write_immediate_assignment(&bts->trx[trx_no].pdch[ts_no],</span><br><span>                                                tbf, immediate_assignment, true, 125,</span><br><span>                                                (tbf->pdch[ts_no]->last_rts_fn + 21216) % GSM_MAX_FN,</span><br><span>                                                  tbf->ta(), 7, poll, tbf->poll_fn,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                 pcu->vty.alpha, pcu->vty.gamma, -1,</span><br><span style="color: hsl(120, 100%, 40%);">+                                             bts->pcu->vty.alpha, bts->pcu->vty.gamma, -1,</span><br><span>                                                    GSM_L1_BURST_TYPE_ACCESS_0);</span><br><span>     if (plen >= 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-             do_rate_ctr_inc(CTR_IMMEDIATE_ASSIGN_DL_TBF);</span><br><span style="color: hsl(120, 100%, 40%);">+         bts_do_rate_ctr_inc(bts, CTR_IMMEDIATE_ASSIGN_DL_TBF);</span><br><span>               pcu_l1if_tx_pch(immediate_assignment, plen, pgroup);</span><br><span>         }</span><br><span> </span><br><span>@@ -1007,70 +997,70 @@</span><br><span> }</span><br><span> </span><br><span> /* return maximum DL CS supported by BTS and allowed by VTY */</span><br><span style="color: hsl(0, 100%, 40%);">-uint8_t BTS::max_cs_dl(void) const</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t bts_max_cs_dl(const struct gprs_rlcmac_bts* bts)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      return m_max_cs_dl;</span><br><span style="color: hsl(120, 100%, 40%);">+   return bts->max_cs_dl;</span><br><span> }</span><br><span> </span><br><span> /* return maximum UL CS supported by BTS and allowed by VTY */</span><br><span style="color: hsl(0, 100%, 40%);">-uint8_t BTS::max_cs_ul(void) const</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t bts_max_cs_ul(const struct gprs_rlcmac_bts* bts)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   return m_max_cs_ul;</span><br><span style="color: hsl(120, 100%, 40%);">+   return bts->max_cs_ul;</span><br><span> }</span><br><span> </span><br><span> /* return maximum DL MCS supported by BTS and allowed by VTY */</span><br><span style="color: hsl(0, 100%, 40%);">-uint8_t BTS::max_mcs_dl(void) const</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t bts_max_mcs_dl(const struct gprs_rlcmac_bts* bts)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-        return m_max_mcs_dl;</span><br><span style="color: hsl(120, 100%, 40%);">+  return bts->max_mcs_dl;</span><br><span> }</span><br><span> </span><br><span> /* return maximum UL MCS supported by BTS and allowed by VTY */</span><br><span style="color: hsl(0, 100%, 40%);">-uint8_t BTS::max_mcs_ul(void) const</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t bts_max_mcs_ul(const struct gprs_rlcmac_bts* bts)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-       return m_max_mcs_ul;</span><br><span style="color: hsl(120, 100%, 40%);">+  return bts->max_mcs_ul;</span><br><span> }</span><br><span> </span><br><span> /* Set maximum DL CS supported by BTS and allowed by VTY */</span><br><span style="color: hsl(0, 100%, 40%);">-void BTS::set_max_cs_dl(uint8_t cs_dl)</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_set_max_cs_dl(struct gprs_rlcmac_bts* bts, uint8_t cs_dl)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-       m_max_cs_dl = cs_dl;</span><br><span style="color: hsl(120, 100%, 40%);">+  bts->max_cs_dl = cs_dl;</span><br><span> }</span><br><span> </span><br><span> /* Set maximum UL CS supported by BTS and allowed by VTY */</span><br><span style="color: hsl(0, 100%, 40%);">-void BTS::set_max_cs_ul(uint8_t cs_ul)</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_set_max_cs_ul(struct gprs_rlcmac_bts* bts, uint8_t cs_ul)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-       m_max_cs_ul = cs_ul;</span><br><span style="color: hsl(120, 100%, 40%);">+  bts->max_cs_ul = cs_ul;</span><br><span> }</span><br><span> </span><br><span> /* Set maximum DL MCS supported by BTS and allowed by VTY */</span><br><span style="color: hsl(0, 100%, 40%);">-void BTS::set_max_mcs_dl(uint8_t mcs_dl)</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_set_max_mcs_dl(struct gprs_rlcmac_bts* bts, uint8_t mcs_dl)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  m_max_mcs_dl = mcs_dl;</span><br><span style="color: hsl(120, 100%, 40%);">+        bts->max_mcs_dl = mcs_dl;</span><br><span> }</span><br><span> </span><br><span> /* Set maximum UL MCS supported by BTS and allowed by VTY */</span><br><span style="color: hsl(0, 100%, 40%);">-void BTS::set_max_mcs_ul(uint8_t mcs_ul)</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_set_max_mcs_ul(struct gprs_rlcmac_bts* bts, uint8_t mcs_ul)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-        m_max_mcs_ul = mcs_ul;</span><br><span style="color: hsl(120, 100%, 40%);">+        bts->max_mcs_ul = mcs_ul;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-bool BTS::cs_dl_is_supported(CodingScheme cs)</span><br><span style="color: hsl(120, 100%, 40%);">+bool bts_cs_dl_is_supported(const struct gprs_rlcmac_bts* bts, CodingScheme cs)</span><br><span> {</span><br><span>     OSMO_ASSERT(mcs_is_valid(cs));</span><br><span>       uint8_t num = mcs_chan_code(cs);</span><br><span>     if (mcs_is_gprs(cs)) {</span><br><span style="color: hsl(0, 100%, 40%);">-          return (max_cs_dl() >= num) && (m_bts.cs_mask & (1U << num));</span><br><span style="color: hsl(120, 100%, 40%);">+            return (bts_max_cs_dl(bts) >= num) && (bts->cs_mask & (1U << num));</span><br><span>  } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                return (max_mcs_dl() >= num) && (m_bts.mcs_mask & (1U << num));</span><br><span style="color: hsl(120, 100%, 40%);">+          return (bts_max_mcs_dl(bts) >= num) && (bts->mcs_mask & (1U << num));</span><br><span>        }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-GprsMs *BTS::ms_alloc(uint8_t ms_class, uint8_t egprs_ms_class)</span><br><span style="color: hsl(120, 100%, 40%);">+GprsMs *bts_alloc_ms(struct gprs_rlcmac_bts* bts, uint8_t ms_class, uint8_t egprs_ms_class)</span><br><span> {</span><br><span>  GprsMs *ms;</span><br><span style="color: hsl(0, 100%, 40%);">-     ms = ms_store().create_ms();</span><br><span style="color: hsl(120, 100%, 40%);">+  ms = bts_ms_store(bts)->create_ms();</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     ms_set_timeout(ms, osmo_tdef_get(pcu->T_defs, -2030, OSMO_TDEF_S, -1));</span><br><span style="color: hsl(120, 100%, 40%);">+    ms_set_timeout(ms, osmo_tdef_get(bts->pcu->T_defs, -2030, OSMO_TDEF_S, -1));</span><br><span>   ms_set_ms_class(ms, ms_class);</span><br><span>       ms_set_egprs_ms_class(ms, egprs_ms_class);</span><br><span> </span><br><span>@@ -1078,23 +1068,38 @@</span><br><span> }</span><br><span> </span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int bts_talloc_destructor(struct BTS* bts)</span><br><span style="color: hsl(120, 100%, 40%);">+static int bts_talloc_destructor(struct gprs_rlcmac_bts* bts)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      bts->~BTS();</span><br><span style="color: hsl(120, 100%, 40%);">+       bts_cleanup(bts);</span><br><span>    return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct BTS* bts_alloc(struct gprs_pcu *pcu)</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlcmac_bts* bts_alloc(struct gprs_pcu *pcu)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-     struct BTS* bts;</span><br><span style="color: hsl(0, 100%, 40%);">-        bts = talloc(pcu, struct BTS);</span><br><span style="color: hsl(120, 100%, 40%);">+        struct gprs_rlcmac_bts* bts;</span><br><span style="color: hsl(120, 100%, 40%);">+  bts = talloc_zero(pcu, struct gprs_rlcmac_bts);</span><br><span>      if (!bts)</span><br><span>            return bts;</span><br><span>  talloc_set_destructor(bts, bts_talloc_destructor);</span><br><span style="color: hsl(0, 100%, 40%);">-      new (bts) BTS(pcu);</span><br><span style="color: hsl(120, 100%, 40%);">+   bts_init(bts, pcu);</span><br><span>  return bts;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+struct SBAController *bts_sba(struct gprs_rlcmac_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   return bts->sba;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct GprsMsStorage *bts_ms_store(struct gprs_rlcmac_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  return bts->ms_store;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct GprsMs *bts_ms_by_tlli(struct gprs_rlcmac_bts *bts, uint32_t tlli, uint32_t old_tlli)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        return bts_ms_store(bts)->get_ms(tlli, old_tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* update TA based on TA provided by PH-DATA-IND */</span><br><span> void update_tbf_ta(struct gprs_rlcmac_ul_tbf *tbf, int8_t ta_delta)</span><br><span> {</span><br><span>@@ -1136,7 +1141,7 @@</span><br><span> void bts_update_tbf_ta(const char *p, uint32_t fn, uint8_t trx_no, uint8_t ts, int8_t ta, bool is_rach)</span><br><span> {</span><br><span>         struct gprs_rlcmac_ul_tbf *tbf =</span><br><span style="color: hsl(0, 100%, 40%);">-                bts_main_data()->bts->ul_tbf_by_poll_fn(fn, trx_no, ts);</span><br><span style="color: hsl(120, 100%, 40%);">+                bts_ul_tbf_by_poll_fn(the_pcu->bts, fn, trx_no, ts);</span><br><span>      if (!tbf)</span><br><span>            LOGP(DL1IF, LOGL_DEBUG, "[%s] update TA = %u ignored due to "</span><br><span>                   "unknown UL TBF on TRX = %d, TS = %d, FN = %d\n",</span><br><span>@@ -1182,7 +1187,7 @@</span><br><span>             return;</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   max_cs_dl = bts->bts->max_cs_dl();</span><br><span style="color: hsl(120, 100%, 40%);">+      max_cs_dl = bts_max_cs_dl(bts);</span><br><span>      if (bts->pcuif_info_ind.initial_cs > max_cs_dl) {</span><br><span>              LOGP(DL1IF, LOGL_DEBUG, " downgrading initial_cs_dl to %d\n", max_cs_dl);</span><br><span>          bts->initial_cs_dl = max_cs_dl;</span><br><span>@@ -1192,7 +1197,7 @@</span><br><span>   if (bts->initial_cs_dl == 0)</span><br><span>              bts->initial_cs_dl = 1; /* CS1 Must always be supported */</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       max_cs_ul = bts->bts->max_cs_ul();</span><br><span style="color: hsl(120, 100%, 40%);">+      max_cs_ul = bts_max_cs_ul(bts);</span><br><span>      if (bts->pcuif_info_ind.initial_cs > max_cs_ul) {</span><br><span>              LOGP(DL1IF, LOGL_DEBUG, " downgrading initial_cs_ul to %d\n", max_cs_ul);</span><br><span>          bts->initial_cs_ul = max_cs_ul;</span><br><span>@@ -1212,14 +1217,14 @@</span><br><span>                 return;</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   max_mcs_dl = bts->bts->max_mcs_dl();</span><br><span style="color: hsl(120, 100%, 40%);">+    max_mcs_dl = bts_max_mcs_dl(bts);</span><br><span>    if (bts->pcuif_info_ind.initial_mcs > max_mcs_dl) {</span><br><span>            LOGP(DL1IF, LOGL_DEBUG, " downgrading initial_mcs_dl to %d\n", max_mcs_dl);</span><br><span>                bts->initial_mcs_dl = max_mcs_dl;</span><br><span>         } else {</span><br><span>             bts->initial_mcs_dl = bts->pcuif_info_ind.initial_mcs;</span><br><span>         }</span><br><span style="color: hsl(0, 100%, 40%);">-       max_mcs_ul = bts->bts->max_mcs_ul();</span><br><span style="color: hsl(120, 100%, 40%);">+    max_mcs_ul = bts_max_mcs_ul(bts);</span><br><span>    if (bts->pcuif_info_ind.initial_mcs > max_mcs_ul) {</span><br><span>            LOGP(DL1IF, LOGL_DEBUG, " downgrading initial_mcs_ul to %d\n", max_mcs_ul);</span><br><span>                bts->initial_mcs_ul = max_mcs_ul;</span><br><span>@@ -1232,7 +1237,7 @@</span><br><span> {</span><br><span>    int i;</span><br><span>       uint8_t cs_dl, cs_ul;</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gprs_pcu *pcu = bts->bts->pcu;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct gprs_pcu *pcu = bts->pcu;</span><br><span> </span><br><span>      cs_dl = 0;</span><br><span>   for (i = pcu->vty.max_cs_dl - 1; i >= 0; i--) {</span><br><span>@@ -1251,15 +1256,15 @@</span><br><span>      }</span><br><span> </span><br><span>        LOGP(DRLCMAC, LOGL_DEBUG, "New max CS: DL=%u UL=%u\n", cs_dl, cs_ul);</span><br><span style="color: hsl(0, 100%, 40%);">- bts->bts->set_max_cs_dl(cs_dl);</span><br><span style="color: hsl(0, 100%, 40%);">-   bts->bts->set_max_cs_ul(cs_ul);</span><br><span style="color: hsl(120, 100%, 40%);">+ bts_set_max_cs_dl(bts, cs_dl);</span><br><span style="color: hsl(120, 100%, 40%);">+        bts_set_max_cs_ul(bts, cs_ul);</span><br><span> }</span><br><span> </span><br><span> void bts_recalc_max_mcs(struct gprs_rlcmac_bts *bts)</span><br><span> {</span><br><span>         int i;</span><br><span>       uint8_t mcs_dl, mcs_ul;</span><br><span style="color: hsl(0, 100%, 40%);">- struct gprs_pcu *pcu = bts->bts->pcu;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct gprs_pcu *pcu = bts->pcu;</span><br><span> </span><br><span>      mcs_dl = 0;</span><br><span>  for (i = pcu->vty.max_mcs_dl - 1; i >= 0; i--) {</span><br><span>@@ -1278,37 +1283,11 @@</span><br><span>     }</span><br><span> </span><br><span>        LOGP(DRLCMAC, LOGL_DEBUG, "New max MCS: DL=%u UL=%u\n", mcs_dl, mcs_ul);</span><br><span style="color: hsl(0, 100%, 40%);">-      bts->bts->set_max_mcs_dl(mcs_dl);</span><br><span style="color: hsl(0, 100%, 40%);">- bts->bts->set_max_mcs_ul(mcs_ul);</span><br><span style="color: hsl(120, 100%, 40%);">+       bts_set_max_mcs_dl(bts, mcs_dl);</span><br><span style="color: hsl(120, 100%, 40%);">+      bts_set_max_mcs_ul(bts, mcs_ul);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct gprs_rlcmac_bts *bts_data(struct BTS *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+struct GprsMs *bts_ms_by_imsi(struct gprs_rlcmac_bts *bts, const char *imsi)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   return &bts->m_bts;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct GprsMs *bts_ms_by_imsi(struct BTS *bts, const char *imsi)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    return bts->ms_by_imsi(imsi);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-uint8_t bts_max_cs_dl(const struct BTS *bts)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  return bts->max_cs_dl();</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-uint8_t bts_max_cs_ul(const struct BTS *bts)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       return bts->max_cs_ul();</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-uint8_t bts_max_mcs_dl(const struct BTS *bts)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      return bts->max_mcs_dl();</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-uint8_t bts_max_mcs_ul(const struct BTS *bts)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     return bts->max_mcs_ul();</span><br><span style="color: hsl(120, 100%, 40%);">+  return bts_ms_store(bts)->get_ms(0, 0, imsi);</span><br><span> }</span><br><span>diff --git a/src/bts.h b/src/bts.h</span><br><span>index b1f73b4..d316370 100644</span><br><span>--- a/src/bts.h</span><br><span>+++ b/src/bts.h</span><br><span>@@ -20,11 +20,13 @@</span><br><span> </span><br><span> #pragma once</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <pdch.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdbool.h></span><br><span> </span><br><span> #ifdef __cplusplus</span><br><span> extern "C" {</span><br><span> #endif</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> #include <osmocom/core/linuxlist.h></span><br><span> #include <osmocom/core/rate_ctr.h></span><br><span> #include <osmocom/core/stat_item.h></span><br><span>@@ -40,21 +42,11 @@</span><br><span> }</span><br><span> #endif</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#ifdef __cplusplus</span><br><span style="color: hsl(0, 100%, 40%);">-#include "poll_controller.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "sba.h"</span><br><span> #include "tbf.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "gprs_ms_storage.h"</span><br><span> #include "coding_scheme.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include <cxx_linuxlist.h></span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#include <pdch.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <stdint.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <stdbool.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct BTS;</span><br><span> struct GprsMs;</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlcmac_bts;</span><br><span> </span><br><span> struct gprs_rlcmac_trx {</span><br><span>    void *fl1h;</span><br><span>@@ -62,11 +54,12 @@</span><br><span>    struct gprs_rlcmac_pdch pdch[8];</span><br><span> </span><br><span>         /* back pointers */</span><br><span style="color: hsl(0, 100%, 40%);">-     struct BTS *bts;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gprs_rlcmac_bts *bts;</span><br><span>         uint8_t trx_no;</span><br><span> </span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #ifdef __cplusplus</span><br><span> extern "C" {</span><br><span> #endif</span><br><span>@@ -78,48 +71,7 @@</span><br><span> }</span><br><span> #endif</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/**</span><br><span style="color: hsl(0, 100%, 40%);">- * This is the data from C. As soon as our minimal compiler is gcc 4.7</span><br><span style="color: hsl(0, 100%, 40%);">- * we can start to compile pcu_vty.c with c++ and remove the split.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-struct gprs_rlcmac_bts {</span><br><span style="color: hsl(0, 100%, 40%);">-        bool active;</span><br><span style="color: hsl(0, 100%, 40%);">-    uint8_t bsic;</span><br><span style="color: hsl(0, 100%, 40%);">-   uint8_t cs_mask; /* Allowed CS mask from BTS */</span><br><span style="color: hsl(0, 100%, 40%);">- uint16_t mcs_mask;  /* Allowed MCS mask from BTS */</span><br><span style="color: hsl(0, 100%, 40%);">-     struct { /* information stored from last received PCUIF info_ind message */</span><br><span style="color: hsl(0, 100%, 40%);">-             uint8_t initial_cs;</span><br><span style="color: hsl(0, 100%, 40%);">-             uint8_t initial_mcs;</span><br><span style="color: hsl(0, 100%, 40%);">-    } pcuif_info_ind;</span><br><span style="color: hsl(0, 100%, 40%);">-       uint8_t initial_cs_dl, initial_cs_ul;</span><br><span style="color: hsl(0, 100%, 40%);">-   uint8_t initial_mcs_dl, initial_mcs_ul;</span><br><span style="color: hsl(0, 100%, 40%);">- /* Timer defintions */</span><br><span style="color: hsl(0, 100%, 40%);">-  struct osmo_tdef *T_defs_bts; /* timers controlled by BTS, received through PCUIF */</span><br><span style="color: hsl(0, 100%, 40%);">-    uint8_t n3101;</span><br><span style="color: hsl(0, 100%, 40%);">-  uint8_t n3103;</span><br><span style="color: hsl(0, 100%, 40%);">-  uint8_t n3105;</span><br><span style="color: hsl(0, 100%, 40%);">-  struct gprs_rlcmac_trx trx[8];</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      uint8_t si13[GSM_MACBLOCK_LEN];</span><br><span style="color: hsl(0, 100%, 40%);">- bool si13_is_set;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* State for dynamic algorithm selection */</span><br><span style="color: hsl(0, 100%, 40%);">-     int multislot_disabled;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /**</span><br><span style="color: hsl(0, 100%, 40%);">-      * Point back to the C++ object. This is used during the transition</span><br><span style="color: hsl(0, 100%, 40%);">-      * period.</span><br><span style="color: hsl(0, 100%, 40%);">-       */</span><br><span style="color: hsl(0, 100%, 40%);">-     struct BTS *bts;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* Packet Application Information (3GPP TS 44.060 11.2.47, usually ETWS primary message). We don't need to store</span><br><span style="color: hsl(0, 100%, 40%);">-     * more than one message, because they get sent so rarely. */</span><br><span style="color: hsl(0, 100%, 40%);">-   struct msgb *app_info;</span><br><span style="color: hsl(0, 100%, 40%);">-  uint32_t app_info_pending; /* Count of MS with active TBF, to which we did not send app_info yet */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* main nsei */</span><br><span style="color: hsl(0, 100%, 40%);">- struct gprs_ns2_nse *nse;</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span> </span><br><span> enum {</span><br><span>    CTR_TBF_DL_ALLOCATED,</span><br><span>@@ -230,189 +182,159 @@</span><br><span>      bool single_block;</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#ifdef __cplusplus</span><br><span style="color: hsl(120, 100%, 40%);">+struct PollController;</span><br><span style="color: hsl(120, 100%, 40%);">+struct SBAController;</span><br><span style="color: hsl(120, 100%, 40%);">+struct GprsMsStorage;</span><br><span style="color: hsl(120, 100%, 40%);">+struct pcu_l1_meas;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /**</span><br><span>  * I represent a GSM BTS. I have one or more TRX, I know the current</span><br><span>  * GSM time and I have controllers that help with allocating resources</span><br><span>  * on my TRXs.</span><br><span>  */</span><br><span style="color: hsl(0, 100%, 40%);">-struct BTS {</span><br><span style="color: hsl(0, 100%, 40%);">-public:</span><br><span style="color: hsl(0, 100%, 40%);">-        BTS(struct gprs_pcu *pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-      ~BTS();</span><br><span style="color: hsl(0, 100%, 40%);">- void cleanup();</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlcmac_bts {</span><br><span style="color: hsl(120, 100%, 40%);">+     bool active;</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t bsic;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t cs_mask; /* Allowed CS mask from BTS */</span><br><span style="color: hsl(120, 100%, 40%);">+       uint16_t mcs_mask;  /* Allowed MCS mask from BTS */</span><br><span style="color: hsl(120, 100%, 40%);">+   struct { /* information stored from last received PCUIF info_ind message */</span><br><span style="color: hsl(120, 100%, 40%);">+           uint8_t initial_cs;</span><br><span style="color: hsl(120, 100%, 40%);">+           uint8_t initial_mcs;</span><br><span style="color: hsl(120, 100%, 40%);">+  } pcuif_info_ind;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t initial_cs_dl, initial_cs_ul;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t initial_mcs_dl, initial_mcs_ul;</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Timer defintions */</span><br><span style="color: hsl(120, 100%, 40%);">+        struct osmo_tdef *T_defs_bts; /* timers controlled by BTS, received through PCUIF */</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t n3101;</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t n3103;</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t n3105;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct gprs_rlcmac_trx trx[8];</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      static BTS* main_bts();</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t si13[GSM_MACBLOCK_LEN];</span><br><span style="color: hsl(120, 100%, 40%);">+       bool si13_is_set;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   struct gprs_rlcmac_bts *bts_data();</span><br><span style="color: hsl(0, 100%, 40%);">-     SBAController *sba();</span><br><span style="color: hsl(120, 100%, 40%);">+ /* State for dynamic algorithm selection */</span><br><span style="color: hsl(120, 100%, 40%);">+   int multislot_disabled;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     /** TODO: change the number to unsigned */</span><br><span style="color: hsl(0, 100%, 40%);">-      void set_current_frame_number(int frame_number);</span><br><span style="color: hsl(0, 100%, 40%);">-        void set_current_block_frame_number(int frame_number, unsigned max_delay);</span><br><span style="color: hsl(0, 100%, 40%);">-      int current_frame_number() const;</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Packet Application Information (3GPP TS 44.060 11.2.47, usually ETWS primary message). We don't need to store</span><br><span style="color: hsl(120, 100%, 40%);">+   * more than one message, because they get sent so rarely. */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct msgb *app_info;</span><br><span style="color: hsl(120, 100%, 40%);">+        uint32_t app_info_pending; /* Count of MS with active TBF, to which we did not send app_info yet */</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- /** add paging to paging queue(s) */</span><br><span style="color: hsl(0, 100%, 40%);">-    int add_paging(uint8_t chan_needed, const struct osmo_mobile_identity *mi);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     gprs_rlcmac_dl_tbf *dl_tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts);</span><br><span style="color: hsl(0, 100%, 40%);">-    gprs_rlcmac_ul_tbf *ul_tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts);</span><br><span style="color: hsl(0, 100%, 40%);">-    gprs_rlcmac_dl_tbf *dl_tbf_by_tfi(uint8_t tfi, uint8_t trx, uint8_t ts);</span><br><span style="color: hsl(0, 100%, 40%);">-        gprs_rlcmac_ul_tbf *ul_tbf_by_tfi(uint8_t tfi, uint8_t trx, uint8_t ts);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        int tfi_find_free(enum gprs_rlcmac_tbf_direction dir, uint8_t *_trx, int8_t use_trx) const;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     int rcv_imm_ass_cnf(const uint8_t *data, uint32_t fn);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  uint32_t rfn_to_fn(int32_t rfn);</span><br><span style="color: hsl(0, 100%, 40%);">-        int rcv_rach(const struct rach_ind_params *rip);</span><br><span style="color: hsl(0, 100%, 40%);">-        int rcv_ptcch_rach(const struct rach_ind_params *rip);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  void snd_dl_ass(gprs_rlcmac_tbf *tbf, bool poll, uint16_t pgroup);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      uint8_t max_cs_dl(void) const;</span><br><span style="color: hsl(0, 100%, 40%);">-  uint8_t max_cs_ul(void) const;</span><br><span style="color: hsl(0, 100%, 40%);">-  uint8_t max_mcs_dl(void) const;</span><br><span style="color: hsl(0, 100%, 40%);">- uint8_t max_mcs_ul(void) const;</span><br><span style="color: hsl(0, 100%, 40%);">- void set_max_cs_dl(uint8_t cs_dl);</span><br><span style="color: hsl(0, 100%, 40%);">-      void set_max_cs_ul(uint8_t cs_ul);</span><br><span style="color: hsl(0, 100%, 40%);">-      void set_max_mcs_dl(uint8_t mcs_dl);</span><br><span style="color: hsl(0, 100%, 40%);">-    void set_max_mcs_ul(uint8_t mcs_ul);</span><br><span style="color: hsl(0, 100%, 40%);">-    bool cs_dl_is_supported(CodingScheme cs);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       GprsMsStorage &ms_store();</span><br><span style="color: hsl(0, 100%, 40%);">-  GprsMs *ms_by_tlli(uint32_t tlli, uint32_t old_tlli = GSM_RESERVED_TMSI);</span><br><span style="color: hsl(0, 100%, 40%);">-       GprsMs *ms_by_imsi(const char *imsi);</span><br><span style="color: hsl(0, 100%, 40%);">-   GprsMs *ms_alloc(uint8_t ms_class, uint8_t egprs_ms_class = 0);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- void send_gsmtap(enum pcu_gsmtap_category categ, bool uplink, uint8_t trx_no,</span><br><span style="color: hsl(0, 100%, 40%);">-                         uint8_t ts_no, uint8_t channel, uint32_t fn,</span><br><span style="color: hsl(0, 100%, 40%);">-                            const uint8_t *data, unsigned int len);</span><br><span style="color: hsl(0, 100%, 40%);">-   void send_gsmtap_meas(enum pcu_gsmtap_category categ, bool uplink, uint8_t trx_no,</span><br><span style="color: hsl(0, 100%, 40%);">-                            uint8_t ts_no, uint8_t channel, uint32_t fn,</span><br><span style="color: hsl(0, 100%, 40%);">-                            const uint8_t *data, unsigned int len, struct pcu_l1_meas *meas);</span><br><span style="color: hsl(0, 100%, 40%);">- void send_gsmtap_rach(enum pcu_gsmtap_category categ, uint8_t channel,</span><br><span style="color: hsl(0, 100%, 40%);">-                        const struct rach_ind_params *rip);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /*</span><br><span style="color: hsl(0, 100%, 40%);">-       * Below for C interface for the VTY</span><br><span style="color: hsl(0, 100%, 40%);">-     */</span><br><span style="color: hsl(0, 100%, 40%);">-     struct rate_ctr_group *rate_counters() const;</span><br><span style="color: hsl(0, 100%, 40%);">-   struct osmo_stat_item_group *stat_items() const;</span><br><span style="color: hsl(0, 100%, 40%);">-        void do_rate_ctr_inc(unsigned int ctr_id);</span><br><span style="color: hsl(0, 100%, 40%);">-      void do_rate_ctr_add(unsigned int ctr_id, int inc);</span><br><span style="color: hsl(0, 100%, 40%);">-     void stat_item_add(unsigned int stat_id, int inc);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      LListHead<gprs_rlcmac_tbf>& ul_tbfs();</span><br><span style="color: hsl(0, 100%, 40%);">-        LListHead<gprs_rlcmac_tbf>& dl_tbfs();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        struct gprs_rlcmac_bts m_bts;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* main nsei */</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_ns2_nse *nse;</span><br><span> </span><br><span>        /* back pointer to PCU object */</span><br><span>     struct gprs_pcu *pcu;</span><br><span style="color: hsl(0, 100%, 40%);">-private:</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       int m_cur_fn;</span><br><span style="color: hsl(0, 100%, 40%);">-   int m_cur_blk_fn;</span><br><span style="color: hsl(0, 100%, 40%);">-       uint8_t m_max_cs_dl, m_max_cs_ul;</span><br><span style="color: hsl(0, 100%, 40%);">-       uint8_t m_max_mcs_dl, m_max_mcs_ul;</span><br><span style="color: hsl(0, 100%, 40%);">-     PollController m_pollController;</span><br><span style="color: hsl(0, 100%, 40%);">-        SBAController m_sba;</span><br><span style="color: hsl(0, 100%, 40%);">-    struct rate_ctr_group *m_ratectrs;</span><br><span style="color: hsl(0, 100%, 40%);">-      struct osmo_stat_item_group *m_statg;</span><br><span style="color: hsl(120, 100%, 40%);">+ int cur_fn;</span><br><span style="color: hsl(120, 100%, 40%);">+   int cur_blk_fn;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t max_cs_dl, max_cs_ul;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t max_mcs_dl, max_mcs_ul;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct PollController *pollController;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct SBAController *sba;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct rate_ctr_group *ratectrs;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct osmo_stat_item_group *statg;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- GprsMsStorage m_ms_store;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct GprsMsStorage *ms_store;</span><br><span> </span><br><span>  /* list of uplink TBFs */</span><br><span style="color: hsl(0, 100%, 40%);">-       LListHead<gprs_rlcmac_tbf> m_ul_tbfs;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct llist_head ul_tbfs; /* list of gprs_rlcmac_tbf */</span><br><span>     /* list of downlink TBFs */</span><br><span style="color: hsl(0, 100%, 40%);">-     LListHead<gprs_rlcmac_tbf> m_dl_tbfs;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* disable copying to avoid slicing */</span><br><span style="color: hsl(0, 100%, 40%);">-  BTS(const BTS&);</span><br><span style="color: hsl(0, 100%, 40%);">-    BTS& operator=(const BTS&);</span><br><span style="color: hsl(120, 100%, 40%);">+   struct llist_head dl_tbfs; /* list of gprs_rlcmac_tbf */</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-inline int BTS::current_frame_number() const</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- return m_cur_fn;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-inline SBAController *BTS::sba()</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      return &m_sba;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-inline GprsMsStorage &BTS::ms_store()</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   return m_ms_store;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-inline GprsMs *BTS::ms_by_tlli(uint32_t tlli, uint32_t old_tlli)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    return ms_store().get_ms(tlli, old_tlli);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-inline GprsMs *BTS::ms_by_imsi(const char *imsi)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     return ms_store().get_ms(0, 0, imsi);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-inline LListHead<gprs_rlcmac_tbf>& BTS::ul_tbfs()</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      return m_ul_tbfs;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-inline LListHead<gprs_rlcmac_tbf>& BTS::dl_tbfs()</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  return m_dl_tbfs;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-inline struct rate_ctr_group *BTS::rate_counters() const</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     return m_ratectrs;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-inline struct osmo_stat_item_group *BTS::stat_items() const</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- return m_statg;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-inline void BTS::do_rate_ctr_inc(unsigned int ctr_id) {</span><br><span style="color: hsl(0, 100%, 40%);">- rate_ctr_inc(&m_ratectrs->ctr[ctr_id]);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-inline void BTS::do_rate_ctr_add(unsigned int ctr_id, int inc) {</span><br><span style="color: hsl(0, 100%, 40%);">- rate_ctr_add(&m_ratectrs->ctr[ctr_id], inc);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-inline void BTS::stat_item_add(unsigned int stat_id, int inc) {</span><br><span style="color: hsl(0, 100%, 40%);">-     int32_t val = osmo_stat_item_get_last(m_statg->items[stat_id]);</span><br><span style="color: hsl(0, 100%, 40%);">-      osmo_stat_item_set(m_statg->items[stat_id], val + inc);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct gprs_pcu;</span><br><span style="color: hsl(0, 100%, 40%);">-struct BTS* bts_alloc(struct gprs_pcu *pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> #ifdef __cplusplus</span><br><span> extern "C" {</span><br><span> #endif</span><br><span style="color: hsl(0, 100%, 40%);">- void bts_cleanup();</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gprs_rlcmac_bts *bts_data(struct BTS *bts);</span><br><span style="color: hsl(0, 100%, 40%);">-      struct gprs_rlcmac_bts *bts_main_data();</span><br><span style="color: hsl(0, 100%, 40%);">-        struct rate_ctr_group *bts_main_data_stats();</span><br><span style="color: hsl(0, 100%, 40%);">-   struct osmo_stat_item_group *bts_main_data_stat_items();</span><br><span style="color: hsl(0, 100%, 40%);">-        void bts_recalc_initial_cs(struct gprs_rlcmac_bts *bts);</span><br><span style="color: hsl(0, 100%, 40%);">-        void bts_recalc_initial_mcs(struct gprs_rlcmac_bts *bts);</span><br><span style="color: hsl(0, 100%, 40%);">-       void bts_recalc_max_cs(struct gprs_rlcmac_bts *bts);</span><br><span style="color: hsl(0, 100%, 40%);">-    void bts_recalc_max_mcs(struct gprs_rlcmac_bts *bts);</span><br><span style="color: hsl(0, 100%, 40%);">-   struct GprsMs *bts_ms_by_imsi(struct BTS *bts, const char *imsi);</span><br><span style="color: hsl(0, 100%, 40%);">-       uint8_t bts_max_cs_dl(const struct BTS *bts);</span><br><span style="color: hsl(0, 100%, 40%);">-   uint8_t bts_max_cs_ul(const struct BTS *bts);</span><br><span style="color: hsl(0, 100%, 40%);">-   uint8_t bts_max_mcs_dl(const struct BTS *bts);</span><br><span style="color: hsl(0, 100%, 40%);">-  uint8_t bts_max_mcs_ul(const struct BTS *bts);</span><br><span style="color: hsl(0, 100%, 40%);">-#ifdef __cplusplus</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct GprsMs *bts_alloc_ms(struct gprs_rlcmac_bts *bts, uint8_t ms_class, uint8_t egprs_ms_class);</span><br><span style="color: hsl(120, 100%, 40%);">+int bts_add_paging(struct gprs_rlcmac_bts *bts, uint8_t chan_needed, const struct osmo_mobile_identity *mi);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+uint32_t bts_rfn_to_fn(const struct gprs_rlcmac_bts *bts, int32_t rfn);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlcmac_dl_tbf *bts_dl_tbf_by_poll_fn(struct gprs_rlcmac_bts *bts, uint32_t fn, uint8_t trx, uint8_t ts);</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlcmac_ul_tbf *bts_ul_tbf_by_poll_fn(struct gprs_rlcmac_bts *bts, uint32_t fn, uint8_t trx, uint8_t ts);</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlcmac_dl_tbf *bts_dl_tbf_by_tfi(struct gprs_rlcmac_bts *bts, uint8_t tfi, uint8_t trx, uint8_t ts);</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlcmac_ul_tbf *bts_ul_tbf_by_tfi(struct gprs_rlcmac_bts *bts, uint8_t tfi, uint8_t trx, uint8_t ts);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_snd_dl_ass(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *tbf, bool poll, uint16_t pgroup);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/** TODO: change the number to unsigned */</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_set_current_frame_number(struct gprs_rlcmac_bts *bts, int frame_number);</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_set_current_block_frame_number(struct gprs_rlcmac_bts *bts, int frame_number, unsigned max_delay);</span><br><span style="color: hsl(120, 100%, 40%);">+static inline int bts_current_frame_number(const struct gprs_rlcmac_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      return bts->cur_fn;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+int bts_tfi_find_free(const struct gprs_rlcmac_bts *bts, enum gprs_rlcmac_tbf_direction dir,</span><br><span style="color: hsl(120, 100%, 40%);">+               uint8_t *_trx, int8_t use_trx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int bts_rcv_rach(struct gprs_rlcmac_bts *bts, const struct rach_ind_params *rip);</span><br><span style="color: hsl(120, 100%, 40%);">+int bts_rcv_ptcch_rach(struct gprs_rlcmac_bts *bts, const struct rach_ind_params *rip);</span><br><span style="color: hsl(120, 100%, 40%);">+int bts_rcv_imm_ass_cnf(struct gprs_rlcmac_bts *bts, const uint8_t *data, uint32_t fn);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_send_gsmtap(struct gprs_rlcmac_bts *bts,</span><br><span style="color: hsl(120, 100%, 40%);">+                  enum pcu_gsmtap_category categ, bool uplink, uint8_t trx_no,</span><br><span style="color: hsl(120, 100%, 40%);">+                  uint8_t ts_no, uint8_t channel, uint32_t fn,</span><br><span style="color: hsl(120, 100%, 40%);">+                  const uint8_t *data, unsigned int len);</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_send_gsmtap_meas(struct gprs_rlcmac_bts *bts,</span><br><span style="color: hsl(120, 100%, 40%);">+                    enum pcu_gsmtap_category categ, bool uplink, uint8_t trx_no,</span><br><span style="color: hsl(120, 100%, 40%);">+                          uint8_t ts_no, uint8_t channel, uint32_t fn,</span><br><span style="color: hsl(120, 100%, 40%);">+                          const uint8_t *data, unsigned int len, struct pcu_l1_meas *meas);</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_send_gsmtap_rach(struct gprs_rlcmac_bts *bts,</span><br><span style="color: hsl(120, 100%, 40%);">+                     enum pcu_gsmtap_category categ, uint8_t channel,</span><br><span style="color: hsl(120, 100%, 40%);">+                      const struct rach_ind_params *rip);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct SBAController *bts_sba(struct gprs_rlcmac_bts *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct GprsMsStorage *bts_ms_store(struct gprs_rlcmac_bts *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct GprsMs *bts_ms_by_tlli(struct gprs_rlcmac_bts *bts, uint32_t tlli, uint32_t old_tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static inline struct rate_ctr_group *bts_rate_counters(struct gprs_rlcmac_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   return bts->ratectrs;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static inline struct osmo_stat_item_group *bts_stat_items(struct gprs_rlcmac_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      return bts->statg;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static inline void bts_do_rate_ctr_inc(struct gprs_rlcmac_bts *bts, unsigned int ctr_id) {</span><br><span style="color: hsl(120, 100%, 40%);">+        rate_ctr_inc(&bts->ratectrs->ctr[ctr_id]);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static inline void bts_do_rate_ctr_add(struct gprs_rlcmac_bts *bts, unsigned int ctr_id, int inc) {</span><br><span style="color: hsl(120, 100%, 40%);">+        rate_ctr_add(&bts->ratectrs->ctr[ctr_id], inc);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static inline void bts_stat_item_add(struct gprs_rlcmac_bts *bts, unsigned int stat_id, int inc) {</span><br><span style="color: hsl(120, 100%, 40%);">+    int32_t val = osmo_stat_item_get_last(bts->statg->items[stat_id]);</span><br><span style="color: hsl(120, 100%, 40%);">+      osmo_stat_item_set(bts->statg->items[stat_id], val + inc);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlcmac_bts *bts_alloc(struct gprs_pcu *pcu);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlcmac_bts *bts_main_data();</span><br><span style="color: hsl(120, 100%, 40%);">+struct rate_ctr_group *bts_main_data_stats();</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_stat_item_group *bts_main_data_stat_items();</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_recalc_initial_cs(struct gprs_rlcmac_bts *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_recalc_initial_mcs(struct gprs_rlcmac_bts *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_recalc_max_cs(struct gprs_rlcmac_bts *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_recalc_max_mcs(struct gprs_rlcmac_bts *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+struct GprsMs *bts_ms_by_imsi(struct gprs_rlcmac_bts *bts, const char *imsi);</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t bts_max_cs_dl(const struct gprs_rlcmac_bts *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t bts_max_cs_ul(const struct gprs_rlcmac_bts *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t bts_max_mcs_dl(const struct gprs_rlcmac_bts *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t bts_max_mcs_ul(const struct gprs_rlcmac_bts *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_set_max_cs_dl(struct gprs_rlcmac_bts *bts, uint8_t cs_dl);</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_set_max_cs_ul(struct gprs_rlcmac_bts *bts, uint8_t cs_ul);</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_set_max_mcs_dl(struct gprs_rlcmac_bts *bts, uint8_t mcs_dl);</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_set_max_mcs_ul(struct gprs_rlcmac_bts *bts, uint8_t mcs_ul);</span><br><span style="color: hsl(120, 100%, 40%);">+bool bts_cs_dl_is_supported(const struct gprs_rlcmac_bts *bts, enum CodingScheme cs);</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef __cplusplus</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span> #endif</span><br><span>diff --git a/src/encoding.cpp b/src/encoding.cpp</span><br><span>index e7b1fb4..f605ca2 100644</span><br><span>--- a/src/encoding.cpp</span><br><span>+++ b/src/encoding.cpp</span><br><span>@@ -24,6 +24,7 @@</span><br><span> #include <bts.h></span><br><span> #include <tbf.h></span><br><span> #include <tbf_ul.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <tbf_dl.h></span><br><span> #include <gprs_debug.h></span><br><span> #include <egprs_rlc_compression.h></span><br><span> </span><br><span>diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp</span><br><span>index 1596d67..92fa845 100644</span><br><span>--- a/src/gprs_bssgp_pcu.cpp</span><br><span>+++ b/src/gprs_bssgp_pcu.cpp</span><br><span>@@ -34,6 +34,7 @@</span><br><span>   #include <osmocom/core/utils.h></span><br><span>        #include <osmocom/gsm/gsm48.h></span><br><span>         #include "coding_scheme.h"</span><br><span style="color: hsl(120, 100%, 40%);">+  #include "tbf_dl.h"</span><br><span> }</span><br><span> </span><br><span> /* Tuning parameters for BSSGP flow control */</span><br><span>@@ -208,7 +209,7 @@</span><br><span>       if ((rc = get_paging_mi(&mi, tp)) > 0)</span><br><span>                return bssgp_tx_status((enum gprs_bssgp_cause) rc, NULL, msg);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      return BTS::main_bts()->add_paging(tlvp_val8(tp, BSSGP_IE_CHAN_NEEDED, 0), &mi);</span><br><span style="color: hsl(120, 100%, 40%);">+       return bts_add_paging(the_pcu->bts, tlvp_val8(tp, BSSGP_IE_CHAN_NEEDED, 0), &mi);</span><br><span> }</span><br><span> </span><br><span> static int gprs_bssgp_pcu_rx_paging_ps(struct msgb *msg, const struct tlv_parsed *tp)</span><br><span>@@ -761,8 +762,8 @@</span><br><span>                     } else {</span><br><span>                             /* We found "num" for free in the loop above */</span><br><span>                    }</span><br><span style="color: hsl(0, 100%, 40%);">-               } else if (bts->bts->max_mcs_dl()) {</span><br><span style="color: hsl(0, 100%, 40%);">-                      num = bts->bts->max_mcs_dl();</span><br><span style="color: hsl(120, 100%, 40%);">+           } else if (bts_max_mcs_dl(bts)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     num = bts_max_mcs_dl(bts);</span><br><span>           } else {</span><br><span>                     num = 9;</span><br><span>             }</span><br><span>@@ -782,8 +783,8 @@</span><br><span>                              }</span><br><span>                    }</span><br><span>            }</span><br><span style="color: hsl(0, 100%, 40%);">-       } else if (bts->bts->max_cs_dl()) {</span><br><span style="color: hsl(0, 100%, 40%);">-               num = bts->bts->max_cs_dl();</span><br><span style="color: hsl(120, 100%, 40%);">+    } else if (bts_max_cs_dl(bts)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              num = bts_max_cs_dl(bts);</span><br><span>    }</span><br><span> </span><br><span>        if (!num)</span><br><span>diff --git a/src/gprs_ms.c b/src/gprs_ms.c</span><br><span>index 9d303d6..ea497a3 100644</span><br><span>--- a/src/gprs_ms.c</span><br><span>+++ b/src/gprs_ms.c</span><br><span>@@ -91,7 +91,7 @@</span><br><span> }</span><br><span> </span><br><span> static int ms_talloc_destructor(struct GprsMs *ms);</span><br><span style="color: hsl(0, 100%, 40%);">-struct GprsMs *ms_alloc(struct BTS *bts, uint32_t tlli)</span><br><span style="color: hsl(120, 100%, 40%);">+struct GprsMs *ms_alloc(struct gprs_rlcmac_bts *bts, uint32_t tlli)</span><br><span> {</span><br><span>      struct GprsMs *ms = talloc_zero(tall_pcu_ctx, struct GprsMs);</span><br><span> </span><br><span>@@ -249,13 +249,13 @@</span><br><span>    case GPRS:</span><br><span>           if (!mcs_is_gprs(ms->current_cs_ul)) {</span><br><span>                    ms->current_cs_ul = mcs_get_gprs_by_num(</span><br><span style="color: hsl(0, 100%, 40%);">-                             bts_data(ms->bts)->initial_cs_ul);</span><br><span style="color: hsl(120, 100%, 40%);">+                              ms->bts->initial_cs_ul);</span><br><span>                       if (!mcs_is_valid(ms->current_cs_ul))</span><br><span>                             ms->current_cs_ul = CS1;</span><br><span>          }</span><br><span>            if (!mcs_is_gprs(ms->current_cs_dl)) {</span><br><span>                    ms->current_cs_dl = mcs_get_gprs_by_num(</span><br><span style="color: hsl(0, 100%, 40%);">-                             bts_data(ms->bts)->initial_cs_dl);</span><br><span style="color: hsl(120, 100%, 40%);">+                              ms->bts->initial_cs_dl);</span><br><span>                       if (!mcs_is_valid(ms->current_cs_dl))</span><br><span>                             ms->current_cs_dl = CS1;</span><br><span>          }</span><br><span>@@ -265,13 +265,13 @@</span><br><span>    case EGPRS:</span><br><span>          if (!mcs_is_edge(ms->current_cs_ul)) {</span><br><span>                    ms->current_cs_ul = mcs_get_egprs_by_num(</span><br><span style="color: hsl(0, 100%, 40%);">-                            bts_data(ms->bts)->initial_mcs_ul);</span><br><span style="color: hsl(120, 100%, 40%);">+                             ms->bts->initial_mcs_ul);</span><br><span>                      if (!mcs_is_valid(ms->current_cs_ul))</span><br><span>                             ms->current_cs_ul = MCS1;</span><br><span>                 }</span><br><span>            if (!mcs_is_edge(ms->current_cs_dl)) {</span><br><span>                    ms->current_cs_dl = mcs_get_egprs_by_num(</span><br><span style="color: hsl(0, 100%, 40%);">-                            bts_data(ms->bts)->initial_mcs_dl);</span><br><span style="color: hsl(120, 100%, 40%);">+                             ms->bts->initial_mcs_dl);</span><br><span>                      if (!mcs_is_valid(ms->current_cs_dl))</span><br><span>                             ms->current_cs_dl = MCS1;</span><br><span>                 }</span><br><span>diff --git a/src/gprs_ms.h b/src/gprs_ms.h</span><br><span>index 6391f72..12809f1 100644</span><br><span>--- a/src/gprs_ms.h</span><br><span>+++ b/src/gprs_ms.h</span><br><span>@@ -49,7 +49,7 @@</span><br><span>       MS_CTR_DL_CTRL_MSG_SCHED,</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct BTS;</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlcmac_bts;</span><br><span> struct gprs_rlcmac_trx;</span><br><span> struct GprsMs;</span><br><span> </span><br><span>@@ -63,7 +63,7 @@</span><br><span>         struct gpr_ms_callback cb;</span><br><span>   bool app_info_pending;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      struct BTS *bts;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gprs_rlcmac_bts *bts;</span><br><span>         struct gprs_rlcmac_ul_tbf *ul_tbf;</span><br><span>   struct gprs_rlcmac_dl_tbf *dl_tbf;</span><br><span>   struct llist_head old_tbfs; /* list of gprs_rlcmac_tbf */</span><br><span>@@ -102,7 +102,7 @@</span><br><span>      struct rate_ctr_group *ctrs;</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct GprsMs *ms_alloc(struct BTS *bts, uint32_t tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+struct GprsMs *ms_alloc(struct gprs_rlcmac_bts *bts, uint32_t tlli);</span><br><span> </span><br><span> int ms_first_common_ts(const struct GprsMs *ms);</span><br><span> void ms_set_reserved_slots(struct GprsMs *ms, struct gprs_rlcmac_trx *trx,</span><br><span>diff --git a/src/gprs_ms_storage.cpp b/src/gprs_ms_storage.cpp</span><br><span>index 6d5b09e..6245ed9 100644</span><br><span>--- a/src/gprs_ms_storage.cpp</span><br><span>+++ b/src/gprs_ms_storage.cpp</span><br><span>@@ -35,7 +35,7 @@</span><br><span> {</span><br><span>         llist_del(&ms->list);</span><br><span>         if (ms->bts)</span><br><span style="color: hsl(0, 100%, 40%);">-         ms->bts->stat_item_add(STAT_MS_PRESENT, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+            bts_stat_item_add(ms->bts, STAT_MS_PRESENT, -1);</span><br><span>  if (ms_is_idle(ms))</span><br><span>          talloc_free(ms);</span><br><span> }</span><br><span>@@ -50,7 +50,7 @@</span><br><span>    .ms_active = ms_storage_ms_active_cb,</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-GprsMsStorage::GprsMsStorage(BTS *bts) :</span><br><span style="color: hsl(120, 100%, 40%);">+GprsMsStorage::GprsMsStorage(struct gprs_rlcmac_bts *bts) :</span><br><span>         m_bts(bts)</span><br><span> {</span><br><span>      INIT_LLIST_HEAD(&m_list);</span><br><span>@@ -109,7 +109,7 @@</span><br><span>  ms_set_callback(ms, &ms_storage_ms_cb);</span><br><span>  llist_add(&ms->list, &m_list);</span><br><span>    if (m_bts)</span><br><span style="color: hsl(0, 100%, 40%);">-              m_bts->stat_item_add(STAT_MS_PRESENT, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+          bts_stat_item_add(m_bts, STAT_MS_PRESENT, 1);</span><br><span> </span><br><span>    return ms;</span><br><span> }</span><br><span>diff --git a/src/gprs_ms_storage.h b/src/gprs_ms_storage.h</span><br><span>index af49688..dcb6d8d 100644</span><br><span>--- a/src/gprs_ms_storage.h</span><br><span>+++ b/src/gprs_ms_storage.h</span><br><span>@@ -25,11 +25,11 @@</span><br><span> #include <stdint.h></span><br><span> #include <stddef.h></span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct BTS;</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlcmac_bts;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-class GprsMsStorage {</span><br><span style="color: hsl(120, 100%, 40%);">+struct GprsMsStorage {</span><br><span> public:</span><br><span style="color: hsl(0, 100%, 40%);">-    GprsMsStorage(BTS *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+      GprsMsStorage(struct gprs_rlcmac_bts *bts);</span><br><span>  ~GprsMsStorage();</span><br><span> </span><br><span>        void cleanup();</span><br><span>@@ -39,6 +39,6 @@</span><br><span> </span><br><span>      const struct llist_head* ms_list() const {return &m_list;}</span><br><span> private:</span><br><span style="color: hsl(0, 100%, 40%);">-      BTS *m_bts;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct gprs_rlcmac_bts *m_bts;</span><br><span>       struct llist_head m_list; /* list of struct GprsMs */</span><br><span> };</span><br><span>diff --git a/src/gprs_pcu.c b/src/gprs_pcu.c</span><br><span>index bc9b350..b280652 100644</span><br><span>--- a/src/gprs_pcu.c</span><br><span>+++ b/src/gprs_pcu.c</span><br><span>@@ -109,8 +109,7 @@</span><br><span>       the_pcu->vty.initial_cs_ul = cs_ul;</span><br><span> </span><br><span>   /*TODO: once we support multiple bts, foreach(bts) apply */</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gprs_rlcmac_bts *bts = bts_data(pcu->bts);</span><br><span style="color: hsl(0, 100%, 40%);">-    bts_recalc_initial_cs(bts);</span><br><span style="color: hsl(120, 100%, 40%);">+   bts_recalc_initial_cs(pcu->bts);</span><br><span> }</span><br><span> void gprs_pcu_set_initial_mcs(struct gprs_pcu *pcu, uint8_t mcs_dl, uint8_t mcs_ul)</span><br><span> {</span><br><span>@@ -118,8 +117,7 @@</span><br><span>   the_pcu->vty.initial_mcs_ul = mcs_ul;</span><br><span> </span><br><span>         /*TODO: once we support multiple bts, foreach(bts) apply */</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gprs_rlcmac_bts *bts = bts_data(pcu->bts);</span><br><span style="color: hsl(0, 100%, 40%);">-    bts_recalc_initial_mcs(bts);</span><br><span style="color: hsl(120, 100%, 40%);">+  bts_recalc_initial_mcs(pcu->bts);</span><br><span> }</span><br><span> </span><br><span> void gprs_pcu_set_max_cs(struct gprs_pcu *pcu, uint8_t cs_dl, uint8_t cs_ul)</span><br><span>@@ -127,14 +125,12 @@</span><br><span>        the_pcu->vty.max_cs_dl = cs_dl;</span><br><span>   the_pcu->vty.max_cs_ul = cs_ul;</span><br><span>   /*TODO: once we support multiple bts, foreach(bts) apply */</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gprs_rlcmac_bts *bts = bts_data(pcu->bts);</span><br><span style="color: hsl(0, 100%, 40%);">-    bts_recalc_max_cs(bts);</span><br><span style="color: hsl(120, 100%, 40%);">+       bts_recalc_max_cs(pcu->bts);</span><br><span> }</span><br><span> void gprs_pcu_set_max_mcs(struct gprs_pcu *pcu, uint8_t mcs_dl, uint8_t mcs_ul)</span><br><span> {</span><br><span>         the_pcu->vty.max_mcs_dl = mcs_dl;</span><br><span>         the_pcu->vty.max_mcs_ul = mcs_ul;</span><br><span>         /* TODO: once we support multiple bts, foreach(bts) apply */</span><br><span style="color: hsl(0, 100%, 40%);">-    struct gprs_rlcmac_bts *bts = bts_data(pcu->bts);</span><br><span style="color: hsl(0, 100%, 40%);">-    bts_recalc_max_mcs(bts);</span><br><span style="color: hsl(120, 100%, 40%);">+      bts_recalc_max_mcs(pcu->bts);</span><br><span> }</span><br><span>diff --git a/src/gprs_pcu.h b/src/gprs_pcu.h</span><br><span>index 8913001..37f6e07 100644</span><br><span>--- a/src/gprs_pcu.h</span><br><span>+++ b/src/gprs_pcu.h</span><br><span>@@ -55,7 +55,6 @@</span><br><span>       PCU_GSMTAP_C_UL_PTCCH           = 21,   /* uplink PTCCH bursts */</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct BTS;</span><br><span> struct gprs_rlcmac_bts;</span><br><span> struct GprsMs;</span><br><span> struct gprs_rlcmac_tbf;</span><br><span>@@ -108,7 +107,7 @@</span><br><span>         struct gsmtap_inst *gsmtap;</span><br><span>  uint32_t gsmtap_categ_mask;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- struct BTS *bts;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gprs_rlcmac_bts *bts;</span><br><span> </span><br><span>     struct gprs_ns2_inst *nsi;</span><br><span> </span><br><span>diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp</span><br><span>index b5709c9..39e22c0 100644</span><br><span>--- a/src/gprs_rlcmac_sched.cpp</span><br><span>+++ b/src/gprs_rlcmac_sched.cpp</span><br><span>@@ -41,13 +41,13 @@</span><br><span>        struct gprs_rlcmac_ul_tbf *ul_ack;</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static uint32_t sched_poll(BTS *bts,</span><br><span style="color: hsl(120, 100%, 40%);">+static uint32_t sched_poll(struct gprs_rlcmac_bts *bts,</span><br><span>                uint8_t trx, uint8_t ts, uint32_t fn, uint8_t block_nr,</span><br><span>              struct tbf_sched_candidates *tbf_cand)</span><br><span> {</span><br><span>      struct gprs_rlcmac_ul_tbf *ul_tbf;</span><br><span>   struct gprs_rlcmac_dl_tbf *dl_tbf;</span><br><span style="color: hsl(0, 100%, 40%);">-      LListHead<gprs_rlcmac_tbf> *pos;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct llist_item *pos;</span><br><span>      uint32_t poll_fn;</span><br><span> </span><br><span>        /* check special TBF for events */</span><br><span>@@ -55,8 +55,8 @@</span><br><span>       if ((block_nr % 3) == 2)</span><br><span>             poll_fn ++;</span><br><span>  poll_fn = poll_fn % GSM_MAX_FN;</span><br><span style="color: hsl(0, 100%, 40%);">- llist_for_each(pos, &bts->ul_tbfs()) {</span><br><span style="color: hsl(0, 100%, 40%);">-           ul_tbf = as_ul_tbf(pos->entry());</span><br><span style="color: hsl(120, 100%, 40%);">+  llist_for_each_entry(pos, &bts->ul_tbfs, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+               ul_tbf = as_ul_tbf((struct gprs_rlcmac_tbf *)pos->entry);</span><br><span>                 OSMO_ASSERT(ul_tbf);</span><br><span>                 /* this trx, this ts */</span><br><span>              if (ul_tbf->trx->trx_no != trx || !ul_tbf->is_control_ts(ts))</span><br><span>@@ -74,8 +74,8 @@</span><br><span> /* FIXME: Is this supposed to be fair? The last TBF for each wins? Maybe use llist_add_tail and skip once we have all</span><br><span> states? */</span><br><span>    }</span><br><span style="color: hsl(0, 100%, 40%);">-       llist_for_each(pos, &bts->dl_tbfs()) {</span><br><span style="color: hsl(0, 100%, 40%);">-           dl_tbf = as_dl_tbf(pos->entry());</span><br><span style="color: hsl(120, 100%, 40%);">+  llist_for_each_entry(pos, &bts->dl_tbfs, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+               dl_tbf = as_dl_tbf((struct gprs_rlcmac_tbf *)pos->entry);</span><br><span>                 OSMO_ASSERT(dl_tbf);</span><br><span>                 /* this trx, this ts */</span><br><span>              if (dl_tbf->trx->trx_no != trx || !dl_tbf->is_control_ts(ts))</span><br><span>@@ -136,7 +136,7 @@</span><br><span>         if (!tbf || !tbf->ms()->app_info_pending)</span><br><span>              return NULL;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        bts_data = BTS::main_bts()->bts_data();</span><br><span style="color: hsl(120, 100%, 40%);">+    bts_data = the_pcu->bts;</span><br><span> </span><br><span>      if (bts_data->app_info) {</span><br><span>                 LOGP(DRLCMACSCHED, LOGL_DEBUG, "Sending Packet Application Information message\n");</span><br><span>@@ -367,7 +367,7 @@</span><br><span>  return msg;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static inline void tap_n_acc(const struct msgb *msg, const struct gprs_rlcmac_bts *bts, uint8_t trx, uint8_t ts,</span><br><span style="color: hsl(120, 100%, 40%);">+static inline void tap_n_acc(const struct msgb *msg, struct gprs_rlcmac_bts *bts, uint8_t trx, uint8_t ts,</span><br><span>                          uint32_t fn, enum pcu_gsmtap_category cat)</span><br><span> {</span><br><span>         if (!msg)</span><br><span>@@ -375,19 +375,19 @@</span><br><span> </span><br><span>        switch(cat) {</span><br><span>        case PCU_GSMTAP_C_DL_CTRL:</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->bts->do_rate_ctr_inc(CTR_RLC_SENT_CONTROL);</span><br><span style="color: hsl(0, 100%, 40%);">-          bts->bts->send_gsmtap(PCU_GSMTAP_C_DL_CTRL, false, trx, ts, GSMTAP_CHANNEL_PACCH, fn, msg->data,</span><br><span style="color: hsl(120, 100%, 40%);">+             bts_do_rate_ctr_inc(bts, CTR_RLC_SENT_CONTROL);</span><br><span style="color: hsl(120, 100%, 40%);">+               bts_send_gsmtap(bts, PCU_GSMTAP_C_DL_CTRL, false, trx, ts, GSMTAP_CHANNEL_PACCH, fn, msg->data,</span><br><span>                                 msg->len);</span><br><span>          break;</span><br><span>       case PCU_GSMTAP_C_DL_DATA_GPRS:</span><br><span>      case PCU_GSMTAP_C_DL_DATA_EGPRS:</span><br><span style="color: hsl(0, 100%, 40%);">-                bts->bts->do_rate_ctr_inc(CTR_RLC_SENT);</span><br><span style="color: hsl(0, 100%, 40%);">-          bts->bts->send_gsmtap(cat, false, trx, ts, GSMTAP_CHANNEL_PDTCH, fn, msg->data,</span><br><span style="color: hsl(120, 100%, 40%);">+              bts_do_rate_ctr_inc(bts, CTR_RLC_SENT);</span><br><span style="color: hsl(120, 100%, 40%);">+               bts_send_gsmtap(bts, cat, false, trx, ts, GSMTAP_CHANNEL_PDTCH, fn, msg->data,</span><br><span>                                  msg->len);</span><br><span>          break;</span><br><span>       case PCU_GSMTAP_C_DL_DUMMY:</span><br><span style="color: hsl(0, 100%, 40%);">-             bts->bts->do_rate_ctr_inc(CTR_RLC_SENT_DUMMY);</span><br><span style="color: hsl(0, 100%, 40%);">-            bts->bts->send_gsmtap(PCU_GSMTAP_C_DL_DUMMY, false, trx, ts, GSMTAP_CHANNEL_PACCH, fn, msg->data,</span><br><span style="color: hsl(120, 100%, 40%);">+            bts_do_rate_ctr_inc(bts, CTR_RLC_SENT_DUMMY);</span><br><span style="color: hsl(120, 100%, 40%);">+         bts_send_gsmtap(bts, PCU_GSMTAP_C_DL_DUMMY, false, trx, ts, GSMTAP_CHANNEL_PACCH, fn, msg->data,</span><br><span>                                msg->len);</span><br><span>          break;</span><br><span>       default:</span><br><span>@@ -438,7 +438,7 @@</span><br><span>               req_mcs_kind = EGPRS; /* all kinds are fine */</span><br><span>       }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   poll_fn = sched_poll(bts->bts, trx, ts, fn, block_nr, &tbf_cand);</span><br><span style="color: hsl(120, 100%, 40%);">+      poll_fn = sched_poll(bts, trx, ts, fn, block_nr, &tbf_cand);</span><br><span>     /* check uplink resource for polling */</span><br><span>      if (tbf_cand.poll) {</span><br><span>                 LOGP(DRLCMACSCHED, LOGL_DEBUG, "Received RTS for PDCH: TRX=%d "</span><br><span>@@ -447,7 +447,7 @@</span><br><span>                      block_nr, poll_fn, tbf_name(tbf_cand.poll));</span><br><span>                 usf = USF_UNUSED;</span><br><span>    /* else. check for sba */</span><br><span style="color: hsl(0, 100%, 40%);">-       } else if ((sba_fn = bts->bts->sba()->sched(trx, ts, fn, block_nr)) != 0xffffffff) {</span><br><span style="color: hsl(120, 100%, 40%);">+} else if ((sba_fn = bts_sba(bts)->sched(trx, ts, fn, block_nr)) != 0xffffffff) {</span><br><span>          LOGP(DRLCMACSCHED, LOGL_DEBUG, "Received RTS for PDCH: TRX=%d "</span><br><span>                    "TS=%d FN=%d block_nr=%d scheduling free USF for "</span><br><span>                         "single block allocation at FN=%d\n", trx, ts, fn,</span><br><span>@@ -493,7 +493,7 @@</span><br><span>   }</span><br><span> </span><br><span>        /* msg is now available */</span><br><span style="color: hsl(0, 100%, 40%);">-      bts->bts->do_rate_ctr_add(CTR_RLC_DL_BYTES, msg->data_len);</span><br><span style="color: hsl(120, 100%, 40%);">+  bts_do_rate_ctr_add(bts, CTR_RLC_DL_BYTES, msg->data_len);</span><br><span> </span><br><span>    /* set USF */</span><br><span>        OSMO_ASSERT(msgb_length(msg) > 0);</span><br><span>diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp</span><br><span>index 7c2e828..f8b1c1f 100644</span><br><span>--- a/src/gprs_rlcmac_ts_alloc.cpp</span><br><span>+++ b/src/gprs_rlcmac_ts_alloc.cpp</span><br><span>@@ -305,7 +305,7 @@</span><br><span>  *  \param[out] trx_no_ TRX number on which TFI was found</span><br><span>  *  \returns negative error code or 0 on success</span><br><span>  */</span><br><span style="color: hsl(0, 100%, 40%);">-static int tfi_find_free(const BTS *bts, const gprs_rlcmac_trx *trx, const GprsMs *ms,</span><br><span style="color: hsl(120, 100%, 40%);">+static int tfi_find_free(const struct gprs_rlcmac_bts *bts, const gprs_rlcmac_trx *trx, const GprsMs *ms,</span><br><span>                     enum gprs_rlcmac_tbf_direction dir, int8_t use_trx, uint8_t *trx_no_)</span><br><span> {</span><br><span>  int tfi;</span><br><span>@@ -323,7 +323,7 @@</span><br><span>       if (use_trx == -1 && ms_current_trx(ms))</span><br><span>             use_trx = ms_current_trx(ms)->trx_no;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    tfi = bts->tfi_find_free(dir, &trx_no, use_trx);</span><br><span style="color: hsl(120, 100%, 40%);">+       tfi = bts_tfi_find_free(bts, dir, &trx_no, use_trx);</span><br><span>     if (tfi < 0)</span><br><span>              return -EBUSY;</span><br><span> </span><br><span>@@ -423,7 +423,7 @@</span><br><span>     ms_set_reserved_slots(ms_, trx, 1 << ts, 1 << ts);</span><br><span> </span><br><span>   tbf_->upgrade_to_multislot = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-      bts->bts->do_rate_ctr_inc(CTR_TBF_ALLOC_ALGO_A);</span><br><span style="color: hsl(120, 100%, 40%);">+        bts_do_rate_ctr_inc(bts, CTR_TBF_ALLOC_ALGO_A);</span><br><span>      return 0;</span><br><span> }</span><br><span> </span><br><span>@@ -888,7 +888,7 @@</span><br><span>     trx = ms_current_trx(ms);</span><br><span> </span><br><span>        /* Step 2a: Find usable TRX and TFI */</span><br><span style="color: hsl(0, 100%, 40%);">-  tfi = tfi_find_free(bts->bts, trx, ms, tbf->direction, use_trx, &trx_no);</span><br><span style="color: hsl(120, 100%, 40%);">+   tfi = tfi_find_free(bts, trx, ms, tbf->direction, use_trx, &trx_no);</span><br><span>  if (tfi < 0) {</span><br><span>            LOGPAL(tbf, "B", single, use_trx, LOGL_NOTICE, "failed to allocate a TFI\n");</span><br><span>            return tfi;</span><br><span>@@ -966,7 +966,7 @@</span><br><span>    else</span><br><span>                 assign_ul_tbf_slots(as_ul_tbf(tbf_), trx, ul_slots, tfi, usf);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      bts->bts->do_rate_ctr_inc(CTR_TBF_ALLOC_ALGO_B);</span><br><span style="color: hsl(120, 100%, 40%);">+        bts_do_rate_ctr_inc(bts, CTR_TBF_ALLOC_ALGO_B);</span><br><span> </span><br><span>  return 0;</span><br><span> }</span><br><span>diff --git a/src/gsm_timer.cpp b/src/gsm_timer.cpp</span><br><span>index cefe520..0627753 100644</span><br><span>--- a/src/gsm_timer.cpp</span><br><span>+++ b/src/gsm_timer.cpp</span><br><span>@@ -16,7 +16,7 @@</span><br><span>  * along with this program; if not, write to the Free Software</span><br><span>  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.</span><br><span>  */</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* These store the amount of frame number that we wait until next timer expires. */</span><br><span> static int nearest;</span><br><span> static int *nearest_p;</span><br><span>@@ -45,7 +45,7 @@</span><br><span>  */</span><br><span> int get_current_fn()</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-       return BTS::main_bts()->current_frame_number();</span><br><span style="color: hsl(120, 100%, 40%);">+    return bts_current_frame_number(the_pcu->bts);</span><br><span> }</span><br><span> </span><br><span> static void __add_gsm_timer(struct osmo_gsm_timer_list *timer)</span><br><span>@@ -232,4 +232,3 @@</span><br><span> }</span><br><span> </span><br><span> /*! }@ */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>diff --git a/src/llc.cpp b/src/llc.cpp</span><br><span>index 51cb15a..470e154 100644</span><br><span>--- a/src/llc.cpp</span><br><span>+++ b/src/llc.cpp</span><br><span>@@ -122,13 +122,13 @@</span><br><span>    msgb_enqueue(&m_queue, llc_msg);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void llc_queue_clear(struct gprs_llc_queue *q, struct BTS *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+void llc_queue_clear(struct gprs_llc_queue *q, struct gprs_rlcmac_bts *bts)</span><br><span> {</span><br><span>       struct msgb *msg;</span><br><span> </span><br><span>        while ((msg = msgb_dequeue(&q->m_queue))) {</span><br><span>           if (bts)</span><br><span style="color: hsl(0, 100%, 40%);">-                        bts->do_rate_ctr_inc(CTR_LLC_FRAME_DROPPED);</span><br><span style="color: hsl(120, 100%, 40%);">+                       bts_do_rate_ctr_inc(bts, CTR_LLC_FRAME_DROPPED);</span><br><span>             msgb_free(msg);</span><br><span>      }</span><br><span> </span><br><span>@@ -221,7 +221,7 @@</span><br><span>  return msg;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void gprs_llc_queue::calc_pdu_lifetime(BTS *bts, const uint16_t pdu_delay_csec, struct timespec *tv)</span><br><span style="color: hsl(120, 100%, 40%);">+void gprs_llc_queue::calc_pdu_lifetime(struct gprs_rlcmac_bts *bts, const uint16_t pdu_delay_csec, struct timespec *tv)</span><br><span> {</span><br><span>       uint16_t delay_csec;</span><br><span>         if (bts->pcu->vty.force_llc_lifetime)</span><br><span>diff --git a/src/llc.h b/src/llc.h</span><br><span>index 72fa62e..13662d8 100644</span><br><span>--- a/src/llc.h</span><br><span>+++ b/src/llc.h</span><br><span>@@ -32,7 +32,7 @@</span><br><span> </span><br><span> #define LLC_MAX_LEN 1543</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct BTS;</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlcmac_bts;</span><br><span> </span><br><span> /**</span><br><span>  * I represent the LLC data to a MS</span><br><span>@@ -65,7 +65,7 @@</span><br><span>  */</span><br><span> struct gprs_llc_queue {</span><br><span> #ifdef __cplusplus</span><br><span style="color: hsl(0, 100%, 40%);">-  static void calc_pdu_lifetime(BTS *bts, const uint16_t pdu_delay_csec,</span><br><span style="color: hsl(120, 100%, 40%);">+        static void calc_pdu_lifetime(struct gprs_rlcmac_bts *bts, const uint16_t pdu_delay_csec,</span><br><span>            struct timespec *tv);</span><br><span>        static bool is_frame_expired(const struct timespec *now,</span><br><span>             const struct timespec *tv);</span><br><span>@@ -84,7 +84,7 @@</span><br><span> extern "C" {</span><br><span> #endif</span><br><span> void llc_queue_init(struct gprs_llc_queue *q);</span><br><span style="color: hsl(0, 100%, 40%);">-void llc_queue_clear(struct gprs_llc_queue *q, struct BTS *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+void llc_queue_clear(struct gprs_llc_queue *q, struct gprs_rlcmac_bts *bts);</span><br><span> void llc_queue_move_and_merge(struct gprs_llc_queue *q, struct gprs_llc_queue *o);</span><br><span> </span><br><span> static inline uint16_t llc_chunk_size(const struct gprs_llc *llc)</span><br><span>diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp</span><br><span>index a11ec7e..1a47b37 100644</span><br><span>--- a/src/pcu_l1_if.cpp</span><br><span>+++ b/src/pcu_l1_if.cpp</span><br><span>@@ -53,6 +53,7 @@</span><br><span> #include <pdch.h></span><br><span> #include <tbf_ul.h></span><br><span> #include <tbf_dl.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <gprs_ms_storage.h></span><br><span> </span><br><span> // FIXME: move this, when changed from c++ to c.</span><br><span> extern "C" {</span><br><span>@@ -271,13 +272,13 @@</span><br><span> </span><br><span> extern "C" void pcu_rx_block_time(uint16_t arfcn, uint32_t fn, uint8_t ts_no)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  BTS::main_bts()->set_current_block_frame_number(fn, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+    bts_set_current_block_frame_number(the_pcu->bts,fn, 0);</span><br><span> }</span><br><span> </span><br><span> extern "C" void pcu_rx_ra_time(uint16_t arfcn, uint32_t fn, uint8_t ts_no)</span><br><span> {</span><br><span>     /* access bursts may arrive some bursts earlier */</span><br><span style="color: hsl(0, 100%, 40%);">-      BTS::main_bts()->set_current_block_frame_number(fn, 5);</span><br><span style="color: hsl(120, 100%, 40%);">+    bts_set_current_block_frame_number(the_pcu->bts,fn, 5);</span><br><span> }</span><br><span> </span><br><span> extern "C" int pcu_rx_data_ind_pdtch(uint8_t trx_no, uint8_t ts_no, uint8_t *data,</span><br><span>@@ -368,7 +369,7 @@</span><br><span>    switch (data_cnf->sapi) {</span><br><span>         case PCU_IF_SAPI_PCH:</span><br><span>                if (data_cnf->data[2] == 0x3f)</span><br><span style="color: hsl(0, 100%, 40%);">-                       BTS::main_bts()->rcv_imm_ass_cnf(data_cnf->data, data_cnf->fn);</span><br><span style="color: hsl(120, 100%, 40%);">+                      bts_rcv_imm_ass_cnf(the_pcu->bts, data_cnf->data, data_cnf->fn);</span><br><span>            break;</span><br><span>       default:</span><br><span>             LOGP(DL1IF, LOGL_ERROR, "Received PCU data confirm with "</span><br><span>@@ -447,7 +448,7 @@</span><br><span>            .qta = qta,</span><br><span>  };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  return BTS::main_bts()->rcv_ptcch_rach(&rip);</span><br><span style="color: hsl(120, 100%, 40%);">+  return bts_rcv_ptcch_rach(the_pcu->bts, &rip);</span><br><span> }</span><br><span> </span><br><span> static int pcu_rx_rach_ind(const struct gsm_pcu_if_rach_ind *rach_ind)</span><br><span>@@ -471,10 +472,10 @@</span><br><span> </span><br><span>         switch (rach_ind->sapi) {</span><br><span>         case PCU_IF_SAPI_RACH:</span><br><span style="color: hsl(0, 100%, 40%);">-          rc = BTS::main_bts()->rcv_rach(&rip);</span><br><span style="color: hsl(120, 100%, 40%);">+          rc = bts_rcv_rach(the_pcu->bts, &rip);</span><br><span>                break;</span><br><span>       case PCU_IF_SAPI_PTCCH:</span><br><span style="color: hsl(0, 100%, 40%);">-         rc = BTS::main_bts()->rcv_ptcch_rach(&rip);</span><br><span style="color: hsl(120, 100%, 40%);">+            rc = bts_rcv_ptcch_rach(the_pcu->bts, &rip);</span><br><span>          break;</span><br><span>       default:</span><br><span>             LOGP(DL1IF, LOGL_ERROR, "Received PCU rach request with "</span><br><span>@@ -751,7 +752,7 @@</span><br><span> </span><br><span>        LOGP(DL1IF, LOGL_DEBUG, "Time indication received: %d\n", time_ind->fn % 52);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  BTS::main_bts()->set_current_frame_number(time_ind->fn);</span><br><span style="color: hsl(120, 100%, 40%);">+        bts_set_current_frame_number(the_pcu->bts, time_ind->fn);</span><br><span>      return 0;</span><br><span> }</span><br><span> </span><br><span>@@ -776,12 +777,12 @@</span><br><span>           return -EINVAL;</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   return BTS::main_bts()->add_paging(pag_req->chan_needed, &mi);</span><br><span style="color: hsl(120, 100%, 40%);">+      return bts_add_paging(the_pcu->bts, pag_req->chan_needed, &mi);</span><br><span> }</span><br><span> </span><br><span> static int pcu_rx_susp_req(struct gsm_pcu_if_susp_req *susp_req)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-     BTS *bts = BTS::main_bts();</span><br><span style="color: hsl(120, 100%, 40%);">+   struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       struct bssgp_bvc_ctx *bctx = gprs_bssgp_pcu_current_bctx();</span><br><span>  GprsMs *ms;</span><br><span>  struct gprs_rlcmac_dl_tbf *dl_tbf;</span><br><span>@@ -793,7 +794,7 @@</span><br><span>     LOGP(DL1IF, LOGL_INFO, "GPRS Suspend request received: TLLI=0x%08x RAI=%s\n",</span><br><span>              susp_req->tlli, osmo_rai_name(&ra_id));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      if ((ms = bts->ms_store().get_ms(susp_req->tlli))) {</span><br><span style="color: hsl(120, 100%, 40%);">+    if ((ms = bts_ms_store(bts)->get_ms(susp_req->tlli))) {</span><br><span>                /* We need to catch both pointers here since MS may become freed</span><br><span>                after first tbf_free(dl_tbf) if only DL TBF was available */</span><br><span>              dl_tbf = ms_dl_tbf(ms);</span><br><span>@@ -812,15 +813,15 @@</span><br><span> </span><br><span> static int pcu_rx_app_info_req(struct gsm_pcu_if_app_info_req *app_info_req)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-        BTS *bts = BTS::main_bts();</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gprs_rlcmac_bts *bts_data = bts->bts_data();</span><br><span style="color: hsl(120, 100%, 40%);">+        struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct gprs_rlcmac_bts *bts_data = bts;</span><br><span>      struct llist_head *tmp;</span><br><span> </span><br><span>  LOGP(DL1IF, LOGL_DEBUG, "Application Information Request received: type=0x%08x len=%i\n",</span><br><span>       app_info_req->application_type, app_info_req->len);</span><br><span> </span><br><span>   bts_data->app_info_pending = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-      llist_for_each(tmp, bts->ms_store().ms_list()) {</span><br><span style="color: hsl(120, 100%, 40%);">+   llist_for_each(tmp, bts_ms_store(bts)->ms_list()) {</span><br><span>               GprsMs *ms = llist_entry(tmp, typeof(*ms), list);</span><br><span>            if (!ms_dl_tbf(ms))</span><br><span>                  continue;</span><br><span>diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp</span><br><span>index e953d43..8bb7c1f 100644</span><br><span>--- a/src/pcu_main.cpp</span><br><span>+++ b/src/pcu_main.cpp</span><br><span>@@ -342,7 +342,7 @@</span><br><span> </span><br><span>     pcu_l1if_close();</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   bts_cleanup();</span><br><span style="color: hsl(120, 100%, 40%);">+        TALLOC_FREE(the_pcu);</span><br><span>        talloc_report_full(tall_pcu_ctx, stderr);</span><br><span>    talloc_free(tall_pcu_ctx);</span><br><span> </span><br><span>diff --git a/src/pcu_vty_functions.cpp b/src/pcu_vty_functions.cpp</span><br><span>index 0276b3e..0e9cc00 100644</span><br><span>--- a/src/pcu_vty_functions.cpp</span><br><span>+++ b/src/pcu_vty_functions.cpp</span><br><span>@@ -101,21 +101,23 @@</span><br><span>      vty_out(vty, "%s%s", VTY_NEWLINE, VTY_NEWLINE);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int pcu_vty_show_tbf_all(struct vty *vty, struct gprs_rlcmac_bts *bts_data, uint32_t flags)</span><br><span style="color: hsl(120, 100%, 40%);">+int pcu_vty_show_tbf_all(struct vty *vty, struct gprs_rlcmac_bts *bts, uint32_t flags)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      BTS *bts = bts_data->bts;</span><br><span style="color: hsl(0, 100%, 40%);">-    LListHead<gprs_rlcmac_tbf> *iter;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct llist_item *iter;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gprs_rlcmac_tbf *tbf;</span><br><span> </span><br><span>     vty_out(vty, "UL TBFs%s", VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-       llist_for_each(iter, &bts->ul_tbfs()) {</span><br><span style="color: hsl(0, 100%, 40%);">-          if (iter->entry()->state_flags & flags)</span><br><span style="color: hsl(0, 100%, 40%);">-                       tbf_print_vty_info(vty, iter->entry());</span><br><span style="color: hsl(120, 100%, 40%);">+    llist_for_each_entry(iter, &bts->ul_tbfs, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+              tbf = (struct gprs_rlcmac_tbf *)iter->entry;</span><br><span style="color: hsl(120, 100%, 40%);">+               if (tbf->state_flags & flags)</span><br><span style="color: hsl(120, 100%, 40%);">+                  tbf_print_vty_info(vty, tbf);</span><br><span>        }</span><br><span> </span><br><span>        vty_out(vty, "%sDL TBFs%s", VTY_NEWLINE, VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-        llist_for_each(iter, &bts->dl_tbfs()) {</span><br><span style="color: hsl(0, 100%, 40%);">-          if (iter->entry()->state_flags & flags)</span><br><span style="color: hsl(0, 100%, 40%);">-                       tbf_print_vty_info(vty, iter->entry());</span><br><span style="color: hsl(120, 100%, 40%);">+    llist_for_each_entry(iter, &bts->dl_tbfs, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+              tbf = (struct gprs_rlcmac_tbf *)iter->entry;</span><br><span style="color: hsl(120, 100%, 40%);">+               if (tbf->state_flags & flags)</span><br><span style="color: hsl(120, 100%, 40%);">+                  tbf_print_vty_info(vty, tbf);</span><br><span>        }</span><br><span> </span><br><span>        return CMD_SUCCESS;</span><br><span>@@ -204,12 +206,11 @@</span><br><span>  return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int pcu_vty_show_ms_all(struct vty *vty, struct gprs_rlcmac_bts *bts_data)</span><br><span style="color: hsl(120, 100%, 40%);">+int pcu_vty_show_ms_all(struct vty *vty, struct gprs_rlcmac_bts *bts)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      BTS *bts = bts_data->bts;</span><br><span>         struct llist_head *tmp;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     llist_for_each(tmp, bts->ms_store().ms_list()) {</span><br><span style="color: hsl(120, 100%, 40%);">+   llist_for_each(tmp, bts_ms_store(bts)->ms_list()) {</span><br><span>               GprsMs *ms_iter = llist_entry(tmp, typeof(*ms_iter), list);</span><br><span>          show_ms(vty, ms_iter);</span><br><span>       }</span><br><span>@@ -217,11 +218,10 @@</span><br><span>    return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int pcu_vty_show_ms_by_tlli(struct vty *vty, struct gprs_rlcmac_bts *bts_data,</span><br><span style="color: hsl(120, 100%, 40%);">+int pcu_vty_show_ms_by_tlli(struct vty *vty, struct gprs_rlcmac_bts *bts,</span><br><span>        uint32_t tlli)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-     BTS *bts = bts_data->bts;</span><br><span style="color: hsl(0, 100%, 40%);">-    GprsMs *ms = bts->ms_store().get_ms(tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+ GprsMs *ms = bts_ms_store(bts)->get_ms(tlli);</span><br><span>     if (!ms) {</span><br><span>           vty_out(vty, "Unknown TLLI %08x.%s", tlli, VTY_NEWLINE);</span><br><span>           return CMD_WARNING;</span><br><span>@@ -230,11 +230,10 @@</span><br><span>  return show_ms(vty, ms);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int pcu_vty_show_ms_by_imsi(struct vty *vty, struct gprs_rlcmac_bts *bts_data,</span><br><span style="color: hsl(120, 100%, 40%);">+int pcu_vty_show_ms_by_imsi(struct vty *vty, struct gprs_rlcmac_bts *bts,</span><br><span>   const char *imsi)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  BTS *bts = bts_data->bts;</span><br><span style="color: hsl(0, 100%, 40%);">-    GprsMs *ms = bts->ms_store().get_ms(0, 0, imsi);</span><br><span style="color: hsl(120, 100%, 40%);">+   GprsMs *ms = bts_ms_store(bts)->get_ms(0, 0, imsi);</span><br><span>       if (!ms) {</span><br><span>           vty_out(vty, "Unknown IMSI '%s'.%s", imsi, VTY_NEWLINE);</span><br><span>           return CMD_WARNING;</span><br><span>diff --git a/src/pdch.cpp b/src/pdch.cpp</span><br><span>index 49cce8d..49f0b85 100644</span><br><span>--- a/src/pdch.cpp</span><br><span>+++ b/src/pdch.cpp</span><br><span>@@ -113,9 +113,9 @@</span><br><span>       }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static inline void sched_ul_ass_or_rej(BTS *bts, gprs_rlcmac_bts *bts_data, struct gprs_rlcmac_dl_tbf *tbf)</span><br><span style="color: hsl(120, 100%, 40%);">+static inline void sched_ul_ass_or_rej(struct gprs_rlcmac_bts *bts, gprs_rlcmac_bts *bts_data, struct gprs_rlcmac_dl_tbf *tbf)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      bts->do_rate_ctr_inc(CTR_CHANNEL_REQUEST_DESCRIPTION);</span><br><span style="color: hsl(120, 100%, 40%);">+     bts_do_rate_ctr_inc(bts, CTR_CHANNEL_REQUEST_DESCRIPTION);</span><br><span> </span><br><span>       /* This call will register the new TBF with the MS on success */</span><br><span>     gprs_rlcmac_ul_tbf *ul_tbf = tbf_alloc_ul(bts_data, tbf->ms(), tbf->trx->trx_no, tbf->tlli());</span><br><span>@@ -158,7 +158,7 @@</span><br><span>     while ((pag = dequeue_paging()))</span><br><span>             talloc_free(pag);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   trx->bts->sba()->free_resources(this);</span><br><span style="color: hsl(120, 100%, 40%);">+       bts_sba(trx->bts)->free_resources(this);</span><br><span> }</span><br><span> </span><br><span> struct gprs_rlcmac_paging *gprs_rlcmac_pdch::dequeue_paging()</span><br><span>@@ -292,12 +292,12 @@</span><br><span> {</span><br><span>        struct gprs_rlcmac_tbf *tbf, *new_tbf;</span><br><span>       uint32_t tlli = packet->TLLI;</span><br><span style="color: hsl(0, 100%, 40%);">-        GprsMs *ms = bts()->ms_by_tlli(tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+      GprsMs *ms = bts_ms_by_tlli(bts(), tlli, GSM_RESERVED_TMSI);</span><br><span>         gprs_rlcmac_ul_tbf *ul_tbf;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- tbf = bts()->ul_tbf_by_poll_fn(fn, trx_no(), ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+       tbf = bts_ul_tbf_by_poll_fn(bts(), fn, trx_no(), ts_no);</span><br><span>     if (!tbf)</span><br><span style="color: hsl(0, 100%, 40%);">-               tbf = bts()->dl_tbf_by_poll_fn(fn, trx_no(), ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+               tbf = bts_dl_tbf_by_poll_fn(bts(), fn, trx_no(), ts_no);</span><br><span> </span><br><span>         if (!tbf) {</span><br><span>          LOGP(DRLCMAC, LOGL_NOTICE, "PACKET CONTROL ACK with "</span><br><span>@@ -410,7 +410,7 @@</span><br><span>        char show_bits[RLC_GPRS_WS + 1];</span><br><span> </span><br><span>         tfi = ack_nack->DOWNLINK_TFI;</span><br><span style="color: hsl(0, 100%, 40%);">-        tbf = bts()->dl_tbf_by_poll_fn(fn, trx_no(), ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+       tbf = bts_dl_tbf_by_poll_fn(bts(), fn, trx_no(), ts_no);</span><br><span>     if (!tbf) {</span><br><span>          LOGP(DRLCMAC, LOGL_NOTICE, "PACKET DOWNLINK ACK with "</span><br><span>                     "unknown FN=%u TFI=%d (TRX %d TS %d)\n",</span><br><span>@@ -477,7 +477,7 @@</span><br><span>     int bsn_begin, bsn_end;</span><br><span> </span><br><span>  tfi = ack_nack->DOWNLINK_TFI;</span><br><span style="color: hsl(0, 100%, 40%);">-        tbf = bts()->dl_tbf_by_poll_fn(fn, trx_no(), ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+       tbf = bts_dl_tbf_by_poll_fn(bts(), fn, trx_no(), ts_no);</span><br><span>     if (!tbf) {</span><br><span>          LOGP(DRLCMAC, LOGL_NOTICE, "EGPRS PACKET DOWNLINK ACK with "</span><br><span>                       "unknown FN=%u TFI=%d (TRX %d TS %d)\n",</span><br><span>@@ -566,10 +566,10 @@</span><br><span>           uint32_t tlli = request->ID.u.TLLI;</span><br><span>               bool ms_found = true;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-               GprsMs *ms = bts()->ms_by_tlli(tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+              GprsMs *ms = bts_ms_by_tlli(bts(), tlli, GSM_RESERVED_TMSI);</span><br><span>                 if (!ms) {</span><br><span>                   ms_found = false;</span><br><span style="color: hsl(0, 100%, 40%);">-                       ms = bts()->ms_alloc(0, 0); /* ms class updated later */</span><br><span style="color: hsl(120, 100%, 40%);">+                   ms = bts_alloc_ms(bts(), 0, 0); /* ms class updated later */</span><br><span>                         ms_set_tlli(ms, tlli);</span><br><span>               }</span><br><span>            ul_tbf = ms_ul_tbf(ms); /* hence ul_tbf may be NULL */</span><br><span>@@ -580,10 +580,10 @@</span><br><span>               LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF "</span><br><span>                    "in packet resource request of single "</span><br><span>                    "block, so we provide one:\n");</span><br><span style="color: hsl(0, 100%, 40%);">-               sba = bts()->sba()->find(this, fn);</span><br><span style="color: hsl(120, 100%, 40%);">+             sba = bts_sba(bts())->find(this, fn);</span><br><span>             if (sba) {</span><br><span>                   ms_set_ta(ms, sba->ta);</span><br><span style="color: hsl(0, 100%, 40%);">-                      bts()->sba()->free_sba(sba);</span><br><span style="color: hsl(120, 100%, 40%);">+                    bts_sba(bts())->free_sba(sba);</span><br><span>            } else if (!ul_tbf || !ul_tbf->state_is(GPRS_RLCMAC_FINISHED)) {</span><br><span>                  LOGPTBFUL(ul_tbf, LOGL_NOTICE,</span><br><span>                                 "MS requests UL TBF in PACKET RESOURCE REQ of "</span><br><span>@@ -640,7 +640,7 @@</span><br><span>    if (request->ID.u.Global_TFI.UnionType) {</span><br><span>                 struct gprs_rlcmac_dl_tbf *dl_tbf;</span><br><span>           int8_t tfi = request->ID.u.Global_TFI.u.DOWNLINK_TFI;</span><br><span style="color: hsl(0, 100%, 40%);">-                dl_tbf = bts()->dl_tbf_by_tfi(tfi, trx_no(), ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+               dl_tbf = bts_dl_tbf_by_tfi(bts(), tfi, trx_no(), ts_no);</span><br><span>             if (!dl_tbf) {</span><br><span>                       LOGP(DRLCMAC, LOGL_NOTICE, "PACKET RESOURCE REQ unknown downlink TFI=%d\n", tfi);</span><br><span>                  return;</span><br><span>@@ -653,7 +653,7 @@</span><br><span>        } else {</span><br><span>             struct gprs_rlcmac_ul_tbf *ul_tbf;</span><br><span>           int8_t tfi = request->ID.u.Global_TFI.u.UPLINK_TFI;</span><br><span style="color: hsl(0, 100%, 40%);">-          ul_tbf = bts()->ul_tbf_by_tfi(tfi, trx_no(), ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+               ul_tbf = bts_ul_tbf_by_tfi(bts(), tfi, trx_no(), ts_no);</span><br><span>             if (!ul_tbf) {</span><br><span>                       LOGP(DRLCMAC, LOGL_NOTICE, "PACKET RESOURCE REQ unknown uplink TFI=%d\n", tfi);</span><br><span>                    return;</span><br><span>@@ -671,16 +671,16 @@</span><br><span>      struct gprs_rlcmac_sba *sba;</span><br><span>         GprsMs *ms;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- ms = bts()->ms_by_tlli(report->TLLI);</span><br><span style="color: hsl(120, 100%, 40%);">+   ms = bts_ms_by_tlli(bts(), report->TLLI, GSM_RESERVED_TMSI);</span><br><span>      if (!ms) {</span><br><span>           LOGP(DRLCMAC, LOGL_NOTICE, "MS send measurement "</span><br><span>               "but TLLI 0x%08x is unknown\n", report->TLLI);</span><br><span style="color: hsl(0, 100%, 40%);">-                ms = bts()->ms_alloc(0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+                ms = bts_alloc_ms(bts(), 0, 0);</span><br><span>              ms_set_tlli(ms, report->TLLI);</span><br><span>    }</span><br><span style="color: hsl(0, 100%, 40%);">-       if ((sba = bts()->sba()->find(this, fn))) {</span><br><span style="color: hsl(120, 100%, 40%);">+     if ((sba = bts_sba(bts())->find(this, fn))) {</span><br><span>             ms_set_ta(ms, sba->ta);</span><br><span style="color: hsl(0, 100%, 40%);">-              bts()->sba()->free_sba(sba);</span><br><span style="color: hsl(120, 100%, 40%);">+            bts_sba(bts())->free_sba(sba);</span><br><span>    }</span><br><span>    gprs_rlcmac_meas_rep(ms, report);</span><br><span> }</span><br><span>@@ -703,9 +703,9 @@</span><br><span> </span><br><span>     rc = decode_gsm_rlcmac_uplink(rlc_block, ul_control_block);</span><br><span>  if (ul_control_block->u.MESSAGE_TYPE == MT_PACKET_UPLINK_DUMMY_CONTROL_BLOCK)</span><br><span style="color: hsl(0, 100%, 40%);">-                bts()->send_gsmtap_meas(PCU_GSMTAP_C_UL_DUMMY, true, trx_no(), ts_no, GSMTAP_CHANNEL_PACCH, fn, data, data_len, meas);</span><br><span style="color: hsl(120, 100%, 40%);">+             bts_send_gsmtap_meas(bts(), PCU_GSMTAP_C_UL_DUMMY, true, trx_no(), ts_no, GSMTAP_CHANNEL_PACCH, fn, data, data_len, meas);</span><br><span>   else</span><br><span style="color: hsl(0, 100%, 40%);">-            bts()->send_gsmtap_meas(PCU_GSMTAP_C_UL_CTRL, true, trx_no(), ts_no, GSMTAP_CHANNEL_PACCH, fn, data, data_len, meas);</span><br><span style="color: hsl(120, 100%, 40%);">+              bts_send_gsmtap_meas(bts(), PCU_GSMTAP_C_UL_CTRL, true, trx_no(), ts_no, GSMTAP_CHANNEL_PACCH, fn, data, data_len, meas);</span><br><span> </span><br><span>        if (rc < 0) {</span><br><span>             LOGP(DRLCMACUL, LOGL_ERROR, "Dropping Uplink Control Block with invalid "</span><br><span>@@ -714,7 +714,7 @@</span><br><span>    }</span><br><span>    LOGP(DRLCMAC, LOGL_DEBUG, "------------------------- RX : Uplink Control Block -------------------------\n");</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     bts()->do_rate_ctr_inc(CTR_RLC_RECV_CONTROL);</span><br><span style="color: hsl(120, 100%, 40%);">+      bts_do_rate_ctr_inc(bts(), CTR_RLC_RECV_CONTROL);</span><br><span>    switch (ul_control_block->u.MESSAGE_TYPE) {</span><br><span>       case MT_PACKET_CONTROL_ACK:</span><br><span>          rcv_control_ack(&ul_control_block->u.Packet_Control_Acknowledgement, fn);</span><br><span>@@ -735,7 +735,7 @@</span><br><span>               /* ignoring it. change the SI to not force sending these? */</span><br><span>                 break;</span><br><span>       default:</span><br><span style="color: hsl(0, 100%, 40%);">-                bts()->do_rate_ctr_inc(CTR_DECODE_ERRORS);</span><br><span style="color: hsl(120, 100%, 40%);">+         bts_do_rate_ctr_inc(bts(), CTR_DECODE_ERRORS);</span><br><span>               LOGP(DRLCMAC, LOGL_NOTICE,</span><br><span>                   "RX: [PCU <- BTS] unknown control block(%d) received\n",</span><br><span>                        ul_control_block->u.MESSAGE_TYPE);</span><br><span>@@ -752,13 +752,13 @@</span><br><span> {</span><br><span>   enum CodingScheme cs = mcs_get_by_size_ul(len);</span><br><span>      if (!cs) {</span><br><span style="color: hsl(0, 100%, 40%);">-              bts()->do_rate_ctr_inc(CTR_DECODE_ERRORS);</span><br><span style="color: hsl(120, 100%, 40%);">+         bts_do_rate_ctr_inc(bts(), CTR_DECODE_ERRORS);</span><br><span>               LOGP(DRLCMACUL, LOGL_ERROR, "Dropping data block with invalid "</span><br><span>                 "length %d: %s\n", len, osmo_hexdump(data, len));</span><br><span>             return -EINVAL;</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   bts()->do_rate_ctr_add(CTR_RLC_UL_BYTES, len);</span><br><span style="color: hsl(120, 100%, 40%);">+     bts_do_rate_ctr_add(bts(), CTR_RLC_UL_BYTES, len);</span><br><span> </span><br><span>       LOGP(DRLCMACUL, LOGL_DEBUG, "Got RLC block, coding scheme: %s, "</span><br><span>           "length: %d (%d))\n", mcs_name(cs), len, mcs_used_size_ul(cs));</span><br><span>@@ -769,7 +769,7 @@</span><br><span>      if (mcs_is_edge(cs))</span><br><span>                 return rcv_data_block(data, len, fn, meas, cs);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     bts()->do_rate_ctr_inc(CTR_DECODE_ERRORS);</span><br><span style="color: hsl(120, 100%, 40%);">+ bts_do_rate_ctr_inc(bts(), CTR_DECODE_ERRORS);</span><br><span>       LOGP(DRLCMACUL, LOGL_ERROR, "Unsupported coding scheme %s\n",</span><br><span>              mcs_name(cs));</span><br><span>       return -EINVAL;</span><br><span>@@ -788,11 +788,11 @@</span><br><span>       * control blocks (see 44.060, section 10.3, 1st par.)</span><br><span>        */</span><br><span>  if (mcs_is_edge(cs)) {</span><br><span style="color: hsl(0, 100%, 40%);">-          bts()->send_gsmtap_meas(PCU_GSMTAP_C_UL_DATA_EGPRS, true,</span><br><span style="color: hsl(120, 100%, 40%);">+          bts_send_gsmtap_meas(bts(), PCU_GSMTAP_C_UL_DATA_EGPRS, true,</span><br><span>                                        trx_no(), ts_no, GSMTAP_CHANNEL_PDTCH, fn,</span><br><span>                                   data, data_len, meas);</span><br><span>       } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                bts()->send_gsmtap_meas(PCU_GSMTAP_C_UL_DATA_GPRS, true,</span><br><span style="color: hsl(120, 100%, 40%);">+           bts_send_gsmtap_meas(bts(), PCU_GSMTAP_C_UL_DATA_GPRS, true,</span><br><span>                                         trx_no(), ts_no, GSMTAP_CHANNEL_PDTCH, fn,</span><br><span>                                   data, data_len, meas);</span><br><span>       }</span><br><span>@@ -804,7 +804,7 @@</span><br><span>              LOGP(DRLCMACUL, LOGL_ERROR,</span><br><span>                  "Got %s RLC block but header parsing has failed\n",</span><br><span>                        mcs_name(cs));</span><br><span style="color: hsl(0, 100%, 40%);">-          bts()->do_rate_ctr_inc(CTR_DECODE_ERRORS);</span><br><span style="color: hsl(120, 100%, 40%);">+         bts_do_rate_ctr_inc(bts(), CTR_DECODE_ERRORS);</span><br><span>               return rc;</span><br><span>   }</span><br><span> </span><br><span>@@ -974,7 +974,7 @@</span><br><span>  m_num_reserved[dir] -= 1;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-inline BTS *gprs_rlcmac_pdch::bts() const</span><br><span style="color: hsl(120, 100%, 40%);">+inline struct gprs_rlcmac_bts *gprs_rlcmac_pdch::bts() const</span><br><span> {</span><br><span>       return trx->bts;</span><br><span> }</span><br><span>@@ -986,7 +986,7 @@</span><br><span> </span><br><span> inline gprs_rlcmac_bts *gprs_rlcmac_pdch::bts_data() const</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   return trx->bts->bts_data();</span><br><span style="color: hsl(120, 100%, 40%);">+    return trx->bts;</span><br><span> }</span><br><span> </span><br><span> /* PTCCH (Packet Timing Advance Control Channel) */</span><br><span>diff --git a/src/pdch.h b/src/pdch.h</span><br><span>index 5185045..7a544fe 100644</span><br><span>--- a/src/pdch.h</span><br><span>+++ b/src/pdch.h</span><br><span>@@ -70,7 +70,7 @@</span><br><span>                 struct pcu_l1_meas *meas, enum CodingScheme cs);</span><br><span> </span><br><span>         gprs_rlcmac_bts *bts_data() const;</span><br><span style="color: hsl(0, 100%, 40%);">-      BTS *bts() const;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gprs_rlcmac_bts *bts() const;</span><br><span>         uint8_t trx_no() const;</span><br><span> </span><br><span>  struct gprs_rlcmac_ul_tbf *ul_tbf_by_tfi(uint8_t tfi);</span><br><span>diff --git a/src/poll_controller.cpp b/src/poll_controller.cpp</span><br><span>index ac79510..04ec4fd 100644</span><br><span>--- a/src/poll_controller.cpp</span><br><span>+++ b/src/poll_controller.cpp</span><br><span>@@ -24,6 +24,7 @@</span><br><span> #include <bts.h></span><br><span> #include <tbf.h></span><br><span> #include <tbf_ul.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <tbf_dl.h></span><br><span> #include <cxx_linuxlist.h></span><br><span> #include <sba.h></span><br><span> </span><br><span>@@ -32,7 +33,7 @@</span><br><span> #include <osmocom/gsm/gsm_utils.h></span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-PollController::PollController(BTS& bts)</span><br><span style="color: hsl(120, 100%, 40%);">+PollController::PollController(struct gprs_rlcmac_bts& bts)</span><br><span>      : m_bts(bts)</span><br><span> {}</span><br><span> </span><br><span>@@ -51,26 +52,26 @@</span><br><span>         struct gprs_rlcmac_dl_tbf *dl_tbf;</span><br><span>   struct gprs_rlcmac_ul_tbf *ul_tbf;</span><br><span>   struct gprs_rlcmac_sba *sba, *sba2;</span><br><span style="color: hsl(0, 100%, 40%);">-     LListHead<gprs_rlcmac_tbf> *pos;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct llist_item *pos;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     llist_for_each(pos, &m_bts.ul_tbfs()) {</span><br><span style="color: hsl(0, 100%, 40%);">-             ul_tbf = as_ul_tbf(pos->entry());</span><br><span style="color: hsl(120, 100%, 40%);">+  llist_for_each_entry(pos, &m_bts.ul_tbfs, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+         ul_tbf = as_ul_tbf((struct gprs_rlcmac_tbf *)pos->entry);</span><br><span>                 if (ul_tbf->poll_scheduled()) {</span><br><span>                   if (elapsed_fn_check(max_delay, frame_number, ul_tbf->poll_fn))</span><br><span>                           ul_tbf->poll_timeout();</span><br><span>           }</span><br><span>    }</span><br><span style="color: hsl(0, 100%, 40%);">-       llist_for_each(pos, &m_bts.dl_tbfs()) {</span><br><span style="color: hsl(0, 100%, 40%);">-             dl_tbf = as_dl_tbf(pos->entry());</span><br><span style="color: hsl(120, 100%, 40%);">+  llist_for_each_entry(pos, &m_bts.dl_tbfs, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+         dl_tbf = as_dl_tbf((struct gprs_rlcmac_tbf *)pos->entry);</span><br><span>                 if (dl_tbf->poll_scheduled()) {</span><br><span>                   if (elapsed_fn_check(max_delay, frame_number, dl_tbf->poll_fn))</span><br><span>                           dl_tbf->poll_timeout();</span><br><span>           }</span><br><span>    }</span><br><span style="color: hsl(0, 100%, 40%);">-       llist_for_each_entry_safe(sba, sba2, &m_bts.sba()->m_sbas, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+     llist_for_each_entry_safe(sba, sba2, &bts_sba(&m_bts)->m_sbas, list) {</span><br><span>            if (elapsed_fn_check(max_delay, frame_number, sba->fn)) {</span><br><span>                         /* sba will be freed here */</span><br><span style="color: hsl(0, 100%, 40%);">-                    m_bts.sba()->timeout(sba);</span><br><span style="color: hsl(120, 100%, 40%);">+                 bts_sba(&m_bts)->timeout(sba);</span><br><span>                }</span><br><span>    }</span><br><span> </span><br><span>diff --git a/src/poll_controller.h b/src/poll_controller.h</span><br><span>index 65d1fee..8e709a3 100644</span><br><span>--- a/src/poll_controller.h</span><br><span>+++ b/src/poll_controller.h</span><br><span>@@ -21,22 +21,22 @@</span><br><span> </span><br><span> #pragma once</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct BTS;</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlcmac_bts;</span><br><span> </span><br><span> /**</span><br><span>  * I belong to a BTS and I am responsible for finding TBFs and</span><br><span>  * SBAs that should have been polled and execute the timeout</span><br><span>  * action on them.</span><br><span>  */</span><br><span style="color: hsl(0, 100%, 40%);">-class PollController {</span><br><span style="color: hsl(120, 100%, 40%);">+struct PollController {</span><br><span> public:</span><br><span style="color: hsl(0, 100%, 40%);">-    PollController(BTS& bts);</span><br><span style="color: hsl(120, 100%, 40%);">+ PollController(struct gprs_rlcmac_bts& bts);</span><br><span> </span><br><span>         /* check for poll timeout */</span><br><span>         void expireTimedout(int frame_number, unsigned max_delay);</span><br><span> </span><br><span> private:</span><br><span style="color: hsl(0, 100%, 40%);">-      BTS& m_bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts& m_bts;</span><br><span> </span><br><span> private:</span><br><span>   /* disable copying to avoid slicing */</span><br><span>diff --git a/src/rlc.cpp b/src/rlc.cpp</span><br><span>index 8f56a8e..a2cc52c 100644</span><br><span>--- a/src/rlc.cpp</span><br><span>+++ b/src/rlc.cpp</span><br><span>@@ -127,7 +127,7 @@</span><br><span>        return (ssn - 1 - bitnum);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void gprs_rlc_dl_window::update(BTS *bts, const struct bitvec *rbb,</span><br><span style="color: hsl(120, 100%, 40%);">+void gprs_rlc_dl_window::update(struct gprs_rlcmac_bts *bts, const struct bitvec *rbb,</span><br><span>                       uint16_t first_bsn, uint16_t *lost,</span><br><span>                  uint16_t *received)</span><br><span> {</span><br><span>@@ -154,13 +154,13 @@</span><br><span>             } else {</span><br><span>                     LOGP(DRLCMACDL, LOGL_DEBUG, "- got NACK for BSN=%d\n", bsn);</span><br><span>                       m_v_b.mark_nacked(bsn);</span><br><span style="color: hsl(0, 100%, 40%);">-                 bts->do_rate_ctr_inc(CTR_RLC_NACKED);</span><br><span style="color: hsl(120, 100%, 40%);">+                      bts_do_rate_ctr_inc(bts, CTR_RLC_NACKED);</span><br><span>                    *lost += 1;</span><br><span>          }</span><br><span>    }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void gprs_rlc_dl_window::update(BTS *bts, char *show_rbb, uint16_t ssn,</span><br><span style="color: hsl(120, 100%, 40%);">+void gprs_rlc_dl_window::update(struct gprs_rlcmac_bts *bts, char *show_rbb, uint16_t ssn,</span><br><span>                        uint16_t *lost, uint16_t *received)</span><br><span> {</span><br><span>     /* SSN - 1 is in range V(A)..V(S)-1 */</span><br><span>@@ -178,7 +178,7 @@</span><br><span>                 } else {</span><br><span>                     LOGP(DRLCMACDL, LOGL_DEBUG, "- got NACK for BSN=%d\n", bsn);</span><br><span>                       m_v_b.mark_nacked(bsn);</span><br><span style="color: hsl(0, 100%, 40%);">-                 bts->do_rate_ctr_inc(CTR_RLC_NACKED);</span><br><span style="color: hsl(120, 100%, 40%);">+                      bts_do_rate_ctr_inc(bts, CTR_RLC_NACKED);</span><br><span>                    *lost += 1;</span><br><span>          }</span><br><span>    }</span><br><span>diff --git a/src/rlc.h b/src/rlc.h</span><br><span>index 707f305..eb79430 100644</span><br><span>--- a/src/rlc.h</span><br><span>+++ b/src/rlc.h</span><br><span>@@ -38,7 +38,7 @@</span><br><span> #define RLC_MAX_WS   RLC_EGPRS_MAX_WS</span><br><span> #define RLC_MAX_LEN 74 /* MCS-9 data unit */</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct BTS;</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlcmac_bts;</span><br><span> </span><br><span> /* The state of a BSN in the send/receive window */</span><br><span> enum gprs_rlc_ul_bsn_state {</span><br><span>@@ -307,9 +307,9 @@</span><br><span>     /* Methods to manage reception */</span><br><span>    int resend_needed() const;</span><br><span>   int mark_for_resend();</span><br><span style="color: hsl(0, 100%, 40%);">-  void update(BTS *bts, char *show_rbb, uint16_t ssn,</span><br><span style="color: hsl(120, 100%, 40%);">+   void update(struct gprs_rlcmac_bts *bts, char *show_rbb, uint16_t ssn,</span><br><span>                       uint16_t *lost, uint16_t *received);</span><br><span style="color: hsl(0, 100%, 40%);">-    void update(BTS *bts, const struct bitvec *rbb,</span><br><span style="color: hsl(120, 100%, 40%);">+       void update(struct gprs_rlcmac_bts *bts, const struct bitvec *rbb,</span><br><span>                   uint16_t first_bsn, uint16_t *lost,</span><br><span>                  uint16_t *received);</span><br><span>         int move_window();</span><br><span>diff --git a/src/sba.cpp b/src/sba.cpp</span><br><span>index cc58405..53eb847 100644</span><br><span>--- a/src/sba.cpp</span><br><span>+++ b/src/sba.cpp</span><br><span>@@ -40,7 +40,7 @@</span><br><span>  * This offset must be a multiple of 13. */</span><br><span> #define AGCH_START_OFFSET 52</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-SBAController::SBAController(BTS &bts)</span><br><span style="color: hsl(120, 100%, 40%);">+SBAController::SBAController(struct gprs_rlcmac_bts &bts)</span><br><span>  : m_bts(bts)</span><br><span> {</span><br><span>    INIT_LLIST_HEAD(&m_sbas);</span><br><span>@@ -64,7 +64,7 @@</span><br><span> </span><br><span>        for (trx = 0; trx < 8; trx++) {</span><br><span>           for (ts = 7; ts >= 0; ts--) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        pdch = &m_bts.bts_data()->trx[trx].pdch[ts];</span><br><span style="color: hsl(120, 100%, 40%);">+                   pdch = &m_bts.trx[trx].pdch[ts];</span><br><span>                         if (!pdch->is_enabled())</span><br><span>                          continue;</span><br><span>                    break;</span><br><span>@@ -86,7 +86,7 @@</span><br><span>   sba->ta = ta;</span><br><span> </span><br><span>         llist_add(&sba->list, &m_sbas);</span><br><span style="color: hsl(0, 100%, 40%);">-      m_bts.do_rate_ctr_inc(CTR_SBA_ALLOCATED);</span><br><span style="color: hsl(120, 100%, 40%);">+     bts_do_rate_ctr_inc(&m_bts, CTR_SBA_ALLOCATED);</span><br><span> </span><br><span>      *_trx = trx;</span><br><span>         *_ts = ts;</span><br><span>@@ -132,14 +132,14 @@</span><br><span>   LOGP(DRLCMAC, LOGL_NOTICE,</span><br><span>        "Poll timeout for SBA (TRX=%u, TS=%u, FN=%u, TA=%u)\n", sba->trx_no,</span><br><span>            sba->ts_no, sba->fn, sba->ta);</span><br><span style="color: hsl(0, 100%, 40%);">-    m_bts.do_rate_ctr_inc(CTR_SBA_TIMEDOUT);</span><br><span style="color: hsl(120, 100%, 40%);">+      bts_do_rate_ctr_inc(&m_bts, CTR_SBA_TIMEDOUT);</span><br><span>   free_sba(sba);</span><br><span>       return 0;</span><br><span> }</span><br><span> </span><br><span> void SBAController::free_sba(gprs_rlcmac_sba *sba)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   m_bts.do_rate_ctr_inc(CTR_SBA_FREED);</span><br><span style="color: hsl(120, 100%, 40%);">+ bts_do_rate_ctr_inc(&m_bts, CTR_SBA_FREED);</span><br><span>      llist_del(&sba->list);</span><br><span>        talloc_free(sba);</span><br><span> }</span><br><span>diff --git a/src/sba.h b/src/sba.h</span><br><span>index 27dae21..a6e3f82 100644</span><br><span>--- a/src/sba.h</span><br><span>+++ b/src/sba.h</span><br><span>@@ -26,7 +26,7 @@</span><br><span> #include <osmocom/core/linuxlist.h></span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct BTS;</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlcmac_bts;</span><br><span> struct gprs_rlcmac_pdch;</span><br><span> </span><br><span> /*</span><br><span>@@ -45,10 +45,10 @@</span><br><span>  *</span><br><span>  * TODO: Add a flush method..</span><br><span>  */</span><br><span style="color: hsl(0, 100%, 40%);">-class SBAController {</span><br><span style="color: hsl(120, 100%, 40%);">+struct SBAController {</span><br><span>         friend class PollController;</span><br><span> public:</span><br><span style="color: hsl(0, 100%, 40%);">- SBAController(BTS &bts);</span><br><span style="color: hsl(120, 100%, 40%);">+  SBAController(struct gprs_rlcmac_bts &bts);</span><br><span> </span><br><span>  int alloc(uint8_t *_trx, uint8_t *_ts, uint32_t *_fn, uint8_t ta);</span><br><span>   gprs_rlcmac_sba *find(uint8_t trx, uint8_t ts, uint32_t fn);</span><br><span>@@ -62,6 +62,6 @@</span><br><span>     void free_sba(gprs_rlcmac_sba *sba);</span><br><span> </span><br><span> private:</span><br><span style="color: hsl(0, 100%, 40%);">-    BTS &m_bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts &m_bts;</span><br><span>   llist_head m_sbas;</span><br><span> };</span><br><span>diff --git a/src/tbf.cpp b/src/tbf.cpp</span><br><span>index 43c8cbf..05f4e2c 100644</span><br><span>--- a/src/tbf.cpp</span><br><span>+++ b/src/tbf.cpp</span><br><span>@@ -124,7 +124,7 @@</span><br><span>      timespecclear(&rssi_tv);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-gprs_rlcmac_tbf::gprs_rlcmac_tbf(BTS *bts_, GprsMs *ms, gprs_rlcmac_tbf_direction dir) :</span><br><span style="color: hsl(120, 100%, 40%);">+gprs_rlcmac_tbf::gprs_rlcmac_tbf(struct gprs_rlcmac_bts *bts_, GprsMs *ms, gprs_rlcmac_tbf_direction dir) :</span><br><span>   state_flags(0),</span><br><span>      direction(dir),</span><br><span>      trx(NULL),</span><br><span>@@ -147,7 +147,6 @@</span><br><span>     ul_ass_state(GPRS_RLCMAC_UL_ASS_NONE),</span><br><span>       ul_ack_state(GPRS_RLCMAC_UL_ACK_NONE),</span><br><span>       poll_state(GPRS_RLCMAC_POLL_NONE),</span><br><span style="color: hsl(0, 100%, 40%);">-      m_list(this),</span><br><span>        m_egprs_enabled(false)</span><br><span> {</span><br><span>  /* The classes of these members do not have proper constructors yet.</span><br><span>@@ -160,6 +159,9 @@</span><br><span>   memset(&m_ms_list, 0, sizeof(m_ms_list));</span><br><span>        m_ms_list.entry = this;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+   memset(&m_bts_list, 0, sizeof(m_bts_list));</span><br><span style="color: hsl(120, 100%, 40%);">+       m_bts_list.entry = this;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>   m_rlc.init();</span><br><span>        m_llc.init();</span><br><span> </span><br><span>@@ -168,7 +170,7 @@</span><br><span> </span><br><span> gprs_rlcmac_bts *gprs_rlcmac_tbf::bts_data() const</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  return bts->bts_data();</span><br><span style="color: hsl(120, 100%, 40%);">+    return bts;</span><br><span> }</span><br><span> </span><br><span> uint32_t gprs_rlcmac_tbf::tlli() const</span><br><span>@@ -245,7 +247,7 @@</span><br><span>         if (!ms_check_tlli(ms(), tlli)) {</span><br><span>            GprsMs *old_ms;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-             old_ms = bts->ms_store().get_ms(tlli, 0, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+            old_ms = bts_ms_store(bts)->get_ms(tlli, 0, NULL);</span><br><span>                if (old_ms)</span><br><span>                  ms_merge_and_clear_ms(ms(), old_ms);</span><br><span>         }</span><br><span>@@ -274,9 +276,9 @@</span><br><span>      /* update counters */</span><br><span>        if (tbf->direction == GPRS_RLCMAC_UL_TBF) {</span><br><span>               gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-            tbf->bts->do_rate_ctr_inc(CTR_TBF_UL_FREED);</span><br><span style="color: hsl(120, 100%, 40%);">+            bts_do_rate_ctr_inc(tbf->bts, CTR_TBF_UL_FREED);</span><br><span>          if (tbf->state_is(GPRS_RLCMAC_FLOW))</span><br><span style="color: hsl(0, 100%, 40%);">-                 tbf->bts->do_rate_ctr_inc(CTR_TBF_UL_ABORTED);</span><br><span style="color: hsl(120, 100%, 40%);">+                  bts_do_rate_ctr_inc(tbf->bts, CTR_TBF_UL_ABORTED);</span><br><span>                rate_ctr_group_free(ul_tbf->m_ul_egprs_ctrs);</span><br><span>             rate_ctr_group_free(ul_tbf->m_ul_gprs_ctrs);</span><br><span>      } else {</span><br><span>@@ -286,9 +288,9 @@</span><br><span>               } else {</span><br><span>                     rate_ctr_group_free(dl_tbf->m_dl_gprs_ctrs);</span><br><span>              }</span><br><span style="color: hsl(0, 100%, 40%);">-               tbf->bts->do_rate_ctr_inc(CTR_TBF_DL_FREED);</span><br><span style="color: hsl(120, 100%, 40%);">+            bts_do_rate_ctr_inc(tbf->bts, CTR_TBF_DL_FREED);</span><br><span>          if (tbf->state_is(GPRS_RLCMAC_FLOW))</span><br><span style="color: hsl(0, 100%, 40%);">-                 tbf->bts->do_rate_ctr_inc(CTR_TBF_DL_ABORTED);</span><br><span style="color: hsl(120, 100%, 40%);">+                  bts_do_rate_ctr_inc(tbf->bts, CTR_TBF_DL_ABORTED);</span><br><span>        }</span><br><span> </span><br><span>        /* Give final measurement report */</span><br><span>@@ -304,7 +306,7 @@</span><br><span>    tbf->stop_timers("freeing TBF");</span><br><span>        /* TODO: Could/Should generate  bssgp_tx_llc_discarded */</span><br><span>    tbf_unlink_pdch(tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-   llist_del(&tbf->list());</span><br><span style="color: hsl(120, 100%, 40%);">+       llist_del(tbf_bts_list(tbf));</span><br><span> </span><br><span>    if (tbf->ms())</span><br><span>            tbf->set_ms(NULL);</span><br><span>@@ -326,7 +328,7 @@</span><br><span> </span><br><span> int gprs_rlcmac_tbf::update()</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gprs_rlcmac_bts *bts_data = bts->bts_data();</span><br><span style="color: hsl(120, 100%, 40%);">+        struct gprs_rlcmac_bts *bts_data = bts;</span><br><span>      int rc;</span><br><span> </span><br><span>  if (direction != GPRS_RLCMAC_DL_TBF)</span><br><span>@@ -399,13 +401,13 @@</span><br><span> </span><br><span>     switch(n) {</span><br><span>  case N3101:</span><br><span style="color: hsl(0, 100%, 40%);">-             chk = bts->bts_data()->n3101;</span><br><span style="color: hsl(120, 100%, 40%);">+           chk = bts->n3101;</span><br><span>                 break;</span><br><span>       case N3103:</span><br><span style="color: hsl(0, 100%, 40%);">-             chk = bts->bts_data()->n3103;</span><br><span style="color: hsl(120, 100%, 40%);">+           chk = bts->n3103;</span><br><span>                 break;</span><br><span>       case N3105:</span><br><span style="color: hsl(0, 100%, 40%);">-             chk = bts->bts_data()->n3105;</span><br><span style="color: hsl(120, 100%, 40%);">+           chk = bts->n3105;</span><br><span>                 break;</span><br><span>       default:</span><br><span>             LOGPTBF(this, LOGL_ERROR, "unhandled counter %s\n",</span><br><span>@@ -492,7 +494,7 @@</span><br><span>  int microsec;</span><br><span>        struct osmo_tdef *tdef;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     if (!(tdef = osmo_tdef_get_entry(bts->bts_data()->T_defs_bts, T)))</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!(tdef = osmo_tdef_get_entry(bts->T_defs_bts, T)))</span><br><span>            tdef = osmo_tdef_get_entry(bts->pcu->T_defs, T);</span><br><span> </span><br><span>   if (t >= T_MAX || !tdef) {</span><br><span>@@ -563,7 +565,7 @@</span><br><span>          LOGPTBF(this, LOGL_DEBUG, "Polling is already scheduled\n");</span><br><span>               return -EBUSY;</span><br><span>       }</span><br><span style="color: hsl(0, 100%, 40%);">-       if (bts->sba()->find(trx->trx_no, ts, next_fn(fn, 13))) {</span><br><span style="color: hsl(120, 100%, 40%);">+    if (bts_sba(bts)->find(trx->trx_no, ts, next_fn(fn, 13))) {</span><br><span>            LOGPTBF(this, LOGL_DEBUG, "Polling is already scheduled "</span><br><span>                  "for single block allocation at FN %d TS %d ...\n",</span><br><span>                        new_poll_fn, ts);</span><br><span>@@ -628,7 +630,7 @@</span><br><span>      gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(this);</span><br><span> </span><br><span>    LOGPTBF(this, LOGL_NOTICE, "poll timeout for FN=%d, TS=%d (curr FN %d)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-            poll_fn, poll_ts, bts->current_frame_number());</span><br><span style="color: hsl(120, 100%, 40%);">+            poll_fn, poll_ts, bts_current_frame_number(bts));</span><br><span> </span><br><span>        poll_state = GPRS_RLCMAC_POLL_NONE;</span><br><span> </span><br><span>@@ -644,11 +646,11 @@</span><br><span>                              "Timeout for polling PACKET CONTROL ACK for PACKET UPLINK ACK: %s\n",</span><br><span>                              rlcmac_diag().c_str());</span><br><span>              }</span><br><span style="color: hsl(0, 100%, 40%);">-               bts->do_rate_ctr_inc(CTR_RLC_ACK_TIMEDOUT);</span><br><span style="color: hsl(0, 100%, 40%);">-          bts->do_rate_ctr_inc(CTR_PUAN_POLL_TIMEDOUT);</span><br><span style="color: hsl(120, 100%, 40%);">+              bts_do_rate_ctr_inc(bts, CTR_RLC_ACK_TIMEDOUT);</span><br><span style="color: hsl(120, 100%, 40%);">+               bts_do_rate_ctr_inc(bts, CTR_PUAN_POLL_TIMEDOUT);</span><br><span>            if (state_is(GPRS_RLCMAC_FINISHED)) {</span><br><span>                        if (ul_tbf->n_inc(N3103)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                          bts->do_rate_ctr_inc(CTR_PUAN_POLL_FAILED);</span><br><span style="color: hsl(120, 100%, 40%);">+                                bts_do_rate_ctr_inc(bts, CTR_PUAN_POLL_FAILED);</span><br><span>                              TBF_SET_STATE(ul_tbf, GPRS_RLCMAC_RELEASING);</span><br><span>                                T_START(ul_tbf, T3169, 3169, "MAX N3103 reached", false);</span><br><span>                          return;</span><br><span>@@ -665,13 +667,13 @@</span><br><span>                      state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS);</span><br><span>              }</span><br><span>            ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE;</span><br><span style="color: hsl(0, 100%, 40%);">-         bts->do_rate_ctr_inc(CTR_RLC_ASS_TIMEDOUT);</span><br><span style="color: hsl(0, 100%, 40%);">-          bts->do_rate_ctr_inc(CTR_PUA_POLL_TIMEDOUT);</span><br><span style="color: hsl(120, 100%, 40%);">+               bts_do_rate_ctr_inc(bts, CTR_RLC_ASS_TIMEDOUT);</span><br><span style="color: hsl(120, 100%, 40%);">+               bts_do_rate_ctr_inc(bts, CTR_PUA_POLL_TIMEDOUT);</span><br><span>             if (n_inc(N3105)) {</span><br><span>                  TBF_SET_STATE(this, GPRS_RLCMAC_RELEASING);</span><br><span>                  T_START(this, T3195, 3195, "MAX N3105 reached", true);</span><br><span style="color: hsl(0, 100%, 40%);">-                        bts->do_rate_ctr_inc(CTR_RLC_ASS_FAILED);</span><br><span style="color: hsl(0, 100%, 40%);">-                    bts->do_rate_ctr_inc(CTR_PUA_POLL_FAILED);</span><br><span style="color: hsl(120, 100%, 40%);">+                 bts_do_rate_ctr_inc(bts, CTR_RLC_ASS_FAILED);</span><br><span style="color: hsl(120, 100%, 40%);">+                 bts_do_rate_ctr_inc(bts, CTR_PUA_POLL_FAILED);</span><br><span>                       return;</span><br><span>              }</span><br><span>            /* reschedule UL assignment */</span><br><span>@@ -684,13 +686,13 @@</span><br><span>                       state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS);</span><br><span>              }</span><br><span>            dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;</span><br><span style="color: hsl(0, 100%, 40%);">-         bts->do_rate_ctr_inc(CTR_RLC_ASS_TIMEDOUT);</span><br><span style="color: hsl(0, 100%, 40%);">-          bts->do_rate_ctr_inc(CTR_PDA_POLL_TIMEDOUT);</span><br><span style="color: hsl(120, 100%, 40%);">+               bts_do_rate_ctr_inc(bts, CTR_RLC_ASS_TIMEDOUT);</span><br><span style="color: hsl(120, 100%, 40%);">+               bts_do_rate_ctr_inc(bts, CTR_PDA_POLL_TIMEDOUT);</span><br><span>             if (n_inc(N3105)) {</span><br><span>                  TBF_SET_STATE(this, GPRS_RLCMAC_RELEASING);</span><br><span>                  T_START(this, T3195, 3195, "MAX N3105 reached", true);</span><br><span style="color: hsl(0, 100%, 40%);">-                        bts->do_rate_ctr_inc(CTR_RLC_ASS_FAILED);</span><br><span style="color: hsl(0, 100%, 40%);">-                    bts->do_rate_ctr_inc(CTR_PDA_POLL_FAILED);</span><br><span style="color: hsl(120, 100%, 40%);">+                 bts_do_rate_ctr_inc(bts, CTR_RLC_ASS_FAILED);</span><br><span style="color: hsl(120, 100%, 40%);">+                 bts_do_rate_ctr_inc(bts, CTR_PDA_POLL_FAILED);</span><br><span>                       return;</span><br><span>              }</span><br><span>            /* reschedule DL assignment */</span><br><span>@@ -706,17 +708,17 @@</span><br><span>               }</span><br><span> </span><br><span>                if (dl_tbf->state_is(GPRS_RLCMAC_RELEASING))</span><br><span style="color: hsl(0, 100%, 40%);">-                 bts->do_rate_ctr_inc(CTR_RLC_REL_TIMEDOUT);</span><br><span style="color: hsl(120, 100%, 40%);">+                        bts_do_rate_ctr_inc(bts, CTR_RLC_REL_TIMEDOUT);</span><br><span>              else {</span><br><span style="color: hsl(0, 100%, 40%);">-                  bts->do_rate_ctr_inc(CTR_RLC_ACK_TIMEDOUT);</span><br><span style="color: hsl(0, 100%, 40%);">-                  bts->do_rate_ctr_inc(CTR_PDAN_POLL_TIMEDOUT);</span><br><span style="color: hsl(120, 100%, 40%);">+                      bts_do_rate_ctr_inc(bts, CTR_RLC_ACK_TIMEDOUT);</span><br><span style="color: hsl(120, 100%, 40%);">+                       bts_do_rate_ctr_inc(bts, CTR_PDAN_POLL_TIMEDOUT);</span><br><span>            }</span><br><span> </span><br><span>                if (dl_tbf->n_inc(N3105)) {</span><br><span>                       TBF_SET_STATE(dl_tbf, GPRS_RLCMAC_RELEASING);</span><br><span>                        T_START(dl_tbf, T3195, 3195, "MAX N3105 reached", true);</span><br><span style="color: hsl(0, 100%, 40%);">-                      bts->do_rate_ctr_inc(CTR_PDAN_POLL_FAILED);</span><br><span style="color: hsl(0, 100%, 40%);">-                  bts->do_rate_ctr_inc(CTR_RLC_ACK_FAILED);</span><br><span style="color: hsl(120, 100%, 40%);">+                  bts_do_rate_ctr_inc(bts, CTR_PDAN_POLL_FAILED);</span><br><span style="color: hsl(120, 100%, 40%);">+                       bts_do_rate_ctr_inc(bts, CTR_RLC_ACK_FAILED);</span><br><span>                        return;</span><br><span>              }</span><br><span>            /* resend IMM.ASS on CCCH on timeout */</span><br><span>@@ -727,7 +729,7 @@</span><br><span>                        /* send immediate assignment */</span><br><span>                      if ((pgroup = imsi2paging_group(imsi())) > 999)</span><br><span>                           LOGPTBF(dl_tbf, LOGL_ERROR, "IMSI to paging group failed! (%s)\n", imsi());</span><br><span style="color: hsl(0, 100%, 40%);">-                   dl_tbf->bts->snd_dl_ass(dl_tbf, false, pgroup);</span><br><span style="color: hsl(120, 100%, 40%);">+                 bts_snd_dl_ass(dl_tbf->bts, dl_tbf, false, pgroup);</span><br><span>                       dl_tbf->m_wait_confirm = 1;</span><br><span>               }</span><br><span>    } else</span><br><span>@@ -736,7 +738,7 @@</span><br><span> </span><br><span> int gprs_rlcmac_tbf::setup(int8_t use_trx, bool single_slot)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gprs_rlcmac_bts *bts_data = bts->bts_data();</span><br><span style="color: hsl(120, 100%, 40%);">+        struct gprs_rlcmac_bts *bts_data = bts;</span><br><span>      int rc;</span><br><span> </span><br><span>  if (ms_mode(m_ms) != GPRS)</span><br><span>@@ -935,7 +937,7 @@</span><br><span>             goto free_ret;</span><br><span>       }</span><br><span>    LOGP(DTBF, LOGL_DEBUG, "------------------------- TX : Packet Downlink Assignment -------------------------\n");</span><br><span style="color: hsl(0, 100%, 40%);">-      bts->do_rate_ctr_inc(CTR_PKT_DL_ASSIGNMENT);</span><br><span style="color: hsl(120, 100%, 40%);">+       bts_do_rate_ctr_inc(bts, CTR_PKT_DL_ASSIGNMENT);</span><br><span> </span><br><span>         if (poll_ass_dl) {</span><br><span>           set_polling(new_poll_fn, ts, GPRS_RLCMAC_POLL_DL_ASS);</span><br><span>@@ -970,7 +972,7 @@</span><br><span>         Encoding::write_packet_access_reject(</span><br><span>                packet_access_rej, tlli());</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- bts->do_rate_ctr_inc(CTR_PKT_ACCESS_REJ);</span><br><span style="color: hsl(120, 100%, 40%);">+  bts_do_rate_ctr_inc(bts, CTR_PKT_ACCESS_REJ);</span><br><span> </span><br><span>    bitvec_pack(packet_access_rej, msgb_put(msg, GSM_MACBLOCK_LEN));</span><br><span> </span><br><span>@@ -1039,7 +1041,7 @@</span><br><span>                 goto free_ret;</span><br><span>       }</span><br><span>    LOGP(DTBF, LOGL_DEBUG, "------------------------- TX : Packet Uplink Assignment -------------------------\n");</span><br><span style="color: hsl(0, 100%, 40%);">-        bts->do_rate_ctr_inc(CTR_PKT_UL_ASSIGNMENT);</span><br><span style="color: hsl(120, 100%, 40%);">+       bts_do_rate_ctr_inc(bts, CTR_PKT_UL_ASSIGNMENT);</span><br><span> </span><br><span>         set_polling(new_poll_fn, ts, GPRS_RLCMAC_POLL_UL_ASS);</span><br><span> </span><br><span>@@ -1076,9 +1078,9 @@</span><br><span> {</span><br><span>      struct gprs_rlcmac_dl_tbf *new_tbf = NULL;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  bts->do_rate_ctr_inc(CTR_TBF_REUSED);</span><br><span style="color: hsl(120, 100%, 40%);">+      bts_do_rate_ctr_inc(bts, CTR_TBF_REUSED);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   new_tbf = tbf_alloc_dl_tbf(bts->bts_data(), ms(),</span><br><span style="color: hsl(120, 100%, 40%);">+  new_tbf = tbf_alloc_dl_tbf(bts, ms(),</span><br><span>                this->trx->trx_no, false);</span><br><span> </span><br><span>         if (!new_tbf) {</span><br><span>@@ -1112,11 +1114,11 @@</span><br><span> </span><br><span> void gprs_rlcmac_tbf::rotate_in_list()</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-    llist_del(&list());</span><br><span style="color: hsl(120, 100%, 40%);">+       llist_del(tbf_bts_list((struct gprs_rlcmac_tbf *)this));</span><br><span>     if (direction == GPRS_RLCMAC_UL_TBF)</span><br><span style="color: hsl(0, 100%, 40%);">-            llist_add(&list(), &bts->ul_tbfs());</span><br><span style="color: hsl(120, 100%, 40%);">+               llist_add(tbf_bts_list((struct gprs_rlcmac_tbf *)this), &bts->ul_tbfs);</span><br><span>       else</span><br><span style="color: hsl(0, 100%, 40%);">-            llist_add(&list(), &bts->dl_tbfs());</span><br><span style="color: hsl(120, 100%, 40%);">+               llist_add(tbf_bts_list((struct gprs_rlcmac_tbf *)this), &bts->dl_tbfs);</span><br><span> }</span><br><span> </span><br><span> uint8_t gprs_rlcmac_tbf::tsc() const</span><br><span>@@ -1186,6 +1188,11 @@</span><br><span>     return &tbf->m_ms_list.list;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+struct llist_head *tbf_bts_list(struct gprs_rlcmac_tbf *tbf)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return &tbf->m_bts_list.list;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> struct GprsMs *tbf_ms(struct gprs_rlcmac_tbf *tbf)</span><br><span> {</span><br><span>         return tbf->ms();</span><br><span>diff --git a/src/tbf.h b/src/tbf.h</span><br><span>index d767547..cb4c9b9 100644</span><br><span>--- a/src/tbf.h</span><br><span>+++ b/src/tbf.h</span><br><span>@@ -196,6 +196,7 @@</span><br><span> enum gprs_rlcmac_tbf_direction tbf_direction(const struct gprs_rlcmac_tbf *tbf);</span><br><span> void tbf_set_ms(struct gprs_rlcmac_tbf *tbf, struct GprsMs *ms);</span><br><span> struct llist_head *tbf_ms_list(struct gprs_rlcmac_tbf *tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+struct llist_head *tbf_bts_list(struct gprs_rlcmac_tbf *tbf);</span><br><span> struct GprsMs *tbf_ms(struct gprs_rlcmac_tbf *tbf);</span><br><span> bool tbf_timers_pending(struct gprs_rlcmac_tbf *tbf, enum tbf_timers t);</span><br><span> void tbf_free(struct gprs_rlcmac_tbf *tbf);</span><br><span>@@ -212,7 +213,7 @@</span><br><span> #ifdef __cplusplus</span><br><span> </span><br><span> struct gprs_rlcmac_tbf {</span><br><span style="color: hsl(0, 100%, 40%);">-        gprs_rlcmac_tbf(BTS *bts_, GprsMs *ms, gprs_rlcmac_tbf_direction dir);</span><br><span style="color: hsl(120, 100%, 40%);">+        gprs_rlcmac_tbf(struct gprs_rlcmac_bts *bts_, GprsMs *ms, gprs_rlcmac_tbf_direction dir);</span><br><span>    virtual ~gprs_rlcmac_tbf() {}</span><br><span> </span><br><span>    static void free_all(struct gprs_rlcmac_trx *trx);</span><br><span>@@ -296,9 +297,6 @@</span><br><span>     /* attempt to make things a bit more fair */</span><br><span>         void rotate_in_list();</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      LListHead<gprs_rlcmac_tbf>& list();</span><br><span style="color: hsl(0, 100%, 40%);">-   const LListHead<gprs_rlcmac_tbf>& list() const;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>    uint32_t state_flags;</span><br><span>        enum gprs_rlcmac_tbf_direction direction;</span><br><span>    struct gprs_rlcmac_trx *trx;</span><br><span>@@ -335,7 +333,7 @@</span><br><span>   uint8_t upgrade_to_multislot;</span><br><span> </span><br><span>    /* store the BTS this TBF belongs to */</span><br><span style="color: hsl(0, 100%, 40%);">- BTS *bts;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gprs_rlcmac_bts *bts;</span><br><span> </span><br><span>     /*</span><br><span>    * private fields. We can't make it private as it is breaking the</span><br><span>@@ -347,6 +345,7 @@</span><br><span>  struct rate_ctr_group *m_ctrs;</span><br><span>       enum gprs_rlcmac_tbf_state state;</span><br><span>    struct llist_item m_ms_list;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct llist_item m_bts_list;</span><br><span> </span><br><span> protected:</span><br><span>      gprs_rlcmac_bts *bts_data() const;</span><br><span>@@ -364,7 +363,6 @@</span><br><span>     enum gprs_rlcmac_tbf_ul_ass_state ul_ass_state;</span><br><span>      enum gprs_rlcmac_tbf_ul_ack_state ul_ack_state;</span><br><span>      enum gprs_rlcmac_tbf_poll_state poll_state;</span><br><span style="color: hsl(0, 100%, 40%);">-     LListHead<gprs_rlcmac_tbf> m_list;</span><br><span>     bool m_egprs_enabled;</span><br><span>        struct osmo_timer_list Tarr[T_MAX];</span><br><span>  uint8_t Narr[N_MAX];</span><br><span>@@ -522,16 +520,6 @@</span><br><span>  return false;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-inline LListHead<gprs_rlcmac_tbf>& gprs_rlcmac_tbf::list()</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     return this->m_list;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-inline const LListHead<gprs_rlcmac_tbf>& gprs_rlcmac_tbf::list() const</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       return this->m_list;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> inline GprsMs *gprs_rlcmac_tbf::ms() const</span><br><span> {</span><br><span>  return m_ms;</span><br><span>diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp</span><br><span>index ab34ea1..962c31d 100644</span><br><span>--- a/src/tbf_dl.cpp</span><br><span>+++ b/src/tbf_dl.cpp</span><br><span>@@ -139,7 +139,7 @@</span><br><span>              return NULL;</span><br><span> </span><br><span>     talloc_set_destructor(tbf, dl_tbf_dtor);</span><br><span style="color: hsl(0, 100%, 40%);">-        new (tbf) gprs_rlcmac_dl_tbf(bts->bts, ms);</span><br><span style="color: hsl(120, 100%, 40%);">+        new (tbf) gprs_rlcmac_dl_tbf(bts, ms);</span><br><span> </span><br><span>   rc = tbf->setup(use_trx, single_slot);</span><br><span>    /* if no resource */</span><br><span>@@ -169,8 +169,8 @@</span><br><span>           }</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   llist_add(&tbf->list(), &bts->bts->dl_tbfs());</span><br><span style="color: hsl(0, 100%, 40%);">- tbf->bts->do_rate_ctr_inc(CTR_TBF_DL_ALLOCATED);</span><br><span style="color: hsl(120, 100%, 40%);">+        llist_add(tbf_bts_list((struct gprs_rlcmac_tbf *)tbf), &bts->dl_tbfs);</span><br><span style="color: hsl(120, 100%, 40%);">+ bts_do_rate_ctr_inc(tbf->bts, CTR_TBF_DL_ALLOCATED);</span><br><span> </span><br><span>  tbf->m_last_dl_poll_fn = -1;</span><br><span>      tbf->m_last_dl_drained_fn = -1;</span><br><span>@@ -181,7 +181,7 @@</span><br><span>     return tbf;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-gprs_rlcmac_dl_tbf::gprs_rlcmac_dl_tbf(BTS *bts_, GprsMs *ms) :</span><br><span style="color: hsl(120, 100%, 40%);">+gprs_rlcmac_dl_tbf::gprs_rlcmac_dl_tbf(struct gprs_rlcmac_bts *bts_, GprsMs *ms) :</span><br><span>      gprs_rlcmac_tbf(bts_, ms, GPRS_RLCMAC_DL_TBF),</span><br><span>       m_tx_counter(0),</span><br><span>     m_wait_confirm(0),</span><br><span>@@ -289,10 +289,10 @@</span><br><span>   GprsMs *ms, *ms_old;</span><br><span> </span><br><span>     /* check for existing TBF */</span><br><span style="color: hsl(0, 100%, 40%);">-    ms = bts->bts->ms_store().get_ms(tlli, tlli_old, imsi);</span><br><span style="color: hsl(120, 100%, 40%);">+ ms = bts_ms_store(bts)->get_ms(tlli, tlli_old, imsi);</span><br><span> </span><br><span>         if (ms && strlen(ms_imsi(ms)) == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-           ms_old = bts->bts->ms_store().get_ms(0, 0, imsi);</span><br><span style="color: hsl(120, 100%, 40%);">+               ms_old = bts_ms_store(bts)->get_ms(0, 0, imsi);</span><br><span>           if (ms_old && ms_old != ms) {</span><br><span>                        /* The TLLI has changed (RAU), so there are two MS</span><br><span>                    * objects for the same MS */</span><br><span>@@ -317,7 +317,7 @@</span><br><span>  }</span><br><span> </span><br><span>        if (!ms)</span><br><span style="color: hsl(0, 100%, 40%);">-                ms = bts->bts->ms_alloc(ms_class, egprs_ms_class);</span><br><span style="color: hsl(120, 100%, 40%);">+              ms = bts_alloc_ms(bts, ms_class, egprs_ms_class);</span><br><span>    ms_set_imsi(ms, imsi);</span><br><span>       ms_confirm_tlli(ms, tlli);</span><br><span>   if (!ms_ms_class(ms) && ms_class) {</span><br><span>@@ -391,12 +391,12 @@</span><br><span>                          break;</span><br><span>               }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-           bts->do_rate_ctr_inc(CTR_LLC_FRAME_TIMEDOUT);</span><br><span style="color: hsl(120, 100%, 40%);">+              bts_do_rate_ctr_inc(bts, CTR_LLC_FRAME_TIMEDOUT);</span><br><span> drop_frame:</span><br><span>             frames++;</span><br><span>            octets += msg->len;</span><br><span>               msgb_free(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-         bts->do_rate_ctr_inc(CTR_LLC_FRAME_DROPPED);</span><br><span style="color: hsl(120, 100%, 40%);">+               bts_do_rate_ctr_inc(bts, CTR_LLC_FRAME_DROPPED);</span><br><span>             continue;</span><br><span>    }</span><br><span> </span><br><span>@@ -463,9 +463,9 @@</span><br><span>           * MCS1-4, because USF for GPRS-only MS will be sent */</span><br><span>              force_cs = ms_current_cs_dl(m_ms);</span><br><span>           if (force_cs > MCS4) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       force_cs = bts->cs_dl_is_supported(MCS4) ? MCS4 :</span><br><span style="color: hsl(0, 100%, 40%);">-                               bts->cs_dl_is_supported(MCS3) ? MCS3 :</span><br><span style="color: hsl(0, 100%, 40%);">-                               bts->cs_dl_is_supported(MCS2) ? MCS2 :</span><br><span style="color: hsl(120, 100%, 40%);">+                  force_cs = bts_cs_dl_is_supported(bts, MCS4) ? MCS4 :</span><br><span style="color: hsl(120, 100%, 40%);">+                            bts_cs_dl_is_supported(bts, MCS3) ? MCS3 :</span><br><span style="color: hsl(120, 100%, 40%);">+                            bts_cs_dl_is_supported(bts, MCS2) ? MCS2 :</span><br><span>                                   MCS1;</span><br><span>                     LOGPTBFDL(this, LOGL_DEBUG,</span><br><span>                            "Force downgrading DL %s -> %s due to USF for GPRS-only MS\n",</span><br><span>@@ -515,7 +515,7 @@</span><br><span>          LOGPTBFDL(this, LOGL_DEBUG, "Resending BSN %d\n", bsn);</span><br><span>            /* re-send block with negative aknowlegement */</span><br><span>              m_window.m_v_b.mark_unacked(bsn);</span><br><span style="color: hsl(0, 100%, 40%);">-               bts->do_rate_ctr_inc(CTR_RLC_RESENT);</span><br><span style="color: hsl(120, 100%, 40%);">+              bts_do_rate_ctr_inc(bts, CTR_RLC_RESENT);</span><br><span>    } else if (state_is(GPRS_RLCMAC_FINISHED)) {</span><br><span>                 /* If the TBF is in finished, we already sent all packages at least once.</span><br><span>             * If any packages could have been sent (because of unacked) it should have</span><br><span>@@ -523,7 +523,7 @@</span><br><span>            LOGPTBFDL(this, LOGL_DEBUG,</span><br><span>                    "Restarting at BSN %d, because all blocks have been transmitted.\n",</span><br><span>                       m_window.v_a());</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->do_rate_ctr_inc(CTR_RLC_RESTARTED);</span><br><span style="color: hsl(120, 100%, 40%);">+           bts_do_rate_ctr_inc(bts, CTR_RLC_RESTARTED);</span><br><span>                 if (restart_bsn_cycle())</span><br><span>                     return take_next_bsn(fn, previous_bsn, req_mcs_kind, may_combine);</span><br><span>   } else if (dl_window_stalled()) {</span><br><span>@@ -532,7 +532,7 @@</span><br><span>              LOGPTBFDL(this, LOGL_NOTICE,</span><br><span>                           "Restarting at BSN %d, because the window is stalled.\n",</span><br><span>                          m_window.v_a());</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->do_rate_ctr_inc(CTR_RLC_STALLED);</span><br><span style="color: hsl(120, 100%, 40%);">+             bts_do_rate_ctr_inc(bts, CTR_RLC_STALLED);</span><br><span>           if (restart_bsn_cycle())</span><br><span>                     return take_next_bsn(fn, previous_bsn, req_mcs_kind, may_combine);</span><br><span>   } else if (have_data()) {</span><br><span>@@ -551,7 +551,7 @@</span><br><span>              LOGPTBFDL(this, LOGL_DEBUG,</span><br><span>                    "Restarting at BSN %d, because all blocks have been transmitted (FLOW).\n",</span><br><span>                        m_window.v_a());</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->do_rate_ctr_inc(CTR_RLC_RESTARTED);</span><br><span style="color: hsl(120, 100%, 40%);">+           bts_do_rate_ctr_inc(bts, CTR_RLC_RESTARTED);</span><br><span>                 if (restart_bsn_cycle())</span><br><span>                     return take_next_bsn(fn, previous_bsn, req_mcs_kind, may_combine);</span><br><span>   } else {</span><br><span>@@ -568,8 +568,8 @@</span><br><span>               LOGPTBFDL(this, LOGL_DEBUG,</span><br><span>                    "Nothing else to send, Re-transmit final block!\n");</span><br><span>             bsn = m_window.v_s_mod(-1);</span><br><span style="color: hsl(0, 100%, 40%);">-             bts->do_rate_ctr_inc(CTR_RLC_FINAL_BLOCK_RESENT);</span><br><span style="color: hsl(0, 100%, 40%);">-            bts->do_rate_ctr_inc(CTR_RLC_RESENT);</span><br><span style="color: hsl(120, 100%, 40%);">+              bts_do_rate_ctr_inc(bts, CTR_RLC_FINAL_BLOCK_RESENT);</span><br><span style="color: hsl(120, 100%, 40%);">+         bts_do_rate_ctr_inc(bts, CTR_RLC_RESENT);</span><br><span>    }</span><br><span> </span><br><span>        *may_combine = num_data_blocks(mcs_header_type(m_rlc.block(bsn)->cs_current_trans)) > 1;</span><br><span>@@ -628,7 +628,7 @@</span><br><span>                 /* send immediate assignment */</span><br><span>              if ((pgroup = imsi2paging_group(imsi())) > 999)</span><br><span>                   LOGPTBFDL(this, LOGL_ERROR, "IMSI to paging group failed! (%s)\n", imsi());</span><br><span style="color: hsl(0, 100%, 40%);">-           bts->snd_dl_ass(this, false, pgroup);</span><br><span style="color: hsl(120, 100%, 40%);">+              bts_snd_dl_ass(bts, this, false, pgroup);</span><br><span>            m_wait_confirm = 1;</span><br><span>  }</span><br><span> }</span><br><span>@@ -648,7 +648,7 @@</span><br><span>         LOGPTBFDL(this, LOGL_DEBUG, "Dequeue next LLC (len=%d)\n", msg->len);</span><br><span> </span><br><span>       m_llc.put_frame(msg->data, msg->len);</span><br><span style="color: hsl(0, 100%, 40%);">-     bts->do_rate_ctr_inc(CTR_LLC_FRAME_SCHED);</span><br><span style="color: hsl(120, 100%, 40%);">+ bts_do_rate_ctr_inc(bts, CTR_LLC_FRAME_SCHED);</span><br><span>       msgb_free(msg);</span><br><span>      m_last_dl_drained_fn = -1;</span><br><span> }</span><br><span>@@ -742,14 +742,14 @@</span><br><span>                      &m_llc, &write_offset, &num_chunks, data, is_final, &payload_written);</span><br><span> </span><br><span>           if (payload_written > 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                     bts->do_rate_ctr_add(CTR_RLC_DL_PAYLOAD_BYTES, payload_written);</span><br><span style="color: hsl(120, 100%, 40%);">+                   bts_do_rate_ctr_add(bts, CTR_RLC_DL_PAYLOAD_BYTES, payload_written);</span><br><span> </span><br><span>             if (ar == Encoding::AR_NEED_MORE_BLOCKS)</span><br><span>                     break;</span><br><span> </span><br><span>           LOGPTBFDL(this, LOGL_DEBUG, "Complete DL frame, len=%d\n", llc_frame_length(&m_llc));</span><br><span>          gprs_rlcmac_dl_bw(this, llc_frame_length(&m_llc));</span><br><span style="color: hsl(0, 100%, 40%);">-          bts->do_rate_ctr_add(CTR_LLC_DL_BYTES, llc_frame_length(&m_llc));</span><br><span style="color: hsl(120, 100%, 40%);">+              bts_do_rate_ctr_add(bts, CTR_LLC_DL_BYTES, llc_frame_length(&m_llc));</span><br><span>            m_llc.reset();</span><br><span> </span><br><span>           if (is_final) {</span><br><span>@@ -1472,15 +1472,15 @@</span><br><span>             */</span><br><span>          if (block_status_dl == EGPRS_RESEG_FIRST_SEG_SENT) {</span><br><span>                         /* statistics */</span><br><span style="color: hsl(0, 100%, 40%);">-                        bts->do_rate_ctr_inc(CTR_SPB_DL_SECOND_SEGMENT);</span><br><span style="color: hsl(120, 100%, 40%);">+                   bts_do_rate_ctr_inc(bts, CTR_SPB_DL_SECOND_SEGMENT);</span><br><span>                         return EGPRS_RLCMAC_DL_SEC_SEG;</span><br><span>              } else if ((ht_cs_init == HEADER_EGPRS_DATA_TYPE_1) ||</span><br><span>                          (ht_cs_init == HEADER_EGPRS_DATA_TYPE_2)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                  bts->do_rate_ctr_inc(CTR_SPB_DL_FIRST_SEGMENT);</span><br><span style="color: hsl(120, 100%, 40%);">+                    bts_do_rate_ctr_inc(bts, CTR_SPB_DL_FIRST_SEGMENT);</span><br><span>                  return EGPRS_RLCMAC_DL_FIRST_SEG;</span><br><span>            } else if ((cs_init == MCS4) &&</span><br><span>                         (cs_current_trans == MCS1)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        bts->do_rate_ctr_inc(CTR_SPB_DL_FIRST_SEGMENT);</span><br><span style="color: hsl(120, 100%, 40%);">+                    bts_do_rate_ctr_inc(bts, CTR_SPB_DL_FIRST_SEGMENT);</span><br><span>                  return EGPRS_RLCMAC_DL_FIRST_SEG;</span><br><span>            }</span><br><span>    }</span><br><span>@@ -1490,7 +1490,7 @@</span><br><span> </span><br><span> void gprs_rlcmac_dl_tbf::set_window_size()</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-        const struct gprs_rlcmac_bts *b = bts->bts_data();</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct gprs_rlcmac_bts *b = bts;</span><br><span>       uint16_t ws = egprs_window_size(b, dl_slots());</span><br><span> </span><br><span>  LOGPTBFDL(this, LOGL_INFO, "setting EGPRS DL window size to %u, base(%u) slots(%u) ws_pdch(%u)\n",</span><br><span>@@ -1502,55 +1502,55 @@</span><br><span> {</span><br><span>  switch (cs) {</span><br><span>        case CS1:</span><br><span style="color: hsl(0, 100%, 40%);">-               bts->do_rate_ctr_inc(CTR_GPRS_DL_CS1);</span><br><span style="color: hsl(120, 100%, 40%);">+             bts_do_rate_ctr_inc(bts, CTR_GPRS_DL_CS1);</span><br><span>           rate_ctr_inc(&m_dl_gprs_ctrs->ctr[TBF_CTR_GPRS_DL_CS1]);</span><br><span>              break;</span><br><span>       case CS2:</span><br><span style="color: hsl(0, 100%, 40%);">-               bts->do_rate_ctr_inc(CTR_GPRS_DL_CS2);</span><br><span style="color: hsl(120, 100%, 40%);">+             bts_do_rate_ctr_inc(bts, CTR_GPRS_DL_CS2);</span><br><span>           rate_ctr_inc(&m_dl_gprs_ctrs->ctr[TBF_CTR_GPRS_DL_CS2]);</span><br><span>              break;</span><br><span>       case CS3:</span><br><span style="color: hsl(0, 100%, 40%);">-               bts->do_rate_ctr_inc(CTR_GPRS_DL_CS3);</span><br><span style="color: hsl(120, 100%, 40%);">+             bts_do_rate_ctr_inc(bts, CTR_GPRS_DL_CS3);</span><br><span>           rate_ctr_inc(&m_dl_gprs_ctrs->ctr[TBF_CTR_GPRS_DL_CS3]);</span><br><span>              break;</span><br><span>       case CS4:</span><br><span style="color: hsl(0, 100%, 40%);">-               bts->do_rate_ctr_inc(CTR_GPRS_DL_CS4);</span><br><span style="color: hsl(120, 100%, 40%);">+             bts_do_rate_ctr_inc(bts, CTR_GPRS_DL_CS4);</span><br><span>           rate_ctr_inc(&m_dl_gprs_ctrs->ctr[TBF_CTR_GPRS_DL_CS4]);</span><br><span>              break;</span><br><span>       case MCS1:</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS1);</span><br><span style="color: hsl(120, 100%, 40%);">+           bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS1);</span><br><span>                 rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS1]);</span><br><span>           break;</span><br><span>       case MCS2:</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS2);</span><br><span style="color: hsl(120, 100%, 40%);">+           bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS2);</span><br><span>                 rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS2]);</span><br><span>           break;</span><br><span>       case MCS3:</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS3);</span><br><span style="color: hsl(120, 100%, 40%);">+           bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS3);</span><br><span>                 rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS3]);</span><br><span>           break;</span><br><span>       case MCS4:</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS4);</span><br><span style="color: hsl(120, 100%, 40%);">+           bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS4);</span><br><span>                 rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS4]);</span><br><span>           break;</span><br><span>       case MCS5:</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS5);</span><br><span style="color: hsl(120, 100%, 40%);">+           bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS5);</span><br><span>                 rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS5]);</span><br><span>           break;</span><br><span>       case MCS6:</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS6);</span><br><span style="color: hsl(120, 100%, 40%);">+           bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS6);</span><br><span>                 rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS6]);</span><br><span>           break;</span><br><span>       case MCS7:</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS7);</span><br><span style="color: hsl(120, 100%, 40%);">+           bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS7);</span><br><span>                 rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS7]);</span><br><span>           break;</span><br><span>       case MCS8:</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS8);</span><br><span style="color: hsl(120, 100%, 40%);">+           bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS8);</span><br><span>                 rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS8]);</span><br><span>           break;</span><br><span>       case MCS9:</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS9);</span><br><span style="color: hsl(120, 100%, 40%);">+           bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS9);</span><br><span>                 rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS9]);</span><br><span>           break;</span><br><span>       default:</span><br><span>diff --git a/src/tbf_dl.h b/src/tbf_dl.h</span><br><span>index 3cd88c9..e29bb3f 100644</span><br><span>--- a/src/tbf_dl.h</span><br><span>+++ b/src/tbf_dl.h</span><br><span>@@ -39,7 +39,7 @@</span><br><span> #define LOGPTBFDL(tbf, level, fmt, args...) LOGP(DTBFDL, level, "%s " fmt, tbf_name(tbf), ## args)</span><br><span> </span><br><span> struct gprs_rlcmac_dl_tbf : public gprs_rlcmac_tbf {</span><br><span style="color: hsl(0, 100%, 40%);">-   gprs_rlcmac_dl_tbf(BTS *bts, GprsMs *ms);</span><br><span style="color: hsl(120, 100%, 40%);">+     gprs_rlcmac_dl_tbf(struct gprs_rlcmac_bts *bts, GprsMs *ms);</span><br><span>         gprs_rlc_window *window();</span><br><span>   void cleanup();</span><br><span>      /* dispatch Unitdata.DL messages */</span><br><span>diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp</span><br><span>index 1f3cb01..0c59a50 100644</span><br><span>--- a/src/tbf_ul.cpp</span><br><span>+++ b/src/tbf_ul.cpp</span><br><span>@@ -111,7 +111,7 @@</span><br><span>       if (!tbf)</span><br><span>            return NULL;</span><br><span>         talloc_set_destructor(tbf, ul_tbf_dtor);</span><br><span style="color: hsl(0, 100%, 40%);">-        new (tbf) gprs_rlcmac_ul_tbf(bts->bts, ms);</span><br><span style="color: hsl(120, 100%, 40%);">+        new (tbf) gprs_rlcmac_ul_tbf(bts, ms);</span><br><span> </span><br><span>   rc = tbf->setup(use_trx, single_slot);</span><br><span> </span><br><span>@@ -134,8 +134,8 @@</span><br><span>          return NULL;</span><br><span>         }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   llist_add(&tbf->list(), &bts->bts->ul_tbfs());</span><br><span style="color: hsl(0, 100%, 40%);">- tbf->bts->do_rate_ctr_inc(CTR_TBF_UL_ALLOCATED);</span><br><span style="color: hsl(120, 100%, 40%);">+        llist_add_tail(tbf_bts_list(tbf), &bts->ul_tbfs);</span><br><span style="color: hsl(120, 100%, 40%);">+      bts_do_rate_ctr_inc(tbf->bts, CTR_TBF_UL_ALLOCATED);</span><br><span> </span><br><span>  return tbf;</span><br><span> }</span><br><span>@@ -171,7 +171,7 @@</span><br><span>       struct gprs_rlcmac_trx *trx = &bts->trx[trx_no];</span><br><span> </span><br><span>  if (!ms)</span><br><span style="color: hsl(0, 100%, 40%);">-                ms = bts->bts->ms_alloc(0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+          ms = bts_alloc_ms(bts, 0, 0);</span><br><span>        ms_set_tlli(ms, tlli);</span><br><span> </span><br><span>   ul_tbf = talloc(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);</span><br><span>@@ -179,10 +179,10 @@</span><br><span>            return ul_tbf;</span><br><span> </span><br><span>   talloc_set_destructor(ul_tbf, ul_tbf_dtor);</span><br><span style="color: hsl(0, 100%, 40%);">-     new (ul_tbf) gprs_rlcmac_ul_tbf(bts->bts, ms);</span><br><span style="color: hsl(120, 100%, 40%);">+     new (ul_tbf) gprs_rlcmac_ul_tbf(bts, ms);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   llist_add(&ul_tbf->list(), &bts->bts->ul_tbfs());</span><br><span style="color: hsl(0, 100%, 40%);">-      ul_tbf->bts->do_rate_ctr_inc(CTR_TBF_UL_ALLOCATED);</span><br><span style="color: hsl(120, 100%, 40%);">+     llist_add(tbf_bts_list((struct gprs_rlcmac_tbf *)ul_tbf), &bts->ul_tbfs);</span><br><span style="color: hsl(120, 100%, 40%);">+      bts_do_rate_ctr_inc(ul_tbf->bts, CTR_TBF_UL_ALLOCATED);</span><br><span>   TBF_SET_ASS_ON(ul_tbf, GPRS_RLCMAC_FLAG_PACCH, false);</span><br><span> </span><br><span>   ms_attach_tbf(ms, ul_tbf);</span><br><span>@@ -206,7 +206,7 @@</span><br><span>     return ul_tbf;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-gprs_rlcmac_ul_tbf::gprs_rlcmac_ul_tbf(BTS *bts_, GprsMs *ms) :</span><br><span style="color: hsl(120, 100%, 40%);">+gprs_rlcmac_ul_tbf::gprs_rlcmac_ul_tbf(struct gprs_rlcmac_bts *bts_, GprsMs *ms) :</span><br><span>   gprs_rlcmac_tbf(bts_, ms, GPRS_RLCMAC_UL_TBF),</span><br><span>       m_rx_counter(0),</span><br><span>     m_contention_resolution_done(0),</span><br><span>@@ -243,7 +243,7 @@</span><br><span>               frame = frames + i;</span><br><span> </span><br><span>              if (frame->length) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 bts->do_rate_ctr_add(CTR_RLC_UL_PAYLOAD_BYTES, frame->length);</span><br><span style="color: hsl(120, 100%, 40%);">+                  bts_do_rate_ctr_add(bts, CTR_RLC_UL_PAYLOAD_BYTES, frame->length);</span><br><span> </span><br><span>                    LOGPTBFUL(this, LOGL_DEBUG, "Frame %d "</span><br><span>                            "starts at offset %d, "</span><br><span>@@ -259,7 +259,7 @@</span><br><span>                      /* send frame to SGSN */</span><br><span>                     LOGPTBFUL(this, LOGL_DEBUG, "complete UL frame len=%d\n", llc_frame_length(&m_llc));</span><br><span>                   snd_ul_ud();</span><br><span style="color: hsl(0, 100%, 40%);">-                    bts->do_rate_ctr_add(CTR_LLC_UL_BYTES, llc_frame_length(&m_llc));</span><br><span style="color: hsl(120, 100%, 40%);">+                      bts_do_rate_ctr_add(bts, CTR_LLC_UL_BYTES, llc_frame_length(&m_llc));</span><br><span>                    m_llc.reset();</span><br><span>               }</span><br><span>    }</span><br><span>@@ -440,7 +440,7 @@</span><br><span>                              rdbi, rlc->cs, rlc_data, NULL, 0, &new_tlli);</span><br><span> </span><br><span>                     if (num_chunks < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                bts->do_rate_ctr_inc(CTR_DECODE_ERRORS);</span><br><span style="color: hsl(120, 100%, 40%);">+                           bts_do_rate_ctr_inc(bts, CTR_DECODE_ERRORS);</span><br><span>                                 LOGPTBFUL(this, LOGL_NOTICE,</span><br><span>                                           "Failed to decode TLLI of %s UL DATA TFI=%d.\n",</span><br><span>                                           mcs_name(rlc->cs), rlc->tfi);</span><br><span>@@ -589,7 +589,7 @@</span><br><span>  union split_block_status *spb_status = &block->spb_status;</span><br><span>    uint8_t *rlc_data = &block->block[0];</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        bts->do_rate_ctr_inc(CTR_SPB_UL_SECOND_SEGMENT);</span><br><span style="color: hsl(120, 100%, 40%);">+        bts_do_rate_ctr_inc(bts, CTR_SPB_UL_SECOND_SEGMENT);</span><br><span> </span><br><span>        if (spb_status->block_status_ul &</span><br><span>                             EGPRS_RESEG_FIRST_SEG_RXD) {</span><br><span>@@ -622,7 +622,7 @@</span><br><span>   uint8_t *rlc_data = &block->block[0];</span><br><span>         union split_block_status *spb_status = &block->spb_status;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   bts->do_rate_ctr_inc(CTR_SPB_UL_FIRST_SEGMENT);</span><br><span style="color: hsl(120, 100%, 40%);">+    bts_do_rate_ctr_inc(bts, CTR_SPB_UL_FIRST_SEGMENT);</span><br><span> </span><br><span>      if (spb_status->block_status_ul & EGPRS_RESEG_SECOND_SEG_RXD) {</span><br><span>               LOGPTBFUL(this, LOGL_DEBUG,</span><br><span>@@ -702,55 +702,55 @@</span><br><span> {</span><br><span>     switch (cs) {</span><br><span>        case CS1:</span><br><span style="color: hsl(0, 100%, 40%);">-               bts->do_rate_ctr_inc(CTR_GPRS_UL_CS1);</span><br><span style="color: hsl(120, 100%, 40%);">+             bts_do_rate_ctr_inc(bts, CTR_GPRS_UL_CS1);</span><br><span>           rate_ctr_inc(&m_ul_gprs_ctrs->ctr[TBF_CTR_GPRS_UL_CS1]);</span><br><span>              break;</span><br><span>       case CS2:</span><br><span style="color: hsl(0, 100%, 40%);">-               bts->do_rate_ctr_inc(CTR_GPRS_UL_CS2);</span><br><span style="color: hsl(120, 100%, 40%);">+             bts_do_rate_ctr_inc(bts, CTR_GPRS_UL_CS2);</span><br><span>           rate_ctr_inc(&m_ul_gprs_ctrs->ctr[TBF_CTR_GPRS_UL_CS2]);</span><br><span>              break;</span><br><span>       case CS3:</span><br><span style="color: hsl(0, 100%, 40%);">-               bts->do_rate_ctr_inc(CTR_GPRS_UL_CS3);</span><br><span style="color: hsl(120, 100%, 40%);">+             bts_do_rate_ctr_inc(bts, CTR_GPRS_UL_CS3);</span><br><span>           rate_ctr_inc(&m_ul_gprs_ctrs->ctr[TBF_CTR_GPRS_UL_CS3]);</span><br><span>              break;</span><br><span>       case CS4:</span><br><span style="color: hsl(0, 100%, 40%);">-               bts->do_rate_ctr_inc(CTR_GPRS_UL_CS4);</span><br><span style="color: hsl(120, 100%, 40%);">+             bts_do_rate_ctr_inc(bts, CTR_GPRS_UL_CS4);</span><br><span>           rate_ctr_inc(&m_ul_gprs_ctrs->ctr[TBF_CTR_GPRS_UL_CS4]);</span><br><span>              break;</span><br><span>       case MCS1:</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS1);</span><br><span style="color: hsl(120, 100%, 40%);">+           bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS1);</span><br><span>                 rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS1]);</span><br><span>           break;</span><br><span>       case MCS2:</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS2);</span><br><span style="color: hsl(120, 100%, 40%);">+           bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS2);</span><br><span>                 rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS2]);</span><br><span>           break;</span><br><span>       case MCS3:</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS3);</span><br><span style="color: hsl(120, 100%, 40%);">+           bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS3);</span><br><span>                 rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS3]);</span><br><span>           break;</span><br><span>       case MCS4:</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS4);</span><br><span style="color: hsl(120, 100%, 40%);">+           bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS4);</span><br><span>                 rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS4]);</span><br><span>           break;</span><br><span>       case MCS5:</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS5);</span><br><span style="color: hsl(120, 100%, 40%);">+           bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS5);</span><br><span>                 rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS5]);</span><br><span>           break;</span><br><span>       case MCS6:</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS6);</span><br><span style="color: hsl(120, 100%, 40%);">+           bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS6);</span><br><span>                 rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS6]);</span><br><span>           break;</span><br><span>       case MCS7:</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS7);</span><br><span style="color: hsl(120, 100%, 40%);">+           bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS7);</span><br><span>                 rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS7]);</span><br><span>           break;</span><br><span>       case MCS8:</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS8);</span><br><span style="color: hsl(120, 100%, 40%);">+           bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS8);</span><br><span>                 rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS8]);</span><br><span>           break;</span><br><span>       case MCS9:</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS9);</span><br><span style="color: hsl(120, 100%, 40%);">+           bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS9);</span><br><span>                 rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS9]);</span><br><span>           break;</span><br><span>       default:</span><br><span>@@ -761,7 +761,7 @@</span><br><span> </span><br><span> void gprs_rlcmac_ul_tbf::set_window_size()</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   const struct gprs_rlcmac_bts *b = bts->bts_data();</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct gprs_rlcmac_bts *b = bts;</span><br><span>       uint16_t ws = egprs_window_size(b, ul_slots());</span><br><span>      LOGPTBFUL(this, LOGL_INFO, "setting EGPRS UL window size to %u, base(%u) slots(%u) ws_pdch(%u)\n",</span><br><span>                   ws, bts->pcu->vty.ws_base, pcu_bitcount(ul_slots()), bts->pcu->vty.ws_pdch);</span><br><span>diff --git a/src/tbf_ul.h b/src/tbf_ul.h</span><br><span>index 1d9cf50..8713596 100644</span><br><span>--- a/src/tbf_ul.h</span><br><span>+++ b/src/tbf_ul.h</span><br><span>@@ -50,7 +50,7 @@</span><br><span> #define LOGPTBFUL(tbf, level, fmt, args...) LOGP(DTBFUL, level, "%s " fmt, tbf_name(tbf), ## args)</span><br><span> </span><br><span> struct gprs_rlcmac_ul_tbf : public gprs_rlcmac_tbf {</span><br><span style="color: hsl(0, 100%, 40%);">- gprs_rlcmac_ul_tbf(BTS *bts, GprsMs *ms);</span><br><span style="color: hsl(120, 100%, 40%);">+     gprs_rlcmac_ul_tbf(struct gprs_rlcmac_bts *bts, GprsMs *ms);</span><br><span>         gprs_rlc_window *window();</span><br><span>   struct msgb *create_ul_ack(uint32_t fn, uint8_t ts);</span><br><span>         bool ctrl_ack_to_toggle();</span><br><span>diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp</span><br><span>index 249c268..20f5286 100644</span><br><span>--- a/tests/alloc/AllocTest.cpp</span><br><span>+++ b/tests/alloc/AllocTest.cpp</span><br><span>@@ -21,7 +21,9 @@</span><br><span> #include "gprs_debug.h"</span><br><span> #include "tbf.h"</span><br><span> #include "tbf_ul.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "tbf_dl.h"</span><br><span> #include "bts.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "gprs_ms.h"</span><br><span> </span><br><span> #include <string.h></span><br><span> #include <stdio.h></span><br><span>@@ -51,17 +53,17 @@</span><br><span>          return tbf_alloc_dl_tbf(bts, ms, use_trx, single_slot);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void check_tfi_usage(BTS *the_bts)</span><br><span style="color: hsl(120, 100%, 40%);">+static void check_tfi_usage(struct gprs_rlcmac_bts *bts)</span><br><span> {</span><br><span>     int pdch_no;</span><br><span> </span><br><span>     struct gprs_rlcmac_tbf *tfi_usage[8][8][2][32] = {{{{NULL}}}};</span><br><span style="color: hsl(0, 100%, 40%);">-  LListHead<gprs_rlcmac_tbf> *tbf_lists[2] = {</span><br><span style="color: hsl(0, 100%, 40%);">-              &the_bts->ul_tbfs(),</span><br><span style="color: hsl(0, 100%, 40%);">-             &the_bts->dl_tbfs()</span><br><span style="color: hsl(120, 100%, 40%);">+    struct llist_head *tbf_lists[2] = {</span><br><span style="color: hsl(120, 100%, 40%);">+           &bts->ul_tbfs,</span><br><span style="color: hsl(120, 100%, 40%);">+         &bts->dl_tbfs</span><br><span>         };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  LListHead<gprs_rlcmac_tbf> *pos;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct llist_item *pos;</span><br><span>      gprs_rlcmac_tbf *tbf;</span><br><span>        unsigned list_idx;</span><br><span>   struct gprs_rlcmac_tbf **tbf_var;</span><br><span>@@ -69,8 +71,8 @@</span><br><span>        for (list_idx = 0; list_idx < ARRAY_SIZE(tbf_lists); list_idx += 1)</span><br><span>       {</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-           llist_for_each(pos, tbf_lists[list_idx]) {</span><br><span style="color: hsl(0, 100%, 40%);">-                      tbf = pos->entry();</span><br><span style="color: hsl(120, 100%, 40%);">+                llist_for_each_entry(pos, tbf_lists[list_idx], list) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        tbf = (struct gprs_rlcmac_tbf *)pos->entry;</span><br><span>                       for (pdch_no = 0; pdch_no < 8; pdch_no += 1) {</span><br><span>                            struct gprs_rlcmac_pdch *pdch = tbf->pdch[pdch_no];</span><br><span>                               if (pdch == NULL)</span><br><span>@@ -86,14 +88,14 @@</span><br><span>                              if (tbf->direction == GPRS_RLCMAC_DL_TBF) {</span><br><span>                                       OSMO_ASSERT(pdch->dl_tbf_by_tfi(</span><br><span>                                                  tbf->tfi()) == tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-                                 OSMO_ASSERT(the_bts->dl_tbf_by_tfi(</span><br><span style="color: hsl(120, 100%, 40%);">+                                        OSMO_ASSERT(bts_dl_tbf_by_tfi(bts,</span><br><span>                                                   tbf->tfi(),</span><br><span>                                                       tbf->trx->trx_no,</span><br><span>                                                      pdch_no) == tbf);</span><br><span>                            } else {</span><br><span>                                     OSMO_ASSERT(pdch->ul_tbf_by_tfi(</span><br><span>                                                  tbf->tfi()) == tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-                                 OSMO_ASSERT(the_bts->ul_tbf_by_tfi(</span><br><span style="color: hsl(120, 100%, 40%);">+                                        OSMO_ASSERT(bts_ul_tbf_by_tfi(bts,</span><br><span>                                                   tbf->tfi(),</span><br><span>                                                       tbf->trx->trx_no,</span><br><span>                                                      pdch_no) == tbf);</span><br><span>@@ -112,14 +114,12 @@</span><br><span>    int tfi;</span><br><span>     int i;</span><br><span>       uint8_t used_trx, tmp_trx;</span><br><span style="color: hsl(0, 100%, 40%);">-      BTS the_bts(the_pcu);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);</span><br><span>    GprsMs *ms;</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gprs_rlcmac_bts *bts;</span><br><span>         struct gprs_rlcmac_tbf *tbfs[32*8+1] = { 0, };</span><br><span> </span><br><span>   printf("Testing alloc_a direction(%d)\n", dir);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   bts = the_bts.bts_data();</span><br><span>    the_pcu->alloc_algorithm = alloc_algorithm_a;</span><br><span> </span><br><span>         struct gprs_rlcmac_trx *trx = &bts->trx[0];</span><br><span>@@ -136,17 +136,17 @@</span><br><span>    * least this part is working okay.</span><br><span>   */</span><br><span>  for (i = 0; i < (int)ARRAY_SIZE(tbfs); ++i) {</span><br><span style="color: hsl(0, 100%, 40%);">-                ms = bts->bts->ms_alloc(0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+          ms = bts_alloc_ms(bts, 0, 0);</span><br><span>                tbfs[i] = tbf_alloc(bts, ms, dir, -1, 0);</span><br><span>            if (tbfs[i] == NULL)</span><br><span>                         break;</span><br><span> </span><br><span>           used_trx = tbfs[i]->trx->trx_no;</span><br><span style="color: hsl(0, 100%, 40%);">-          tfi = the_bts.tfi_find_free(dir, &tmp_trx, used_trx);</span><br><span style="color: hsl(120, 100%, 40%);">+             tfi = bts_tfi_find_free(bts, dir, &tmp_trx, used_trx);</span><br><span>           OSMO_ASSERT(tbfs[i]->tfi() != tfi);</span><br><span>       }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   check_tfi_usage(&the_bts);</span><br><span style="color: hsl(120, 100%, 40%);">+        check_tfi_usage(bts);</span><br><span> </span><br><span>    OSMO_ASSERT(i == count);</span><br><span> </span><br><span>@@ -154,10 +154,11 @@</span><br><span>                 if (tbfs[i])</span><br><span>                         tbf_free(tbfs[i]);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  ms = bts->bts->ms_alloc(0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+  ms = bts_alloc_ms(bts, 0, 0);</span><br><span>        tbfs[0] = tbf_alloc(bts, ms, dir, -1, 0);</span><br><span>    OSMO_ASSERT(tbfs[0]);</span><br><span>        tbf_free(tbfs[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+    talloc_free(bts);</span><br><span> }</span><br><span> </span><br><span> static void test_alloc_a()</span><br><span>@@ -205,8 +206,7 @@</span><br><span> static inline bool test_alloc_b_ul_dl(bool ts0, bool ts1, bool ts2, bool ts3, bool ts4, bool ts5, bool ts6, bool ts7,</span><br><span>                                    uint8_t ms_class, bool verbose)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      BTS the_bts(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gprs_rlcmac_bts *bts = the_bts.bts_data();</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);</span><br><span>    GprsMs *ms;</span><br><span>  gprs_rlcmac_ul_tbf *ul_tbf;</span><br><span>  gprs_rlcmac_dl_tbf *dl_tbf;</span><br><span>@@ -218,7 +218,7 @@</span><br><span> </span><br><span>        enable_ts_on_bts(bts, ts0, ts1, ts2, ts3, ts4, ts5, ts6, ts7);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      ms = the_bts.ms_alloc(ms_class, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+   ms = bts_alloc_ms(bts, ms_class, 0);</span><br><span>         /* Avoid delaying free to avoid tons of to-be-freed ms objects queuing */</span><br><span>    ms_set_timeout(ms, 0);</span><br><span>       ul_tbf = tbf_alloc_ul_tbf(bts, ms, -1, true);</span><br><span>@@ -239,19 +239,18 @@</span><br><span> </span><br><span>    OSMO_ASSERT(dl_tbf->first_common_ts == ul_tbf->first_common_ts);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      check_tfi_usage(&the_bts);</span><br><span style="color: hsl(120, 100%, 40%);">+        check_tfi_usage(bts);</span><br><span> </span><br><span>    tbf_free(dl_tbf);</span><br><span>    tbf_free(ul_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+     talloc_free(bts);</span><br><span>    return true;</span><br><span> }</span><br><span> </span><br><span> static inline bool test_alloc_b_dl_ul(bool ts0, bool ts1, bool ts2, bool ts3, bool ts4, bool ts5, bool ts6, bool ts7,</span><br><span>                                     uint8_t ms_class, bool verbose)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      BTS the_bts(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gprs_rlcmac_bts *bts = the_bts.bts_data();</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);</span><br><span>    GprsMs *ms;</span><br><span>  gprs_rlcmac_ul_tbf *ul_tbf;</span><br><span>  gprs_rlcmac_dl_tbf *dl_tbf;</span><br><span>@@ -263,7 +262,7 @@</span><br><span> </span><br><span>        enable_ts_on_bts(bts, ts0, ts1, ts2, ts3, ts4, ts5, ts6, ts7);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      ms = the_bts.ms_alloc(ms_class, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+   ms = bts_alloc_ms(bts, ms_class, 0);</span><br><span>         /* Avoid delaying free to avoid tons of to-be-freed ms objects queuing */</span><br><span>    ms_set_timeout(ms, 0);</span><br><span>       dl_tbf = tbf_alloc_dl_tbf(bts, ms, -1, true);</span><br><span>@@ -292,18 +291,17 @@</span><br><span>        dump_assignment(dl_tbf, "DL", verbose);</span><br><span>    OSMO_ASSERT(dl_tbf->first_common_ts == ul_tbf->first_common_ts);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      check_tfi_usage(&the_bts);</span><br><span style="color: hsl(120, 100%, 40%);">+        check_tfi_usage(bts);</span><br><span> </span><br><span>    tbf_free(dl_tbf);</span><br><span>    tbf_free(ul_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+     talloc_free(bts);</span><br><span>    return true;</span><br><span> }</span><br><span> </span><br><span> static inline bool test_alloc_b_jolly(uint8_t ms_class)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS the_bts(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gprs_rlcmac_bts *bts = the_bts.bts_data();</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);</span><br><span>    GprsMs *ms;</span><br><span>  int tfi;</span><br><span>     uint8_t trx_no;</span><br><span>@@ -315,9 +313,9 @@</span><br><span> </span><br><span>    enable_ts_on_bts(bts, false, true, true, true, true, false, false, false);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+     tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);</span><br><span>   OSMO_ASSERT(tfi >= 0);</span><br><span style="color: hsl(0, 100%, 40%);">-       ms = the_bts.ms_alloc(ms_class, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+   ms = bts_alloc_ms(bts, ms_class, 0);</span><br><span>         /* Avoid delaying free to avoid tons of to-be-freed ms objects queuing */</span><br><span>    ms_set_timeout(ms, 0);</span><br><span>       ul_tbf = tbf_alloc_ul_tbf(bts, ms, -1, false);</span><br><span>@@ -338,11 +336,11 @@</span><br><span> </span><br><span>   OSMO_ASSERT(dl_tbf->first_common_ts == ul_tbf->first_common_ts);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      check_tfi_usage(&the_bts);</span><br><span style="color: hsl(120, 100%, 40%);">+        check_tfi_usage(bts);</span><br><span> </span><br><span>    tbf_free(dl_tbf);</span><br><span>    tbf_free(ul_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+     talloc_free(bts);</span><br><span>    return true;</span><br><span> }</span><br><span> </span><br><span>@@ -459,16 +457,13 @@</span><br><span>        }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static GprsMs *alloc_tbfs(BTS *the_bts, struct GprsMs *old_ms, enum test_mode mode)</span><br><span style="color: hsl(120, 100%, 40%);">+static GprsMs *alloc_tbfs(struct gprs_rlcmac_bts *bts, struct GprsMs *old_ms, enum test_mode mode)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  struct gprs_rlcmac_bts *bts;</span><br><span>         struct GprsMs *ms, *new_ms;</span><br><span>  uint8_t trx_no = -1;</span><br><span> </span><br><span>     OSMO_ASSERT(old_ms != NULL);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        bts = the_bts->bts_data();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>        gprs_rlcmac_tbf *tbf = NULL;</span><br><span> </span><br><span>     if (ms_current_trx(old_ms))</span><br><span>@@ -517,12 +512,12 @@</span><br><span> </span><br><span>      case TEST_MODE_DL_AFTER_UL:</span><br><span>  case TEST_MODE_UL_AND_DL:</span><br><span style="color: hsl(0, 100%, 40%);">-               new_ms = alloc_tbfs(the_bts, ms, TEST_MODE_DL_ONLY);</span><br><span style="color: hsl(120, 100%, 40%);">+          new_ms = alloc_tbfs(bts, ms, TEST_MODE_DL_ONLY);</span><br><span>             break;</span><br><span> </span><br><span>   case TEST_MODE_UL_AFTER_DL:</span><br><span>  case TEST_MODE_DL_AND_UL:</span><br><span style="color: hsl(0, 100%, 40%);">-               new_ms = alloc_tbfs(the_bts, ms, TEST_MODE_UL_ONLY);</span><br><span style="color: hsl(120, 100%, 40%);">+          new_ms = alloc_tbfs(bts, ms, TEST_MODE_UL_ONLY);</span><br><span>             break;</span><br><span>       }</span><br><span> </span><br><span>@@ -546,7 +541,7 @@</span><br><span>  return new_ms;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static unsigned alloc_many_tbfs(BTS *the_bts, unsigned min_class,</span><br><span style="color: hsl(120, 100%, 40%);">+static unsigned alloc_many_tbfs(struct gprs_rlcmac_bts *bts, unsigned min_class,</span><br><span>   unsigned max_class, enum test_mode mode)</span><br><span> {</span><br><span>        unsigned counter;</span><br><span>@@ -566,11 +561,11 @@</span><br><span>            enum gprs_rlcmac_tbf_direction dir;</span><br><span>          uint32_t tlli = counter + 0xc0000000;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-               ms = the_bts->ms_by_tlli(tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+            ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);</span><br><span>           if (!ms)</span><br><span style="color: hsl(0, 100%, 40%);">-                        ms = the_bts->ms_alloc(0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+                      ms = bts_alloc_ms(bts, 0, 0);</span><br><span>                ms_set_ms_class(ms, ms_class);</span><br><span style="color: hsl(0, 100%, 40%);">-          ms = alloc_tbfs(the_bts, ms, mode);</span><br><span style="color: hsl(120, 100%, 40%);">+           ms = alloc_tbfs(bts, ms, mode);</span><br><span>              if (!ms)</span><br><span>                     break;</span><br><span> </span><br><span>@@ -630,7 +625,7 @@</span><br><span> </span><br><span>                 if (tfi >= 0) {</span><br><span>                   OSMO_ASSERT(ms_current_trx(ms));</span><br><span style="color: hsl(0, 100%, 40%);">-                        tfi2 = the_bts->tfi_find_free(dir, &trx_no2,</span><br><span style="color: hsl(120, 100%, 40%);">+                   tfi2 = bts_tfi_find_free(bts, dir, &trx_no2,</span><br><span>                             ms_current_trx(ms)->trx_no);</span><br><span>                      OSMO_ASSERT(tfi != tfi2);</span><br><span>                    OSMO_ASSERT(tfi2 < 0 ||</span><br><span>@@ -649,15 +644,13 @@</span><br><span>   unsigned max_class, enum test_mode mode,</span><br><span>     unsigned expect_num, const char *text)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-     BTS the_bts(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gprs_rlcmac_bts *bts;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);</span><br><span>    struct gprs_rlcmac_trx *trx;</span><br><span>         unsigned counter;</span><br><span> </span><br><span>        printf("Going to test assignment with many TBF, algorithm %s class %u..%u (%s)\n",</span><br><span>                text, min_class, max_class, test_mode_descr(mode));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  bts = the_bts.bts_data();</span><br><span>    the_pcu->alloc_algorithm = algo;</span><br><span> </span><br><span>      trx = &bts->trx[0];</span><br><span>@@ -667,7 +660,7 @@</span><br><span>     trx->pdch[6].enable();</span><br><span>    trx->pdch[7].enable();</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   counter = alloc_many_tbfs(&the_bts, min_class, max_class, mode);</span><br><span style="color: hsl(120, 100%, 40%);">+  counter = alloc_many_tbfs(bts, min_class, max_class, mode);</span><br><span> </span><br><span>      printf("  Successfully allocated %u UL TBFs, algorithm %s class %u..%u (%s)\n",</span><br><span>           counter, text, min_class, max_class, test_mode_descr(mode));</span><br><span>@@ -677,14 +670,14 @@</span><br><span> </span><br><span>      OSMO_ASSERT(counter == expect_num);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- check_tfi_usage(&the_bts);</span><br><span style="color: hsl(120, 100%, 40%);">+        check_tfi_usage(bts);</span><br><span style="color: hsl(120, 100%, 40%);">+ talloc_free(bts);</span><br><span> }</span><br><span> </span><br><span> static void test_many_connections(algo_t algo, unsigned expect_num,</span><br><span>    const char *text)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  BTS the_bts(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gprs_rlcmac_bts *bts;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);</span><br><span>    struct gprs_rlcmac_trx *trx;</span><br><span>         int counter1, counter2 = -1;</span><br><span>         unsigned i;</span><br><span>@@ -697,7 +690,6 @@</span><br><span> </span><br><span>        printf("Going to test assignment with many connections, algorithm %s\n", text);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   bts = the_bts.bts_data();</span><br><span>    the_pcu->alloc_algorithm = algo;</span><br><span> </span><br><span>      trx = &bts->trx[0];</span><br><span>@@ -708,11 +700,11 @@</span><br><span>   trx->pdch[7].enable();</span><br><span> </span><br><span>        for (i = 0; i < ARRAY_SIZE(mode_seq); i += 1) {</span><br><span style="color: hsl(0, 100%, 40%);">-              counter1 = alloc_many_tbfs(&the_bts, 1, mslot_class_max(), mode_seq[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+          counter1 = alloc_many_tbfs(bts, 1, mslot_class_max(), mode_seq[i]);</span><br><span>          fprintf(stderr, "  Allocated %d TBFs (previously %d)\n",</span><br><span>                   counter1, counter2);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                check_tfi_usage(&the_bts);</span><br><span style="color: hsl(120, 100%, 40%);">+                check_tfi_usage(bts);</span><br><span> </span><br><span>            /* This will stop earlier due to USF shortage */</span><br><span>             if (mode_seq[i] == TEST_MODE_UL_ONLY)</span><br><span>@@ -733,6 +725,7 @@</span><br><span>          fprintf(stderr, "  Expected %d TBFs (got %d) for algorithm %s\n", expect_num, counter1, text);</span><br><span> </span><br><span>         OSMO_ASSERT(expect_num == (unsigned)counter1);</span><br><span style="color: hsl(120, 100%, 40%);">+        talloc_free(bts);</span><br><span> }</span><br><span> </span><br><span> static inline void test_a_b_dyn(enum test_mode mode, uint8_t exp_A, uint8_t exp_B, uint8_t exp_dyn)</span><br><span>@@ -761,9 +754,8 @@</span><br><span> </span><br><span> static void test_2_consecutive_dl_tbfs()</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-    BTS the_bts(the_pcu);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);</span><br><span>    GprsMs *ms;</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gprs_rlcmac_bts *bts;</span><br><span>         struct gprs_rlcmac_trx *trx;</span><br><span>         uint8_t ms_class = 11;</span><br><span>       uint8_t egprs_ms_class = 11;</span><br><span>@@ -772,7 +764,6 @@</span><br><span> </span><br><span>       printf("Testing DL TS allocation for Multi UEs\n");</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       bts = the_bts.bts_data();</span><br><span>    the_pcu->alloc_algorithm = alloc_algorithm_b;</span><br><span> </span><br><span>         trx = &bts->trx[0];</span><br><span>@@ -781,7 +772,7 @@</span><br><span>     trx->pdch[6].enable();</span><br><span>    trx->pdch[7].enable();</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ms = the_bts.ms_alloc(ms_class, egprs_ms_class);</span><br><span style="color: hsl(120, 100%, 40%);">+      ms = bts_alloc_ms(bts, ms_class, egprs_ms_class);</span><br><span>    dl_tbf1 = tbf_alloc_dl_tbf(bts, ms, 0, false);</span><br><span>       OSMO_ASSERT(dl_tbf1);</span><br><span> </span><br><span>@@ -792,7 +783,7 @@</span><br><span>      OSMO_ASSERT(numTs1 == 4);</span><br><span>    printf("TBF1: numTs(%d)\n", numTs1);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      ms = the_bts.ms_alloc(ms_class, egprs_ms_class);</span><br><span style="color: hsl(120, 100%, 40%);">+      ms = bts_alloc_ms(bts, ms_class, egprs_ms_class);</span><br><span>    dl_tbf2 = tbf_alloc_dl_tbf(bts, ms, 0, false);</span><br><span>       OSMO_ASSERT(dl_tbf2);</span><br><span> </span><br><span>@@ -810,6 +801,7 @@</span><br><span> </span><br><span>  tbf_free(dl_tbf1);</span><br><span>   tbf_free(dl_tbf2);</span><br><span style="color: hsl(120, 100%, 40%);">+    talloc_free(bts);</span><br><span> }</span><br><span> </span><br><span> int main(int argc, char **argv)</span><br><span>diff --git a/tests/alloc/MslotTest.cpp b/tests/alloc/MslotTest.cpp</span><br><span>index e354641..b32a828 100644</span><br><span>--- a/tests/alloc/MslotTest.cpp</span><br><span>+++ b/tests/alloc/MslotTest.cpp</span><br><span>@@ -62,15 +62,12 @@</span><br><span> </span><br><span> static inline void test_multislot_total_ascending(bool seq)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-    BTS the_bts(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gprs_rlcmac_bts *bts;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);</span><br><span>    struct gprs_rlcmac_trx *trx;</span><br><span>         int i;</span><br><span> </span><br><span>   printf("%s(): %s\n", __func__, seq ? "sequential" : "accumulative");</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  bts = the_bts.bts_data();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>    trx = &bts->trx[0];</span><br><span> </span><br><span>       for (i = 0; i < 8; i++) {</span><br><span>@@ -79,19 +76,17 @@</span><br><span> </span><br><span>               test_all_classes(trx, seq);</span><br><span>  }</span><br><span style="color: hsl(120, 100%, 40%);">+     talloc_free(bts);</span><br><span> }</span><br><span> </span><br><span> static inline void test_multislot_total_descending(bool seq)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- BTS the_bts(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gprs_rlcmac_bts *bts;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);</span><br><span>    struct gprs_rlcmac_trx *trx;</span><br><span>         int i;</span><br><span> </span><br><span>   printf("%s(): %s\n", __func__, seq ? "sequential" : "accumulative");</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  bts = the_bts.bts_data();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>    trx = &bts->trx[0];</span><br><span> </span><br><span>       for (i = 7; i >= 0; i--) {</span><br><span>@@ -100,18 +95,16 @@</span><br><span> </span><br><span>             test_all_classes(trx, seq);</span><br><span>  }</span><br><span style="color: hsl(120, 100%, 40%);">+     talloc_free(bts);</span><br><span> }</span><br><span> </span><br><span> static inline void test_multislot_middle(bool seq)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS the_bts(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gprs_rlcmac_bts *bts;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);</span><br><span>    struct gprs_rlcmac_trx *trx;</span><br><span> </span><br><span>     printf("%s(): %s\n", __func__, seq ? "sequential" : "accumulative");</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  bts = the_bts.bts_data();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>    trx = &bts->trx[0];</span><br><span> </span><br><span>       trx->pdch[2].enable();</span><br><span>@@ -119,24 +112,23 @@</span><br><span>    trx->pdch[4].enable();</span><br><span> </span><br><span>        test_all_classes(trx, seq);</span><br><span style="color: hsl(120, 100%, 40%);">+   talloc_free(bts);</span><br><span> }</span><br><span> </span><br><span> static inline void test_multislot_ends(bool seq)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-     BTS the_bts(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gprs_rlcmac_bts *bts;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);</span><br><span>    struct gprs_rlcmac_trx *trx;</span><br><span> </span><br><span>     printf("%s(): %s\n", __func__, seq ? "sequential" : "accumulative");</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  bts = the_bts.bts_data();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>    trx = &bts->trx[0];</span><br><span> </span><br><span>       trx->pdch[0].enable();</span><br><span>    trx->pdch[7].enable();</span><br><span> </span><br><span>        test_all_classes(trx, seq);</span><br><span style="color: hsl(120, 100%, 40%);">+   talloc_free(bts);</span><br><span> }</span><br><span> </span><br><span> static inline void test_window_wrapper()</span><br><span>diff --git a/tests/app_info/AppInfoTest.cpp b/tests/app_info/AppInfoTest.cpp</span><br><span>index 962ead4..e0b2853 100644</span><br><span>--- a/tests/app_info/AppInfoTest.cpp</span><br><span>+++ b/tests/app_info/AppInfoTest.cpp</span><br><span>@@ -20,6 +20,7 @@</span><br><span> #include <assert.h></span><br><span> #include "gprs_rlcmac.h"</span><br><span> #include "bts.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "tbf_dl.h"</span><br><span> </span><br><span> extern "C" {</span><br><span> #include <osmocom/vty/telnet_interface.h></span><br><span>@@ -77,25 +78,23 @@</span><br><span> </span><br><span> void prepare_bts_with_two_dl_tbf_subscr()</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-    BTS *bts = BTS::main_bts();</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gprs_rlcmac_bts *bts_data;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       struct gprs_rlcmac_trx *trx;</span><br><span> </span><br><span>     fprintf(stderr, "--- %s ---\n",  __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       bts_data = bts->bts_data();</span><br><span>       the_pcu->alloc_algorithm = alloc_algorithm_b;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    trx = bts_data->trx;</span><br><span style="color: hsl(120, 100%, 40%);">+       trx = bts->trx;</span><br><span>   trx->pdch[4].enable();</span><br><span>    trx->pdch[5].enable();</span><br><span>    trx->pdch[6].enable();</span><br><span>    trx->pdch[7].enable();</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ms1 = bts->ms_alloc(10, 11);</span><br><span style="color: hsl(0, 100%, 40%);">- tbf1 = tbf_alloc_dl_tbf(bts_data, ms1, 0, false);</span><br><span style="color: hsl(0, 100%, 40%);">-       ms2 = bts->ms_alloc(12, 13);</span><br><span style="color: hsl(0, 100%, 40%);">- tbf2 = tbf_alloc_dl_tbf(bts_data, ms2, 0, false);</span><br><span style="color: hsl(120, 100%, 40%);">+     ms1 = bts_alloc_ms(bts, 10, 11);</span><br><span style="color: hsl(120, 100%, 40%);">+      tbf1 = tbf_alloc_dl_tbf(bts, ms1, 0, false);</span><br><span style="color: hsl(120, 100%, 40%);">+  ms2 = bts_alloc_ms(bts, 12, 13);</span><br><span style="color: hsl(120, 100%, 40%);">+      tbf2 = tbf_alloc_dl_tbf(bts, ms2, 0, false);</span><br><span> </span><br><span>     fprintf(stderr, "\n");</span><br><span> }</span><br><span>@@ -122,15 +121,15 @@</span><br><span> </span><br><span> void test_sched_app_info_missing_app_info_in_bts(const struct gsm_pcu_if_app_info_req *req)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gprs_rlcmac_bts *bts_data = BTS::main_bts()->bts_data();</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       struct gsm_pcu_if pcu_prim = {PCU_IF_MSG_APP_INFO_REQ, };</span><br><span> </span><br><span>        fprintf(stderr, "--- %s ---\n",  __func__);</span><br><span>        pcu_prim.u.app_info_req = *req;</span><br><span>      pcu_rx(PCU_IF_MSG_APP_INFO_REQ, &pcu_prim);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     msgb_free(bts_data->app_info);</span><br><span style="color: hsl(0, 100%, 40%);">-       bts_data->app_info = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_free(bts->app_info);</span><br><span style="color: hsl(120, 100%, 40%);">+  bts->app_info = NULL;</span><br><span> </span><br><span>         assert(sched_app_info(tbf1) == NULL);</span><br><span> </span><br><span>@@ -154,8 +153,8 @@</span><br><span> </span><br><span>  tbf_free(tbf1);</span><br><span>      tbf_free(tbf2);</span><br><span style="color: hsl(0, 100%, 40%);">- BTS::main_bts()->cleanup();</span><br><span style="color: hsl(0, 100%, 40%);">-  /* FIXME: talloc report disabled, because bts->ms_alloc() in prepare_bts_with_two_dl_tbf_subscr() causes leak */</span><br><span style="color: hsl(120, 100%, 40%);">+   TALLOC_FREE(the_pcu->bts);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* FIXME: talloc report disabled, because bts_alloc_ms(bts, ) in prepare_bts_with_two_dl_tbf_subscr() causes leak */</span><br><span>         /* talloc_report_full(tall_pcu_ctx, stderr); */</span><br><span>      talloc_free(the_pcu);</span><br><span>        talloc_free(tall_pcu_ctx);</span><br><span>diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp</span><br><span>index c5ce730..d67646e 100644</span><br><span>--- a/tests/edge/EdgeTest.cpp</span><br><span>+++ b/tests/edge/EdgeTest.cpp</span><br><span>@@ -1151,19 +1151,17 @@</span><br><span>        printf("=== end %s ===\n", __func__);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void setup_bts(BTS *the_bts, uint8_t ts_no, uint8_t cs = 1)</span><br><span style="color: hsl(120, 100%, 40%);">+static void setup_bts(struct gprs_rlcmac_bts *bts, uint8_t ts_no, uint8_t cs = 1)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      gprs_rlcmac_bts *bts;</span><br><span>        gprs_rlcmac_trx *trx;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       bts = the_bts->bts_data();</span><br><span>        the_pcu->alloc_algorithm = alloc_algorithm_a;</span><br><span>     bts->initial_cs_dl = cs;</span><br><span>  bts->initial_cs_ul = cs;</span><br><span>  trx = &bts->trx[0];</span><br><span>   trx->pdch[ts_no].enable();</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">-static void uplink_header_type_2_parsing_test(BTS *the_bts,</span><br><span style="color: hsl(120, 100%, 40%);">+static void uplink_header_type_2_parsing_test(struct gprs_rlcmac_bts *bts,</span><br><span>    uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,</span><br><span>    uint8_t ms_class)</span><br><span> {</span><br><span>@@ -1254,7 +1252,7 @@</span><br><span> </span><br><span> static void uplink_header_type2_test(void)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS the_bts(the_pcu);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);</span><br><span>    int ts_no = 7;</span><br><span>       uint32_t fn = 2654218;</span><br><span>       uint16_t qta = 31;</span><br><span>@@ -1262,14 +1260,15 @@</span><br><span>         uint8_t ms_class = 1;</span><br><span> </span><br><span>    printf("=== start %s ===\n", __func__);</span><br><span style="color: hsl(0, 100%, 40%);">-       setup_bts(&the_bts, ts_no, 10);</span><br><span style="color: hsl(120, 100%, 40%);">+   setup_bts(bts, ts_no, 10);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  uplink_header_type_2_parsing_test(&the_bts, ts_no,</span><br><span style="color: hsl(120, 100%, 40%);">+        uplink_header_type_2_parsing_test(bts, ts_no,</span><br><span>                        tlli, &fn, qta, ms_class);</span><br><span>       printf("=== end %s ===\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+       talloc_free(bts);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void uplink_header_type_1_parsing_test(BTS *the_bts,</span><br><span style="color: hsl(120, 100%, 40%);">+static void uplink_header_type_1_parsing_test(struct gprs_rlcmac_bts *bts,</span><br><span>    uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,</span><br><span>    uint8_t ms_class)</span><br><span> {</span><br><span>@@ -1371,7 +1370,7 @@</span><br><span> </span><br><span> void uplink_header_type1_test(void)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  BTS the_bts(the_pcu);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_bts  *bts = bts_alloc(the_pcu);</span><br><span>   int ts_no = 7;</span><br><span>       uint32_t fn = 2654218;</span><br><span>       uint16_t qta = 31;</span><br><span>@@ -1379,8 +1378,8 @@</span><br><span>   uint8_t ms_class = 1;</span><br><span> </span><br><span>    printf("=== start %s ===\n", __func__);</span><br><span style="color: hsl(0, 100%, 40%);">-       setup_bts(&the_bts, ts_no, 12);</span><br><span style="color: hsl(0, 100%, 40%);">-     uplink_header_type_1_parsing_test(&the_bts, ts_no, tlli, &fn,</span><br><span style="color: hsl(120, 100%, 40%);">+ setup_bts(bts, ts_no, 12);</span><br><span style="color: hsl(120, 100%, 40%);">+    uplink_header_type_1_parsing_test(bts, ts_no, tlli, &fn,</span><br><span>                         qta, ms_class);</span><br><span>      printf("=== end %s ===\n", __func__);</span><br><span> }</span><br><span>diff --git a/tests/emu/pcu_emu.cpp b/tests/emu/pcu_emu.cpp</span><br><span>index 2336e67..ab2804b 100644</span><br><span>--- a/tests/emu/pcu_emu.cpp</span><br><span>+++ b/tests/emu/pcu_emu.cpp</span><br><span>@@ -142,7 +142,7 @@</span><br><span>  init_pcu(pcu);</span><br><span>       init_main_bts();</span><br><span>     bssgp_set_bssgp_callback(gprs_gp_send_cb, pcu->nsi);</span><br><span style="color: hsl(0, 100%, 40%);">- create_and_connect_bssgp(bts_data(pcu->bts), INADDR_LOOPBACK, 23000);</span><br><span style="color: hsl(120, 100%, 40%);">+      create_and_connect_bssgp(pcu->bts, INADDR_LOOPBACK, 23000);</span><br><span> </span><br><span>   for (;;)</span><br><span>             osmo_select_main(0);</span><br><span>diff --git a/tests/fn/FnTest.cpp b/tests/fn/FnTest.cpp</span><br><span>index 3185bd5..dd30b34 100644</span><br><span>--- a/tests/fn/FnTest.cpp</span><br><span>+++ b/tests/fn/FnTest.cpp</span><br><span>@@ -36,24 +36,24 @@</span><br><span> int16_t spoof_mnc = 0, spoof_mcc = 0;</span><br><span> bool spoof_mnc_3_digits = false;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static uint32_t calc_fn(BTS * bts, uint32_t rfn)</span><br><span style="color: hsl(120, 100%, 40%);">+static uint32_t calc_fn(struct gprs_rlcmac_bts * bts, uint32_t rfn)</span><br><span> {</span><br><span>       uint32_t fn;</span><br><span style="color: hsl(0, 100%, 40%);">-    fn = bts->rfn_to_fn(rfn);</span><br><span style="color: hsl(120, 100%, 40%);">+  fn = bts_rfn_to_fn(bts, rfn);</span><br><span>        printf("rfn=%i ==> fn=%i\n", rfn, fn);</span><br><span>  return fn;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void set_fn(BTS * bts, uint32_t fn)</span><br><span style="color: hsl(120, 100%, 40%);">+static void set_fn(struct gprs_rlcmac_bts * bts, uint32_t fn)</span><br><span> {</span><br><span>    printf("\n");</span><br><span style="color: hsl(0, 100%, 40%);">- bts->set_current_frame_number(fn);</span><br><span style="color: hsl(120, 100%, 40%);">+ bts_set_current_frame_number(bts, fn);</span><br><span>       printf("bts: fn=%i\n", fn);</span><br><span> }</span><br><span> </span><br><span> static void run_test()</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS bts(the_pcu);</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);</span><br><span>    uint32_t fn;</span><br><span> </span><br><span>     printf("RFN_MODULUS=%i\n",RFN_MODULUS);</span><br><span>@@ -63,20 +63,20 @@</span><br><span>      /* Test with a collection of real world examples,</span><br><span>     * all all of them are not critical and do not</span><br><span>        * assume the occurence of any race contions */</span><br><span style="color: hsl(0, 100%, 40%);">- set_fn(&bts, 1320462);</span><br><span style="color: hsl(0, 100%, 40%);">-      fn = calc_fn(&bts, 5066);</span><br><span style="color: hsl(120, 100%, 40%);">+ set_fn(bts, 1320462);</span><br><span style="color: hsl(120, 100%, 40%);">+ fn = calc_fn(bts, 5066);</span><br><span>     OSMO_ASSERT(fn == 1320458);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- set_fn(&bts, 8246);</span><br><span style="color: hsl(0, 100%, 40%);">- fn = calc_fn(&bts, 8244);</span><br><span style="color: hsl(120, 100%, 40%);">+ set_fn(bts, 8246);</span><br><span style="color: hsl(120, 100%, 40%);">+    fn = calc_fn(bts, 8244);</span><br><span>     OSMO_ASSERT(fn == 8244);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    set_fn(&bts, 10270);</span><br><span style="color: hsl(0, 100%, 40%);">-        fn = calc_fn(&bts, 10269);</span><br><span style="color: hsl(120, 100%, 40%);">+        set_fn(bts, 10270);</span><br><span style="color: hsl(120, 100%, 40%);">+   fn = calc_fn(bts, 10269);</span><br><span>    OSMO_ASSERT(fn == 10269);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   set_fn(&bts, 311276);</span><br><span style="color: hsl(0, 100%, 40%);">-       fn = calc_fn(&bts, 14250);</span><br><span style="color: hsl(120, 100%, 40%);">+        set_fn(bts, 311276);</span><br><span style="color: hsl(120, 100%, 40%);">+  fn = calc_fn(bts, 14250);</span><br><span>    OSMO_ASSERT(fn == 311274);</span><br><span> </span><br><span> </span><br><span>@@ -84,20 +84,20 @@</span><br><span>      * just wrapped over a little bit above the</span><br><span>   * modulo 42432 raster, but the rach request</span><br><span>          * occurred before the wrapping */</span><br><span style="color: hsl(0, 100%, 40%);">-      set_fn(&bts, RFN_MODULUS + 30);</span><br><span style="color: hsl(0, 100%, 40%);">-     fn = calc_fn(&bts, RFN_MODULUS - 10);</span><br><span style="color: hsl(120, 100%, 40%);">+     set_fn(bts, RFN_MODULUS + 30);</span><br><span style="color: hsl(120, 100%, 40%);">+        fn = calc_fn(bts, RFN_MODULUS - 10);</span><br><span>         OSMO_ASSERT(fn == 42422);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   set_fn(&bts, RFN_MODULUS + 1);</span><br><span style="color: hsl(0, 100%, 40%);">-      fn = calc_fn(&bts, RFN_MODULUS - 1);</span><br><span style="color: hsl(120, 100%, 40%);">+      set_fn(bts, RFN_MODULUS + 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ fn = calc_fn(bts, RFN_MODULUS - 1);</span><br><span>  OSMO_ASSERT(fn == 42431);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   set_fn(&bts, RFN_MODULUS * 123 + 16);</span><br><span style="color: hsl(0, 100%, 40%);">-       fn = calc_fn(&bts, RFN_MODULUS - 4);</span><br><span style="color: hsl(120, 100%, 40%);">+      set_fn(bts, RFN_MODULUS * 123 + 16);</span><br><span style="color: hsl(120, 100%, 40%);">+  fn = calc_fn(bts, RFN_MODULUS - 4);</span><br><span>  OSMO_ASSERT(fn == 5219132);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- set_fn(&bts, RFN_MODULUS * 123 + 451);</span><br><span style="color: hsl(0, 100%, 40%);">-      fn = calc_fn(&bts, RFN_MODULUS - 175);</span><br><span style="color: hsl(120, 100%, 40%);">+    set_fn(bts, RFN_MODULUS * 123 + 451);</span><br><span style="color: hsl(120, 100%, 40%);">+ fn = calc_fn(bts, RFN_MODULUS - 175);</span><br><span>        OSMO_ASSERT(fn == 5218961);</span><br><span> </span><br><span> </span><br><span>@@ -105,41 +105,42 @@</span><br><span>   * the BTS just wrapped its internal frame number</span><br><span>     * but we still get rach requests with high relative</span><br><span>          * frame numbers. */</span><br><span style="color: hsl(0, 100%, 40%);">-    set_fn(&bts, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-    fn = calc_fn(&bts, RFN_MODULUS - 13);</span><br><span style="color: hsl(120, 100%, 40%);">+     set_fn(bts, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+       fn = calc_fn(bts, RFN_MODULUS - 13);</span><br><span>         OSMO_ASSERT(fn == 2715635);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- set_fn(&bts, 453);</span><br><span style="color: hsl(0, 100%, 40%);">-  fn = calc_fn(&bts, RFN_MODULUS - 102);</span><br><span style="color: hsl(120, 100%, 40%);">+    set_fn(bts, 453);</span><br><span style="color: hsl(120, 100%, 40%);">+     fn = calc_fn(bts, RFN_MODULUS - 102);</span><br><span>        OSMO_ASSERT(fn == 2715546);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- set_fn(&bts, 10);</span><br><span style="color: hsl(0, 100%, 40%);">-   fn = calc_fn(&bts, RFN_MODULUS - 10);</span><br><span style="color: hsl(120, 100%, 40%);">+     set_fn(bts, 10);</span><br><span style="color: hsl(120, 100%, 40%);">+      fn = calc_fn(bts, RFN_MODULUS - 10);</span><br><span>         OSMO_ASSERT(fn == 2715638);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- set_fn(&bts, 23);</span><br><span style="color: hsl(0, 100%, 40%);">-   fn = calc_fn(&bts, RFN_MODULUS - 42);</span><br><span style="color: hsl(120, 100%, 40%);">+     set_fn(bts, 23);</span><br><span style="color: hsl(120, 100%, 40%);">+      fn = calc_fn(bts, RFN_MODULUS - 42);</span><br><span>         OSMO_ASSERT(fn == 2715606);</span><br><span> </span><br><span> </span><br><span>  /* Also check with some corner case</span><br><span>   * values where Fn and RFn reach its</span><br><span>          * maximum/minimum valid range */</span><br><span style="color: hsl(0, 100%, 40%);">-       set_fn(&bts, GSM_MAX_FN);</span><br><span style="color: hsl(0, 100%, 40%);">-   fn = calc_fn(&bts, RFN_MODULUS-1);</span><br><span style="color: hsl(120, 100%, 40%);">+        set_fn(bts, GSM_MAX_FN);</span><br><span style="color: hsl(120, 100%, 40%);">+      fn = calc_fn(bts, RFN_MODULUS-1);</span><br><span>    OSMO_ASSERT(fn == GSM_MAX_FN-1);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    set_fn(&bts, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-    fn = calc_fn(&bts, RFN_MODULUS-1);</span><br><span style="color: hsl(120, 100%, 40%);">+        set_fn(bts, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+       fn = calc_fn(bts, RFN_MODULUS-1);</span><br><span>    OSMO_ASSERT(fn == GSM_MAX_FN-1);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    set_fn(&bts, GSM_MAX_FN);</span><br><span style="color: hsl(0, 100%, 40%);">-   fn = calc_fn(&bts, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+    set_fn(bts, GSM_MAX_FN);</span><br><span style="color: hsl(120, 100%, 40%);">+      fn = calc_fn(bts, 0);</span><br><span>        OSMO_ASSERT(fn == GSM_MAX_FN);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      set_fn(&bts, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-    fn = calc_fn(&bts, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+    set_fn(bts, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+       fn = calc_fn(bts, 0);</span><br><span>        OSMO_ASSERT(fn == 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ talloc_free(bts);</span><br><span> }</span><br><span> </span><br><span> int main(int argc, char **argv)</span><br><span>diff --git a/tests/ms/MsTest.cpp b/tests/ms/MsTest.cpp</span><br><span>index d6c8f18..58579f8 100644</span><br><span>--- a/tests/ms/MsTest.cpp</span><br><span>+++ b/tests/ms/MsTest.cpp</span><br><span>@@ -51,18 +51,18 @@</span><br><span>         uint32_t tlli = 0xffeeddbb;</span><br><span>  gprs_rlcmac_dl_tbf *dl_tbf;</span><br><span>  gprs_rlcmac_ul_tbf *ul_tbf;</span><br><span style="color: hsl(0, 100%, 40%);">-     BTS the_bts(the_pcu);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);</span><br><span>    GprsMs *ms;</span><br><span> </span><br><span>      printf("=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ms = ms_alloc(&the_bts, tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+    ms = ms_alloc(bts, tlli);</span><br><span>    OSMO_ASSERT(ms_is_idle(ms));</span><br><span> </span><br><span>     dl_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-  new (dl_tbf) gprs_rlcmac_dl_tbf(&the_bts, ms);</span><br><span style="color: hsl(120, 100%, 40%);">+    new (dl_tbf) gprs_rlcmac_dl_tbf(bts, ms);</span><br><span>    ul_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-  new (ul_tbf) gprs_rlcmac_ul_tbf(&the_bts, ms);</span><br><span style="color: hsl(120, 100%, 40%);">+    new (ul_tbf) gprs_rlcmac_ul_tbf(bts, ms);</span><br><span> </span><br><span>        ms_attach_tbf(ms, ul_tbf);</span><br><span>   OSMO_ASSERT(!ms_is_idle(ms));</span><br><span>@@ -88,7 +88,7 @@</span><br><span> </span><br><span>        talloc_free(dl_tbf);</span><br><span>         talloc_free(ul_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+  talloc_free(bts);</span><br><span>    printf("=== end %s ===\n", __func__);</span><br><span> }</span><br><span> </span><br><span>@@ -114,21 +114,21 @@</span><br><span>     uint32_t tlli = 0xffeeddbb;</span><br><span>  gprs_rlcmac_dl_tbf *dl_tbf;</span><br><span>  gprs_rlcmac_ul_tbf *ul_tbf;</span><br><span style="color: hsl(0, 100%, 40%);">-     BTS the_bts(the_pcu);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);</span><br><span>    GprsMs *ms;</span><br><span>  last_cb = CB_UNKNOWN;</span><br><span> </span><br><span>    printf("=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ms = ms_alloc(&the_bts, tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+    ms = ms_alloc(bts, tlli);</span><br><span>    ms_set_callback(ms, &ms_cb);</span><br><span> </span><br><span>         OSMO_ASSERT(ms_is_idle(ms));</span><br><span> </span><br><span>     dl_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-  new (dl_tbf) gprs_rlcmac_dl_tbf(&the_bts, ms);</span><br><span style="color: hsl(120, 100%, 40%);">+    new (dl_tbf) gprs_rlcmac_dl_tbf(bts, ms);</span><br><span>    ul_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-  new (ul_tbf) gprs_rlcmac_ul_tbf(&the_bts, ms);</span><br><span style="color: hsl(120, 100%, 40%);">+    new (ul_tbf) gprs_rlcmac_ul_tbf(bts, ms);</span><br><span> </span><br><span>        OSMO_ASSERT(last_cb == CB_UNKNOWN);</span><br><span> </span><br><span>@@ -163,7 +163,7 @@</span><br><span> </span><br><span>    talloc_free(dl_tbf);</span><br><span>         talloc_free(ul_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+  talloc_free(bts);</span><br><span>    printf("=== end %s ===\n", __func__);</span><br><span> }</span><br><span> </span><br><span>@@ -188,23 +188,23 @@</span><br><span>     uint32_t tlli = 0xffeeddbb;</span><br><span>  gprs_rlcmac_dl_tbf *dl_tbf[2];</span><br><span>       gprs_rlcmac_ul_tbf *ul_tbf;</span><br><span style="color: hsl(0, 100%, 40%);">-     BTS the_bts(the_pcu);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);</span><br><span>    GprsMs *ms;</span><br><span> </span><br><span>      printf("=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ms = ms_alloc(&the_bts, tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+    ms = ms_alloc(bts, tlli);</span><br><span>    ms_set_callback(ms, &ms_replace_tbf_cb);</span><br><span> </span><br><span>     OSMO_ASSERT(ms_is_idle(ms));</span><br><span>         was_idle = false;</span><br><span> </span><br><span>        dl_tbf[0] = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-       new (dl_tbf[0]) gprs_rlcmac_dl_tbf(&the_bts, ms);</span><br><span style="color: hsl(120, 100%, 40%);">+ new (dl_tbf[0]) gprs_rlcmac_dl_tbf(bts, ms);</span><br><span>         dl_tbf[1] = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-       new (dl_tbf[1]) gprs_rlcmac_dl_tbf(&the_bts, ms);</span><br><span style="color: hsl(120, 100%, 40%);">+ new (dl_tbf[1]) gprs_rlcmac_dl_tbf(bts, ms);</span><br><span>         ul_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-  new (ul_tbf) gprs_rlcmac_ul_tbf(&the_bts, ms);</span><br><span style="color: hsl(120, 100%, 40%);">+    new (ul_tbf) gprs_rlcmac_ul_tbf(bts, ms);</span><br><span> </span><br><span>        ms_attach_tbf(ms, dl_tbf[0]);</span><br><span>        OSMO_ASSERT(!ms_is_idle(ms));</span><br><span>@@ -253,7 +253,7 @@</span><br><span>  talloc_free(dl_tbf[0]);</span><br><span>      talloc_free(dl_tbf[1]);</span><br><span>      talloc_free(ul_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+  talloc_free(bts);</span><br><span>    printf("=== end %s ===\n", __func__);</span><br><span> }</span><br><span> </span><br><span>@@ -262,12 +262,12 @@</span><br><span>     uint32_t start_tlli = 0xaa000000;</span><br><span>    uint32_t new_ms_tlli = 0xff001111;</span><br><span>   uint32_t other_sgsn_tlli = 0xff00eeee;</span><br><span style="color: hsl(0, 100%, 40%);">-  BTS the_bts(the_pcu);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);</span><br><span>    GprsMs *ms;</span><br><span> </span><br><span>      printf("=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ms = ms_alloc(&the_bts, start_tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+      ms = ms_alloc(bts, start_tlli);</span><br><span> </span><br><span>  OSMO_ASSERT(ms_is_idle(ms));</span><br><span> </span><br><span>@@ -347,7 +347,7 @@</span><br><span>       OSMO_ASSERT(!ms_check_tlli(ms, start_tlli));</span><br><span> </span><br><span>     talloc_free(ms);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+      talloc_free(bts);</span><br><span>    printf("=== end %s ===\n", __func__);</span><br><span> }</span><br><span> </span><br><span>@@ -374,9 +374,9 @@</span><br><span>       const char *imsi2 = "001001987654322";</span><br><span> </span><br><span>         gprs_rlcmac_ul_tbf *ul_tbf;</span><br><span style="color: hsl(0, 100%, 40%);">-     BTS the_bts(the_pcu);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);</span><br><span>    GprsMs *ms, *ms_tmp;</span><br><span style="color: hsl(0, 100%, 40%);">-    GprsMsStorage store(&the_bts);</span><br><span style="color: hsl(120, 100%, 40%);">+    GprsMsStorage store(bts);</span><br><span> </span><br><span>        printf("=== start %s ===\n", __func__);</span><br><span> </span><br><span>@@ -420,7 +420,7 @@</span><br><span>  ms = store.get_ms(tlli + 0);</span><br><span>         OSMO_ASSERT(ms != NULL);</span><br><span>     ul_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-  new (ul_tbf) gprs_rlcmac_ul_tbf(&the_bts, ms);</span><br><span style="color: hsl(120, 100%, 40%);">+    new (ul_tbf) gprs_rlcmac_ul_tbf(bts, ms);</span><br><span>    ms_attach_tbf(ms, ul_tbf);</span><br><span>   ms_detach_tbf(ms, ul_tbf);</span><br><span>   ms = store.get_ms(tlli + 0);</span><br><span>@@ -437,7 +437,7 @@</span><br><span>   OSMO_ASSERT(ms == NULL);</span><br><span> </span><br><span>         talloc_free(ul_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+  talloc_free(bts);</span><br><span>    printf("=== end %s ===\n", __func__);</span><br><span> }</span><br><span> </span><br><span>@@ -446,22 +446,22 @@</span><br><span>     uint32_t tlli = 0xffeeddbb;</span><br><span>  gprs_rlcmac_dl_tbf *dl_tbf;</span><br><span>  gprs_rlcmac_ul_tbf *ul_tbf;</span><br><span style="color: hsl(0, 100%, 40%);">-     BTS the_bts(the_pcu);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);</span><br><span>    GprsMs *ms;</span><br><span>  last_cb = CB_UNKNOWN;</span><br><span> </span><br><span>    printf("=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ms = ms_alloc(&the_bts, tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+    ms = ms_alloc(bts, tlli);</span><br><span>    ms_set_callback(ms, &ms_cb);</span><br><span>     ms_set_timeout(ms, 1);</span><br><span> </span><br><span>   OSMO_ASSERT(ms_is_idle(ms));</span><br><span> </span><br><span>     dl_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-  new (dl_tbf) gprs_rlcmac_dl_tbf(&the_bts, ms);</span><br><span style="color: hsl(120, 100%, 40%);">+    new (dl_tbf) gprs_rlcmac_dl_tbf(bts, ms);</span><br><span>    ul_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-  new (ul_tbf) gprs_rlcmac_ul_tbf(&the_bts, ms);</span><br><span style="color: hsl(120, 100%, 40%);">+    new (ul_tbf) gprs_rlcmac_ul_tbf(bts, ms);</span><br><span> </span><br><span>        OSMO_ASSERT(last_cb == CB_UNKNOWN);</span><br><span> </span><br><span>@@ -493,14 +493,13 @@</span><br><span>      talloc_free(ms);</span><br><span>     talloc_free(dl_tbf);</span><br><span>         talloc_free(ul_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+  talloc_free(bts);</span><br><span>    printf("=== end %s ===\n", __func__);</span><br><span> }</span><br><span> </span><br><span> static void test_ms_cs_selection()</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-     BTS the_bts(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   gprs_rlcmac_bts *bts = the_bts.bts_data();</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);</span><br><span>    uint32_t tlli = 0xffeeddbb;</span><br><span> </span><br><span>      gprs_rlcmac_dl_tbf *dl_tbf;</span><br><span>@@ -513,12 +512,12 @@</span><br><span>  the_pcu->vty.cs_downgrade_threshold = 0;</span><br><span>  the_pcu->vty.cs_adj_lower_limit = 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     ms = ms_alloc(&the_bts, tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+    ms = ms_alloc(bts, tlli);</span><br><span> </span><br><span>        OSMO_ASSERT(ms_is_idle(ms));</span><br><span> </span><br><span>     dl_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-  new (dl_tbf) gprs_rlcmac_dl_tbf(&the_bts, ms);</span><br><span style="color: hsl(120, 100%, 40%);">+    new (dl_tbf) gprs_rlcmac_dl_tbf(bts, ms);</span><br><span>    ms_attach_tbf(ms, dl_tbf);</span><br><span> </span><br><span>       OSMO_ASSERT(!ms_is_idle(ms));</span><br><span>@@ -530,7 +529,7 @@</span><br><span>  OSMO_ASSERT(mcs_chan_code(ms_current_cs_dl(ms)) == 2);</span><br><span> </span><br><span>   talloc_free(dl_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+  talloc_free(bts);</span><br><span>    printf("=== end %s ===\n", __func__);</span><br><span> }</span><br><span> </span><br><span>@@ -545,8 +544,7 @@</span><br><span> </span><br><span> static void test_ms_mcs_mode()</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-       BTS the_bts(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   gprs_rlcmac_bts *bts = the_bts.bts_data();</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);</span><br><span>    uint32_t tlli = 0xdeadbeef;</span><br><span> </span><br><span>      gprs_rlcmac_dl_tbf *dl_tbf;</span><br><span>@@ -554,18 +552,18 @@</span><br><span> </span><br><span>      printf("=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ms1 = ms_alloc(&the_bts, tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+   ms1 = ms_alloc(bts, tlli);</span><br><span>   dump_ms(ms1, "1: no BTS defaults  ");</span><br><span> </span><br><span>  bts->initial_cs_dl = 4;</span><br><span>   bts->initial_cs_ul = 1;</span><br><span>   the_pcu->vty.cs_downgrade_threshold = 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- ms2 = ms_alloc(&the_bts, tlli + 1);</span><br><span style="color: hsl(120, 100%, 40%);">+       ms2 = ms_alloc(bts, tlli + 1);</span><br><span>       dump_ms(ms2, "2: with BTS defaults");</span><br><span> </span><br><span>  dl_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-  new (dl_tbf) gprs_rlcmac_dl_tbf(&the_bts, ms2);</span><br><span style="color: hsl(120, 100%, 40%);">+   new (dl_tbf) gprs_rlcmac_dl_tbf(bts, ms2);</span><br><span>   ms_attach_tbf(ms2, dl_tbf);</span><br><span> </span><br><span>      dump_ms(ms2, "2: after TBF attach ");</span><br><span>@@ -599,7 +597,7 @@</span><br><span>        dump_ms(ms2, "2: after mode set   ");</span><br><span> </span><br><span>  talloc_free(dl_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+  talloc_free(bts);</span><br><span>    printf("=== end %s ===\n", __func__);</span><br><span> }</span><br><span> </span><br><span>diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp</span><br><span>index 1b85201..ef26862 100644</span><br><span>--- a/tests/tbf/TbfTest.cpp</span><br><span>+++ b/tests/tbf/TbfTest.cpp</span><br><span>@@ -22,8 +22,11 @@</span><br><span> </span><br><span> #include "bts.h"</span><br><span> #include "tbf.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "tbf_dl.h"</span><br><span> #include "tbf_ul.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "gprs_ms.h"</span><br><span> #include "gprs_debug.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "gprs_ms_storage.h"</span><br><span> #include "pcu_utils.h"</span><br><span> #include "gprs_bssgp_pcu.h"</span><br><span> #include "pcu_l1_if.h"</span><br><span>@@ -54,7 +57,7 @@</span><br><span> /* Measurements shared by all unit tests */</span><br><span> static struct pcu_l1_meas meas;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int bts_handle_rach(BTS *bts, uint16_t ra, uint32_t Fn, int16_t qta)</span><br><span style="color: hsl(120, 100%, 40%);">+static int bts_handle_rach(struct gprs_rlcmac_bts *bts, uint16_t ra, uint32_t Fn, int16_t qta)</span><br><span> {</span><br><span>       struct rach_ind_params rip = {</span><br><span>               .burst_type = GSM_L1_BURST_TYPE_ACCESS_0,</span><br><span>@@ -66,7 +69,7 @@</span><br><span>                .qta = qta,</span><br><span>  };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  return bts->rcv_rach(&rip);</span><br><span style="color: hsl(120, 100%, 40%);">+    return bts_rcv_rach(bts, &rip);</span><br><span> }</span><br><span> </span><br><span> static void check_tbf(gprs_rlcmac_tbf *tbf)</span><br><span>@@ -93,20 +96,20 @@</span><br><span> {</span><br><span>       the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       GprsMs *ms, *ms_new;</span><br><span> </span><br><span>     fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span>       the_pcu->alloc_algorithm = alloc_algorithm_a;</span><br><span style="color: hsl(0, 100%, 40%);">-        the_bts->bts_data()->trx[0].pdch[2].enable();</span><br><span style="color: hsl(0, 100%, 40%);">-     the_bts->bts_data()->trx[0].pdch[3].enable();</span><br><span style="color: hsl(120, 100%, 40%);">+   bts->trx[0].pdch[2].enable();</span><br><span style="color: hsl(120, 100%, 40%);">+      bts->trx[0].pdch[3].enable();</span><br><span> </span><br><span>         /*</span><br><span>    * Make a uplink and downlink allocation</span><br><span>      */</span><br><span style="color: hsl(0, 100%, 40%);">-     ms = the_bts->ms_alloc(0, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-        gprs_rlcmac_tbf *dl_tbf = tbf_alloc_dl_tbf(the_bts->bts_data(),</span><br><span style="color: hsl(120, 100%, 40%);">+    ms = bts_alloc_ms(bts, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ gprs_rlcmac_tbf *dl_tbf = tbf_alloc_dl_tbf(bts,</span><br><span>                                              ms, 0, false);</span><br><span>       OSMO_ASSERT(dl_tbf != NULL);</span><br><span>         dl_tbf->update_ms(0x2342, GPRS_RLCMAC_DL_TBF);</span><br><span>@@ -114,14 +117,14 @@</span><br><span>    OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf);</span><br><span>        OSMO_ASSERT(dl_tbf->ms() == ms);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- gprs_rlcmac_tbf *ul_tbf = tbf_alloc_ul_tbf(the_bts->bts_data(),</span><br><span style="color: hsl(120, 100%, 40%);">+    gprs_rlcmac_tbf *ul_tbf = tbf_alloc_ul_tbf(bts,</span><br><span>                                                 ms, 0, false);</span><br><span>    OSMO_ASSERT(ul_tbf != NULL);</span><br><span>         ul_tbf->update_ms(0x2342, GPRS_RLCMAC_UL_TBF);</span><br><span>    OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);</span><br><span>        OSMO_ASSERT(ul_tbf->ms() == ms);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_ASSERT(the_bts->ms_by_tlli(0x2342) == ms);</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(bts_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI) == ms);</span><br><span> </span><br><span>       /*</span><br><span>    * Now check.. that DL changes and that the timing advance</span><br><span>@@ -130,20 +133,20 @@</span><br><span>   dl_tbf->update_ms(0x4232, GPRS_RLCMAC_DL_TBF);</span><br><span> </span><br><span>        /* It is still there, since the new TLLI has not been used for UL yet */</span><br><span style="color: hsl(0, 100%, 40%);">-        ms_new = the_bts->ms_by_tlli(0x2342);</span><br><span style="color: hsl(120, 100%, 40%);">+      ms_new = bts_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI);</span><br><span>     OSMO_ASSERT(ms == ms_new);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  ms_new = the_bts->ms_by_tlli(0x4232);</span><br><span style="color: hsl(120, 100%, 40%);">+      ms_new = bts_ms_by_tlli(bts, 0x4232, GSM_RESERVED_TMSI);</span><br><span>     OSMO_ASSERT(ms == ms_new);</span><br><span>   OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf);</span><br><span>        OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);</span><br><span> </span><br><span>    /* Now use the new TLLI for UL */</span><br><span>    ul_tbf->update_ms(0x4232, GPRS_RLCMAC_UL_TBF);</span><br><span style="color: hsl(0, 100%, 40%);">-       ms_new = the_bts->ms_by_tlli(0x2342);</span><br><span style="color: hsl(120, 100%, 40%);">+      ms_new = bts_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI);</span><br><span>     OSMO_ASSERT(ms_new == NULL);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        ms_new = the_bts->ms_by_tlli(0x4232);</span><br><span style="color: hsl(120, 100%, 40%);">+      ms_new = bts_ms_by_tlli(bts, 0x4232, GSM_RESERVED_TMSI);</span><br><span>     OSMO_ASSERT(ms_new != NULL);</span><br><span>         OSMO_ASSERT(ms_ta(ms_new) == 4);</span><br><span> </span><br><span>@@ -168,12 +171,10 @@</span><br><span>         return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void setup_bts(BTS *the_bts, uint8_t ts_no, uint8_t cs = 1)</span><br><span style="color: hsl(120, 100%, 40%);">+static void setup_bts(struct gprs_rlcmac_bts *bts, uint8_t ts_no, uint8_t cs = 1)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-    gprs_rlcmac_bts *bts;</span><br><span>        gprs_rlcmac_trx *trx;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       bts = the_bts->bts_data();</span><br><span>        the_pcu->alloc_algorithm = alloc_algorithm_a;</span><br><span>     bts->initial_cs_dl = cs;</span><br><span>  bts->initial_cs_ul = cs;</span><br><span>@@ -182,22 +183,20 @@</span><br><span>  trx = &bts->trx[0];</span><br><span> </span><br><span>       trx->pdch[ts_no].enable();</span><br><span style="color: hsl(0, 100%, 40%);">-   the_bts->set_current_frame_number(DUMMY_FN);</span><br><span style="color: hsl(120, 100%, 40%);">+       bts_set_current_frame_number(bts, DUMMY_FN);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static gprs_rlcmac_dl_tbf *create_dl_tbf(BTS *the_bts, uint8_t ms_class,</span><br><span style="color: hsl(120, 100%, 40%);">+static gprs_rlcmac_dl_tbf *create_dl_tbf(struct gprs_rlcmac_bts *bts, uint8_t ms_class,</span><br><span>       uint8_t egprs_ms_class, uint8_t *trx_no_)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  gprs_rlcmac_bts *bts;</span><br><span>        int tfi;</span><br><span>     uint8_t trx_no;</span><br><span>      GprsMs *ms;</span><br><span>  gprs_rlcmac_dl_tbf *dl_tbf;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- bts = the_bts->bts_data();</span><br><span style="color: hsl(0, 100%, 40%);">-   ms = the_bts->ms_alloc(ms_class, egprs_ms_class);</span><br><span style="color: hsl(120, 100%, 40%);">+  ms = bts_alloc_ms(bts, ms_class, egprs_ms_class);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   tfi = the_bts->tfi_find_free(GPRS_RLCMAC_DL_TBF, &trx_no, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+ tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_DL_TBF, &trx_no, -1);</span><br><span>   OSMO_ASSERT(tfi >= 0);</span><br><span>    dl_tbf = tbf_alloc_dl_tbf(bts, ms, trx_no, true);</span><br><span>    OSMO_ASSERT(dl_tbf);</span><br><span>@@ -243,7 +242,7 @@</span><br><span> static void request_dl_rlc_block(struct gprs_rlcmac_tbf *tbf,</span><br><span>  uint32_t *fn, uint8_t *block_nr = NULL)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-    request_dl_rlc_block(tbf->bts->bts_data(), tbf->trx->trx_no,</span><br><span style="color: hsl(120, 100%, 40%);">+      request_dl_rlc_block(tbf->bts, tbf->trx->trx_no,</span><br><span>            tbf->control_ts, fn, block_nr);</span><br><span> }</span><br><span> </span><br><span>@@ -256,7 +255,7 @@</span><br><span> {</span><br><span>       the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       uint8_t ts_no = 4;</span><br><span>   unsigned i;</span><br><span>  uint8_t ms_class = 45;</span><br><span>@@ -273,8 +272,8 @@</span><br><span>         gprs_rlcmac_dl_tbf *dl_tbf;</span><br><span>  gprs_rlcmac_tbf *new_tbf;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   setup_bts(the_bts, ts_no);</span><br><span style="color: hsl(0, 100%, 40%);">-      dl_tbf = create_dl_tbf(the_bts, ms_class, 0, &trx_no);</span><br><span style="color: hsl(120, 100%, 40%);">+    setup_bts(bts, ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+        dl_tbf = create_dl_tbf(bts, ms_class, 0, &trx_no);</span><br><span>       dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);</span><br><span>      ms = dl_tbf->ms();</span><br><span> </span><br><span>@@ -342,7 +341,7 @@</span><br><span> {</span><br><span>         the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       uint8_t ts_no = 4;</span><br><span>   unsigned i;</span><br><span>  uint8_t ms_class = 45;</span><br><span>@@ -357,10 +356,10 @@</span><br><span> </span><br><span>   fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  setup_bts(the_bts, ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+    setup_bts(bts, ts_no);</span><br><span>       OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      dl_tbf = create_dl_tbf(the_bts, ms_class, 0, &trx_no);</span><br><span style="color: hsl(120, 100%, 40%);">+    dl_tbf = create_dl_tbf(bts, ms_class, 0, &trx_no);</span><br><span>       dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);</span><br><span> </span><br><span>  for (i = 0; i < sizeof(llc_data); i++)</span><br><span>@@ -413,7 +412,7 @@</span><br><span> {</span><br><span>         the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       uint8_t ts_no = 4;</span><br><span>   uint8_t ms_class = 45;</span><br><span>       uint8_t trx_no;</span><br><span>@@ -423,27 +422,27 @@</span><br><span> </span><br><span>  fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  setup_bts(the_bts, ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+    setup_bts(bts, ts_no);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      dl_tbf[0] = create_dl_tbf(the_bts, ms_class, 0, &trx_no);</span><br><span style="color: hsl(0, 100%, 40%);">-   dl_tbf[1] = create_dl_tbf(the_bts, ms_class, 0, &trx_no);</span><br><span style="color: hsl(120, 100%, 40%);">+ dl_tbf[0] = create_dl_tbf(bts, ms_class, 0, &trx_no);</span><br><span style="color: hsl(120, 100%, 40%);">+     dl_tbf[1] = create_dl_tbf(bts, ms_class, 0, &trx_no);</span><br><span> </span><br><span>        dl_tbf[0]->update_ms(0xf1000001, GPRS_RLCMAC_DL_TBF);</span><br><span>     dl_tbf[1]->update_ms(0xf1000002, GPRS_RLCMAC_DL_TBF);</span><br><span> </span><br><span>         ms_set_imsi(dl_tbf[0]->ms(), "001001000000001");</span><br><span style="color: hsl(0, 100%, 40%);">-   ms1 = the_bts->ms_store().get_ms(0, 0, "001001000000001");</span><br><span style="color: hsl(120, 100%, 40%);">+       ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000001");</span><br><span>       OSMO_ASSERT(ms1 != NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-       ms2 = the_bts->ms_store().get_ms(0xf1000001);</span><br><span style="color: hsl(120, 100%, 40%);">+      ms2 = bts_ms_store(bts)->get_ms(0xf1000001);</span><br><span>      OSMO_ASSERT(ms2 != NULL);</span><br><span>    OSMO_ASSERT(strcmp(ms_imsi(ms2), "001001000000001") == 0);</span><br><span>         OSMO_ASSERT(ms1 == ms2);</span><br><span> </span><br><span>         /* change the IMSI on TBF 0 */</span><br><span>       ms_set_imsi(dl_tbf[0]->ms(), "001001000000002");</span><br><span style="color: hsl(0, 100%, 40%);">-   ms1 = the_bts->ms_store().get_ms(0, 0, "001001000000001");</span><br><span style="color: hsl(120, 100%, 40%);">+       ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000001");</span><br><span>       OSMO_ASSERT(ms1 == NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-       ms1 = the_bts->ms_store().get_ms(0, 0, "001001000000002");</span><br><span style="color: hsl(120, 100%, 40%);">+       ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000002");</span><br><span>       OSMO_ASSERT(ms1 != NULL);</span><br><span>    OSMO_ASSERT(strcmp(ms_imsi(ms2), "001001000000002") == 0);</span><br><span>         OSMO_ASSERT(ms1 == ms2);</span><br><span>@@ -452,7 +451,7 @@</span><br><span>       {</span><br><span>            ms_ref(ms2);</span><br><span>                 ms_set_imsi(dl_tbf[1]->ms(), "001001000000002");</span><br><span style="color: hsl(0, 100%, 40%);">-           ms1 = the_bts->ms_store().get_ms(0, 0, "001001000000002");</span><br><span style="color: hsl(120, 100%, 40%);">+               ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000002");</span><br><span>               OSMO_ASSERT(ms1 != NULL);</span><br><span>            OSMO_ASSERT(ms1 != ms2);</span><br><span>             OSMO_ASSERT(strcmp(ms_imsi(ms1), "001001000000002") == 0);</span><br><span>@@ -460,11 +459,11 @@</span><br><span>                 ms_unref(ms2);</span><br><span>       }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ms2 = the_bts->ms_store().get_ms(0xf1000001);</span><br><span style="color: hsl(120, 100%, 40%);">+      ms2 = bts_ms_store(bts)->get_ms(0xf1000001);</span><br><span>      OSMO_ASSERT(ms2 == NULL);</span><br><span> </span><br><span>        tbf_free(dl_tbf[1]);</span><br><span style="color: hsl(0, 100%, 40%);">-    ms1 = the_bts->ms_store().get_ms(0, 0, "001001000000002");</span><br><span style="color: hsl(120, 100%, 40%);">+       ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000002");</span><br><span>       OSMO_ASSERT(ms1 == NULL);</span><br><span> </span><br><span>        TALLOC_FREE(the_pcu);</span><br><span>@@ -475,8 +474,7 @@</span><br><span> {</span><br><span>     the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(0, 100%, 40%);">- gprs_rlcmac_bts *bts;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       unsigned i;</span><br><span>  uint8_t ts_no = 4;</span><br><span>   uint8_t ms_class = 45;</span><br><span>@@ -486,14 +484,13 @@</span><br><span> </span><br><span>   fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  bts = the_bts->bts_data();</span><br><span style="color: hsl(0, 100%, 40%);">-   the_bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (!the_bts->pcu->nsi) {</span><br><span style="color: hsl(120, 100%, 40%);">+       bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!bts->pcu->nsi) {</span><br><span>          LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");</span><br><span>                abort();</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   setup_bts(the_bts, ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+    setup_bts(bts, ts_no);</span><br><span>       gprs_bssgp_init(bts, 1234, 1234, 1, 1, false, 0, 0, 0);</span><br><span> </span><br><span>  for (i = 0; i < 1024; i++) {</span><br><span>@@ -521,8 +518,7 @@</span><br><span> {</span><br><span>   the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(0, 100%, 40%);">- gprs_rlcmac_bts *bts;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       uint8_t ts_no = 4;</span><br><span>   uint8_t ms_class = 45;</span><br><span>       int rc = 0;</span><br><span>@@ -533,16 +529,15 @@</span><br><span> </span><br><span>      uint8_t buf[19];</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    bts = the_bts->bts_data();</span><br><span style="color: hsl(0, 100%, 40%);">-   the_bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (!the_bts->pcu->nsi) {</span><br><span style="color: hsl(120, 100%, 40%);">+       bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!bts->pcu->nsi) {</span><br><span>          LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");</span><br><span>                abort();</span><br><span>     }</span><br><span> </span><br><span>        fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  setup_bts(the_bts, ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+    setup_bts(bts, ts_no);</span><br><span>       /* keep the MS object 10 seconds */</span><br><span>  OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2030, 10, OSMO_TDEF_S) == 0);</span><br><span> </span><br><span>@@ -554,7 +549,7 @@</span><br><span>               delay_csec, buf, sizeof(buf));</span><br><span>       OSMO_ASSERT(rc >= 0);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    ms = the_bts->ms_store().get_ms(0, 0, imsi);</span><br><span style="color: hsl(120, 100%, 40%);">+       ms = bts_ms_store(bts)->get_ms(0, 0, imsi);</span><br><span>       OSMO_ASSERT(ms != NULL);</span><br><span>     OSMO_ASSERT(ms_dl_tbf(ms) != NULL);</span><br><span>  ms_dl_tbf(ms)->set_ta(0);</span><br><span>@@ -605,7 +600,7 @@</span><br><span>   TALLOC_FREE(the_pcu);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static gprs_rlcmac_ul_tbf *establish_ul_tbf_single_phase(BTS *the_bts,</span><br><span style="color: hsl(120, 100%, 40%);">+static gprs_rlcmac_ul_tbf *establish_ul_tbf_single_phase(struct gprs_rlcmac_bts *bts,</span><br><span>  uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta)</span><br><span> {</span><br><span>       GprsMs *ms;</span><br><span>@@ -614,11 +609,11 @@</span><br><span>  uint8_t trx_no = 0;</span><br><span>  struct gprs_rlcmac_pdch *pdch;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+ tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  bts_handle_rach(the_bts, 0x03, *fn, qta);</span><br><span style="color: hsl(120, 100%, 40%);">+     bts_handle_rach(bts, 0x03, *fn, qta);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+       ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);</span><br><span>         OSMO_ASSERT(ul_tbf != NULL);</span><br><span> </span><br><span>     OSMO_ASSERT(ul_tbf->ta() == qta / 4);</span><br><span>@@ -631,16 +626,16 @@</span><br><span>             uint8_t(tlli >> 8), uint8_t(tlli), /* TLLI */</span><br><span>  };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];</span><br><span style="color: hsl(120, 100%, 40%);">+       pdch = &bts->trx[trx_no].pdch[ts_no];</span><br><span>         pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     ms = the_bts->ms_by_tlli(tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+    ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);</span><br><span>   OSMO_ASSERT(ms != NULL);</span><br><span> </span><br><span>         return ul_tbf;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void send_ul_mac_block(BTS *the_bts, unsigned trx_no, unsigned ts_no,</span><br><span style="color: hsl(120, 100%, 40%);">+static void send_ul_mac_block(struct gprs_rlcmac_bts *bts, unsigned trx_no, unsigned ts_no,</span><br><span>     RlcMacUplink_t *ulreq, unsigned fn)</span><br><span> {</span><br><span>     bitvec *rlc_block;</span><br><span>@@ -655,9 +650,9 @@</span><br><span>     OSMO_ASSERT(size_t(num_bytes) < sizeof(buf));</span><br><span>     bitvec_free(rlc_block);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     the_bts->set_current_block_frame_number(fn, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+    bts_set_current_block_frame_number(bts, fn, 0);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];</span><br><span style="color: hsl(120, 100%, 40%);">+       pdch = &bts->trx[trx_no].pdch[ts_no];</span><br><span>         pdch->rcv_block(&buf[0], num_bytes, fn, &meas);</span><br><span> }</span><br><span> </span><br><span>@@ -678,7 +673,7 @@</span><br><span>            &ulreq, tbf->poll_fn);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(BTS *the_bts,</span><br><span style="color: hsl(120, 100%, 40%);">+static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(struct gprs_rlcmac_bts *bts,</span><br><span>      uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,</span><br><span>    uint8_t ms_class, uint8_t egprs_ms_class)</span><br><span> {</span><br><span>@@ -689,12 +684,9 @@</span><br><span>        int tfi = 0;</span><br><span>         gprs_rlcmac_ul_tbf *ul_tbf;</span><br><span>  struct gprs_rlcmac_pdch *pdch;</span><br><span style="color: hsl(0, 100%, 40%);">-  gprs_rlcmac_bts *bts;</span><br><span>        RlcMacUplink_t ulreq = {0};</span><br><span>  struct gprs_rlc_ul_header_egprs_3 *egprs3  = NULL;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  bts = the_bts->bts_data();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>        /* needed to set last_rts_fn in the PDCH object */</span><br><span>   request_dl_rlc_block(bts, trx_no, ts_no, fn);</span><br><span> </span><br><span>@@ -702,10 +694,10 @@</span><br><span>     * simulate RACH, this sends an Immediate</span><br><span>     * Assignment Uplink on the AGCH</span><br><span>      */</span><br><span style="color: hsl(0, 100%, 40%);">-     bts_handle_rach(the_bts, 0x73, rach_fn, qta);</span><br><span style="color: hsl(120, 100%, 40%);">+ bts_handle_rach(bts, 0x73, rach_fn, qta);</span><br><span> </span><br><span>        /* get next free TFI */</span><br><span style="color: hsl(0, 100%, 40%);">- tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+ tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);</span><br><span> </span><br><span>       /* fake a resource request */</span><br><span>        ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;</span><br><span>@@ -733,10 +725,10 @@</span><br><span>                   Multislot_capability.EGPRS_multislot_class = ms_class;</span><br><span>       }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);</span><br><span style="color: hsl(120, 100%, 40%);">+        send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);</span><br><span> </span><br><span>       /* check the TBF */</span><br><span style="color: hsl(0, 100%, 40%);">-     ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+       ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);</span><br><span>         OSMO_ASSERT(ul_tbf);</span><br><span>         OSMO_ASSERT(ul_tbf->ta() == qta / 4);</span><br><span> </span><br><span>@@ -755,10 +747,10 @@</span><br><span>                 1, /* BSN:7, E:1 */</span><br><span>  };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];</span><br><span style="color: hsl(120, 100%, 40%);">+       pdch = &bts->trx[trx_no].pdch[ts_no];</span><br><span>         pdch->rcv_block(&data_msg[0], 23, *fn, &meas);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ms = the_bts->ms_by_tlli(tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+    ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);</span><br><span>   OSMO_ASSERT(ms != NULL);</span><br><span>     OSMO_ASSERT(ms_ta(ms) == qta/4);</span><br><span>     OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);</span><br><span>@@ -825,7 +817,7 @@</span><br><span>  return ul_tbf;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(BTS *the_bts,</span><br><span style="color: hsl(120, 100%, 40%);">+static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(struct gprs_rlcmac_bts *bts,</span><br><span>       uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,</span><br><span>    uint8_t ms_class, uint8_t egprs_ms_class)</span><br><span> {</span><br><span>@@ -836,12 +828,9 @@</span><br><span>        int tfi = 0, i = 0;</span><br><span>  gprs_rlcmac_ul_tbf *ul_tbf;</span><br><span>  struct gprs_rlcmac_pdch *pdch;</span><br><span style="color: hsl(0, 100%, 40%);">-  gprs_rlcmac_bts *bts;</span><br><span>        RlcMacUplink_t ulreq = {0};</span><br><span>  struct gprs_rlc_ul_header_egprs_3 *egprs3  = NULL;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  bts = the_bts->bts_data();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>        /* needed to set last_rts_fn in the PDCH object */</span><br><span>   request_dl_rlc_block(bts, trx_no, ts_no, fn);</span><br><span> </span><br><span>@@ -849,10 +838,10 @@</span><br><span>     * simulate RACH, this sends an Immediate</span><br><span>     * Assignment Uplink on the AGCH</span><br><span>      */</span><br><span style="color: hsl(0, 100%, 40%);">-     bts_handle_rach(the_bts, 0x73, rach_fn, qta);</span><br><span style="color: hsl(120, 100%, 40%);">+ bts_handle_rach(bts, 0x73, rach_fn, qta);</span><br><span> </span><br><span>        /* get next free TFI */</span><br><span style="color: hsl(0, 100%, 40%);">- tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+ tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);</span><br><span> </span><br><span>       /* fake a resource request */</span><br><span>        ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;</span><br><span>@@ -880,10 +869,10 @@</span><br><span>                   Multislot_capability.EGPRS_multislot_class = ms_class;</span><br><span>       }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);</span><br><span style="color: hsl(120, 100%, 40%);">+        send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);</span><br><span> </span><br><span>       /* check the TBF */</span><br><span style="color: hsl(0, 100%, 40%);">-     ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+       ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);</span><br><span>         OSMO_ASSERT(ul_tbf != NULL);</span><br><span>         OSMO_ASSERT(ul_tbf->ta() == qta / 4);</span><br><span> </span><br><span>@@ -903,10 +892,10 @@</span><br><span>                 uint8_t(1), /* BSN:7, E:1 */</span><br><span>         };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];</span><br><span style="color: hsl(120, 100%, 40%);">+       pdch = &bts->trx[trx_no].pdch[ts_no];</span><br><span>         pdch->rcv_block(&data_msg[0], 23, *fn, &meas);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ms = the_bts->ms_by_tlli(tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+    ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);</span><br><span>   OSMO_ASSERT(ms != NULL);</span><br><span>     OSMO_ASSERT(ms_ta(ms) == qta/4);</span><br><span>     OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);</span><br><span>@@ -1263,7 +1252,7 @@</span><br><span>        return ul_tbf;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static gprs_rlcmac_ul_tbf *establish_ul_tbf(BTS *the_bts,</span><br><span style="color: hsl(120, 100%, 40%);">+static gprs_rlcmac_ul_tbf *establish_ul_tbf(struct gprs_rlcmac_bts *bts,</span><br><span>   uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,</span><br><span>    uint8_t ms_class, uint8_t egprs_ms_class)</span><br><span> {</span><br><span>@@ -1272,11 +1261,8 @@</span><br><span>      uint8_t trx_no = 0;</span><br><span>  int tfi = 0;</span><br><span>         gprs_rlcmac_ul_tbf *ul_tbf;</span><br><span style="color: hsl(0, 100%, 40%);">-     gprs_rlcmac_bts *bts;</span><br><span>        RlcMacUplink_t ulreq = {0};</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- bts = the_bts->bts_data();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>        /* needed to set last_rts_fn in the PDCH object */</span><br><span>   request_dl_rlc_block(bts, trx_no, ts_no, fn);</span><br><span> </span><br><span>@@ -1284,10 +1270,10 @@</span><br><span>   * simulate RACH, this sends an Immediate</span><br><span>     * Assignment Uplink on the AGCH</span><br><span>      */</span><br><span style="color: hsl(0, 100%, 40%);">-     bts_handle_rach(the_bts, 0x73, rach_fn, qta);</span><br><span style="color: hsl(120, 100%, 40%);">+ bts_handle_rach(bts, 0x73, rach_fn, qta);</span><br><span> </span><br><span>        /* get next free TFI */</span><br><span style="color: hsl(0, 100%, 40%);">- tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+ tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);</span><br><span> </span><br><span>       /* fake a resource request */</span><br><span>        ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;</span><br><span>@@ -1314,10 +1300,10 @@</span><br><span>                         MS_RA_capability_value[0].u.Content.</span><br><span>                         Multislot_capability.EGPRS_multislot_class = ms_class;</span><br><span>       }</span><br><span style="color: hsl(0, 100%, 40%);">-       send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);</span><br><span style="color: hsl(120, 100%, 40%);">+        send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);</span><br><span> </span><br><span>       /* check the TBF */</span><br><span style="color: hsl(0, 100%, 40%);">-     ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+       ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);</span><br><span>         /* send packet uplink assignment */</span><br><span>  *fn = sba_fn;</span><br><span>        request_dl_rlc_block(ul_tbf, fn);</span><br><span>@@ -1330,7 +1316,7 @@</span><br><span>    return ul_tbf;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_no_length(BTS *the_bts,</span><br><span style="color: hsl(120, 100%, 40%);">+static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_no_length(struct gprs_rlcmac_bts *bts,</span><br><span>       uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,</span><br><span>    uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)</span><br><span> {</span><br><span>@@ -1369,7 +1355,7 @@</span><br><span>           data[5] = 0x0;</span><br><span>               data[6] = 0x2b;</span><br><span>              data[7] = 0x2b;</span><br><span style="color: hsl(0, 100%, 40%);">-         pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];</span><br><span style="color: hsl(120, 100%, 40%);">+               pdch = &bts->trx[trx_no].pdch[ts_no];</span><br><span>                 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);</span><br><span>      }</span><br><span>    ul_tbf->create_ul_ack(*fn, ts_no);</span><br><span>@@ -1394,7 +1380,7 @@</span><br><span>        data[6] = 0x2b;</span><br><span>      data[7] = 0x2b;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];</span><br><span style="color: hsl(120, 100%, 40%);">+       pdch = &bts->trx[trx_no].pdch[ts_no];</span><br><span>         pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);</span><br><span> </span><br><span>  request_dl_rlc_block(ul_tbf, fn);</span><br><span>@@ -1402,7 +1388,7 @@</span><br><span>    check_tbf(ul_tbf);</span><br><span>   OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ms = the_bts->ms_by_tlli(tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+    ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);</span><br><span>   OSMO_ASSERT(ms != NULL);</span><br><span>     OSMO_ASSERT(ms_ta(ms) == qta/4);</span><br><span>     OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);</span><br><span>@@ -1410,7 +1396,7 @@</span><br><span>        return ul_tbf;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_with_length(BTS *the_bts,</span><br><span style="color: hsl(120, 100%, 40%);">+static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_with_length(struct gprs_rlcmac_bts *bts,</span><br><span>   uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,</span><br><span>    uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)</span><br><span> {</span><br><span>@@ -1451,7 +1437,7 @@</span><br><span>           data[5] = 0x0;</span><br><span>               data[6] = 0x2b;</span><br><span>              data[7] = 0x2b;</span><br><span style="color: hsl(0, 100%, 40%);">-         pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];</span><br><span style="color: hsl(120, 100%, 40%);">+               pdch = &bts->trx[trx_no].pdch[ts_no];</span><br><span>                 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);</span><br><span>      }</span><br><span>    ul_tbf->create_ul_ack(*fn, ts_no);</span><br><span>@@ -1476,7 +1462,7 @@</span><br><span>        data[6] = 0x2b;</span><br><span>      data[7] = 0x2b;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];</span><br><span style="color: hsl(120, 100%, 40%);">+       pdch = &bts->trx[trx_no].pdch[ts_no];</span><br><span>         pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);</span><br><span>      ul_tbf->create_ul_ack(*fn, ts_no);</span><br><span> </span><br><span>@@ -1485,7 +1471,7 @@</span><br><span>    check_tbf(ul_tbf);</span><br><span>   OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ms = the_bts->ms_by_tlli(tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+    ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);</span><br><span>   OSMO_ASSERT(ms != NULL);</span><br><span>     OSMO_ASSERT(ms_ta(ms) == qta/4);</span><br><span>     OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);</span><br><span>@@ -1493,7 +1479,7 @@</span><br><span>        return ul_tbf;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_CRBB(BTS *the_bts,</span><br><span style="color: hsl(120, 100%, 40%);">+static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_CRBB(struct gprs_rlcmac_bts *bts,</span><br><span>   uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,</span><br><span>    uint8_t ms_class, uint8_t egprs_ms_class)</span><br><span> {</span><br><span>@@ -1504,7 +1490,7 @@</span><br><span>       struct gprs_rlcmac_pdch *pdch;</span><br><span> </span><br><span>   /* check the TBF */</span><br><span style="color: hsl(0, 100%, 40%);">-     ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+       ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);</span><br><span>         OSMO_ASSERT(ul_tbf);</span><br><span>         OSMO_ASSERT(ul_tbf->ta() == qta / 4);</span><br><span> </span><br><span>@@ -1537,7 +1523,7 @@</span><br><span>                 data[5] = 0x0;</span><br><span>               data[6] = 0x2b;</span><br><span>              data[7] = 0x2b;</span><br><span style="color: hsl(0, 100%, 40%);">-         pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];</span><br><span style="color: hsl(120, 100%, 40%);">+               pdch = &bts->trx[trx_no].pdch[ts_no];</span><br><span>                 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);</span><br><span>      }</span><br><span>    ul_tbf->create_ul_ack(*fn, ts_no);</span><br><span>@@ -1562,7 +1548,7 @@</span><br><span>        data[6] = 0x2b;</span><br><span>      data[7] = 0x2b;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];</span><br><span style="color: hsl(120, 100%, 40%);">+       pdch = &bts->trx[trx_no].pdch[ts_no];</span><br><span>         pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);</span><br><span> </span><br><span>  request_dl_rlc_block(ul_tbf, fn);</span><br><span>@@ -1570,14 +1556,14 @@</span><br><span>  check_tbf(ul_tbf);</span><br><span>   OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ms = the_bts->ms_by_tlli(tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+    ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);</span><br><span>   OSMO_ASSERT(ms != NULL);</span><br><span>     OSMO_ASSERT(ms_ta(ms) == qta/4);</span><br><span>     OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);</span><br><span> </span><br><span>    return ul_tbf;</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">-static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase(BTS *the_bts,</span><br><span style="color: hsl(120, 100%, 40%);">+static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase(struct gprs_rlcmac_bts *bts,</span><br><span>   uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,</span><br><span>    uint8_t ms_class, uint8_t egprs_ms_class)</span><br><span> {</span><br><span>@@ -1588,19 +1574,16 @@</span><br><span>     int tfi = 0;</span><br><span>         gprs_rlcmac_ul_tbf *ul_tbf;</span><br><span>  struct gprs_rlcmac_pdch *pdch;</span><br><span style="color: hsl(0, 100%, 40%);">-  gprs_rlcmac_bts *bts;</span><br><span>        RlcMacUplink_t ulreq = {0};</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- bts = the_bts->bts_data();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>        /* needed to set last_rts_fn in the PDCH object */</span><br><span>   request_dl_rlc_block(bts, trx_no, ts_no, fn);</span><br><span> </span><br><span>    /* simulate RACH, sends an Immediate Assignment Uplink on the AGCH */</span><br><span style="color: hsl(0, 100%, 40%);">-   bts_handle_rach(the_bts, 0x73, rach_fn, qta);</span><br><span style="color: hsl(120, 100%, 40%);">+ bts_handle_rach(bts, 0x73, rach_fn, qta);</span><br><span> </span><br><span>        /* get next free TFI */</span><br><span style="color: hsl(0, 100%, 40%);">- tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+ tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);</span><br><span> </span><br><span>       /* fake a resource request */</span><br><span>        ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;</span><br><span>@@ -1627,10 +1610,10 @@</span><br><span>                         EGPRS_multislot_class = ms_class;</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);</span><br><span style="color: hsl(120, 100%, 40%);">+        send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);</span><br><span> </span><br><span>       /* check the TBF */</span><br><span style="color: hsl(0, 100%, 40%);">-     ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+       ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);</span><br><span>         OSMO_ASSERT(ul_tbf != NULL);</span><br><span>         OSMO_ASSERT(ul_tbf->ta() == qta / 4);</span><br><span> </span><br><span>@@ -1650,10 +1633,10 @@</span><br><span>               uint8_t(1), /* BSN:7, E:1 */</span><br><span>         };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];</span><br><span style="color: hsl(120, 100%, 40%);">+       pdch = &bts->trx[trx_no].pdch[ts_no];</span><br><span>         pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     ms = the_bts->ms_by_tlli(tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+    ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);</span><br><span>   OSMO_ASSERT(ms != NULL);</span><br><span>     OSMO_ASSERT(ms_ta(ms) == qta/4);</span><br><span>     OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);</span><br><span>@@ -1661,34 +1644,34 @@</span><br><span>      return ul_tbf;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void send_dl_data(BTS *the_bts, uint32_t tlli, const char *imsi,</span><br><span style="color: hsl(120, 100%, 40%);">+static void send_dl_data(struct gprs_rlcmac_bts *bts, uint32_t tlli, const char *imsi,</span><br><span>       const uint8_t *data, unsigned data_size)</span><br><span> {</span><br><span>        GprsMs *ms, *ms2;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ms = the_bts->ms_store().get_ms(tlli, 0, imsi);</span><br><span style="color: hsl(120, 100%, 40%);">+    ms = bts_ms_store(bts)->get_ms(tlli, 0, imsi);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   gprs_rlcmac_dl_tbf::handle(the_bts->bts_data(), tlli, 0, imsi, 0, 0,</span><br><span style="color: hsl(120, 100%, 40%);">+       gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, 0, 0,</span><br><span>                 1000, data, data_size);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     ms = the_bts->ms_by_imsi(imsi);</span><br><span style="color: hsl(120, 100%, 40%);">+    ms = bts_ms_by_imsi(bts, imsi);</span><br><span>      OSMO_ASSERT(ms != NULL);</span><br><span>     OSMO_ASSERT(ms_dl_tbf(ms) != NULL);</span><br><span> </span><br><span>      if (imsi[0] && strcmp(imsi, "000") != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-            ms2 = the_bts->ms_by_tlli(tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+           ms2 = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);</span><br><span>          OSMO_ASSERT(ms == ms2);</span><br><span>      }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void transmit_dl_data(BTS *the_bts, uint32_t tlli, uint32_t *fn,</span><br><span style="color: hsl(120, 100%, 40%);">+static void transmit_dl_data(struct gprs_rlcmac_bts *bts, uint32_t tlli, uint32_t *fn,</span><br><span>    uint8_t slots = 0xff)</span><br><span> {</span><br><span>   gprs_rlcmac_dl_tbf *dl_tbf;</span><br><span>  GprsMs *ms;</span><br><span>  unsigned ts_no;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     ms = the_bts->ms_by_tlli(tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+    ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);</span><br><span>   OSMO_ASSERT(ms);</span><br><span>     dl_tbf = ms_dl_tbf(ms);</span><br><span>      OSMO_ASSERT(dl_tbf);</span><br><span>@@ -1698,7 +1681,7 @@</span><br><span>                 for (ts_no = 0 ; ts_no < 8; ts_no += 1) {</span><br><span>                         if (!(slots & (1 << ts_no)))</span><br><span>                               continue;</span><br><span style="color: hsl(0, 100%, 40%);">-                       gprs_rlcmac_rcv_rts_block(the_bts->bts_data(),</span><br><span style="color: hsl(120, 100%, 40%);">+                     gprs_rlcmac_rcv_rts_block(bts,</span><br><span>                               dl_tbf->trx->trx_no, ts_no,</span><br><span>                            *fn, bn);</span><br><span>            }</span><br><span>@@ -1717,7 +1700,7 @@</span><br><span> {</span><br><span>       the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       int ts_no = 7;</span><br><span>       uint32_t fn = DUMMY_FN; /* 17,25,9 */</span><br><span>        uint32_t tlli = 0xf1223344;</span><br><span>@@ -1727,12 +1710,12 @@</span><br><span> </span><br><span>    fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  setup_bts(the_bts, ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+    setup_bts(bts, ts_no);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      ul_tbf = establish_ul_tbf_single_phase(the_bts, ts_no, tlli, &fn, qta);</span><br><span style="color: hsl(120, 100%, 40%);">+   ul_tbf = establish_ul_tbf_single_phase(bts, ts_no, tlli, &fn, qta);</span><br><span> </span><br><span>  print_ta_tlli(ul_tbf, true);</span><br><span style="color: hsl(0, 100%, 40%);">-    send_dl_data(the_bts, tlli, imsi, (const uint8_t *)"TEST", 4);</span><br><span style="color: hsl(120, 100%, 40%);">+      send_dl_data(bts, tlli, imsi, (const uint8_t *)"TEST", 4);</span><br><span> </span><br><span>     fprintf(stderr, "=== end %s ===\n", __func__);</span><br><span>     TALLOC_FREE(the_pcu);</span><br><span>@@ -1742,7 +1725,7 @@</span><br><span> {</span><br><span>   the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       int ts_no = 7;</span><br><span>       uint32_t fn = 2654218;</span><br><span>       uint16_t qta = 31;</span><br><span>@@ -1757,36 +1740,36 @@</span><br><span> </span><br><span>     memset(test_data, 1, sizeof(test_data));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    setup_bts(the_bts, ts_no, 4);</span><br><span style="color: hsl(0, 100%, 40%);">-   the_bts->bts_data()->initial_mcs_dl = 9;</span><br><span style="color: hsl(120, 100%, 40%);">+        setup_bts(bts, ts_no, 4);</span><br><span style="color: hsl(120, 100%, 40%);">+     bts->initial_mcs_dl = 9;</span><br><span>  the_pcu->vty.ws_base = 128;</span><br><span>       the_pcu->vty.ws_pdch = 64;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       ul_tbf = establish_ul_tbf(the_bts, ts_no, tlli, &fn, qta, ms_class, egprs_ms_class);</span><br><span style="color: hsl(120, 100%, 40%);">+      ul_tbf = establish_ul_tbf(bts, ts_no, tlli, &fn, qta, ms_class, egprs_ms_class);</span><br><span>         /* Function to generate URBB with no length */</span><br><span style="color: hsl(0, 100%, 40%);">-  ul_tbf = establish_ul_tbf_two_phase_puan_URBB_no_length(the_bts, ts_no, tlli, &fn,</span><br><span style="color: hsl(120, 100%, 40%);">+        ul_tbf = establish_ul_tbf_two_phase_puan_URBB_no_length(bts, ts_no, tlli, &fn,</span><br><span>           qta, ms_class, egprs_ms_class, ul_tbf);</span><br><span> </span><br><span>  print_ta_tlli(ul_tbf, true);</span><br><span style="color: hsl(0, 100%, 40%);">-    send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));</span><br><span style="color: hsl(120, 100%, 40%);">+      send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));</span><br><span> </span><br><span>     static_cast<gprs_rlc_ul_window *>(ul_tbf->window())->reset_state();</span><br><span>      /* Function to generate URBB with length */</span><br><span style="color: hsl(0, 100%, 40%);">-     ul_tbf = establish_ul_tbf_two_phase_puan_URBB_with_length(the_bts, ts_no, tlli, &fn,</span><br><span style="color: hsl(120, 100%, 40%);">+      ul_tbf = establish_ul_tbf_two_phase_puan_URBB_with_length(bts, ts_no, tlli, &fn,</span><br><span>                 qta, ms_class, egprs_ms_class, ul_tbf);</span><br><span> </span><br><span>  print_ta_tlli(ul_tbf, true);</span><br><span style="color: hsl(0, 100%, 40%);">-    send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));</span><br><span style="color: hsl(120, 100%, 40%);">+      send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));</span><br><span> </span><br><span>     static_cast<gprs_rlc_ul_window *>(ul_tbf->window())->reset_state();</span><br><span>      /* Function to generate CRBB */</span><br><span>      the_pcu->vty.ws_base = 128;</span><br><span>       the_pcu->vty.ws_pdch = 64;</span><br><span style="color: hsl(0, 100%, 40%);">-   ul_tbf = establish_ul_tbf_two_phase_puan_CRBB(the_bts, ts_no, tlli, &fn,</span><br><span style="color: hsl(120, 100%, 40%);">+  ul_tbf = establish_ul_tbf_two_phase_puan_CRBB(bts, ts_no, tlli, &fn,</span><br><span>             qta, ms_class, egprs_ms_class);</span><br><span> </span><br><span>  print_ta_tlli(ul_tbf, true);</span><br><span style="color: hsl(0, 100%, 40%);">-    send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));</span><br><span style="color: hsl(120, 100%, 40%);">+      send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));</span><br><span> </span><br><span>     TALLOC_FREE(the_pcu);</span><br><span>        fprintf(stderr, "=== end %s ===\n", __func__);</span><br><span>@@ -1798,16 +1781,16 @@</span><br><span> {</span><br><span>      the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       uint32_t fn = 2654218;</span><br><span>       uint16_t qta = 31;</span><br><span>   int ts_no = 7;</span><br><span> </span><br><span>   fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  setup_bts(the_bts, ts_no, 4);</span><br><span style="color: hsl(120, 100%, 40%);">+ setup_bts(bts, ts_no, 4);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   the_bts->bts_data()->trx[0].pdch[ts_no].disable();</span><br><span style="color: hsl(120, 100%, 40%);">+      bts->trx[0].pdch[ts_no].disable();</span><br><span> </span><br><span>    uint32_t rach_fn = fn - 51;</span><br><span> </span><br><span>@@ -1817,7 +1800,7 @@</span><br><span>       * simulate RACH, sends an Immediate Assignment</span><br><span>       * Uplink reject on the AGCH</span><br><span>          */</span><br><span style="color: hsl(0, 100%, 40%);">-     rc = bts_handle_rach(the_bts, 0x70, rach_fn, qta);</span><br><span style="color: hsl(120, 100%, 40%);">+    rc = bts_handle_rach(bts, 0x70, rach_fn, qta);</span><br><span> </span><br><span>   OSMO_ASSERT(rc == -EINVAL);</span><br><span> </span><br><span>@@ -1832,14 +1815,14 @@</span><br><span> {</span><br><span>       the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       uint32_t fn = 2654218;</span><br><span>       uint16_t qta = 31;</span><br><span>   int ts_no = 7;</span><br><span> </span><br><span>   fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  setup_bts(the_bts, ts_no, 4);</span><br><span style="color: hsl(120, 100%, 40%);">+ setup_bts(bts, ts_no, 4);</span><br><span> </span><br><span>        uint32_t rach_fn = fn - 51;</span><br><span> </span><br><span>@@ -1849,14 +1832,14 @@</span><br><span>     * simulate RACH, sends an Immediate Assignment Uplink</span><br><span>        * reject on the AGCH</span><br><span>         */</span><br><span style="color: hsl(0, 100%, 40%);">-     rc = bts_handle_rach(the_bts, 0x78, rach_fn, qta);</span><br><span style="color: hsl(0, 100%, 40%);">-      rc = bts_handle_rach(the_bts, 0x79, rach_fn, qta);</span><br><span style="color: hsl(0, 100%, 40%);">-      rc = bts_handle_rach(the_bts, 0x7a, rach_fn, qta);</span><br><span style="color: hsl(0, 100%, 40%);">-      rc = bts_handle_rach(the_bts, 0x7b, rach_fn, qta);</span><br><span style="color: hsl(0, 100%, 40%);">-      rc = bts_handle_rach(the_bts, 0x7c, rach_fn, qta);</span><br><span style="color: hsl(0, 100%, 40%);">-      rc = bts_handle_rach(the_bts, 0x7d, rach_fn, qta);</span><br><span style="color: hsl(0, 100%, 40%);">-      rc = bts_handle_rach(the_bts, 0x7e, rach_fn, qta);</span><br><span style="color: hsl(0, 100%, 40%);">-      rc = bts_handle_rach(the_bts, 0x7f, rach_fn, qta);</span><br><span style="color: hsl(120, 100%, 40%);">+    rc = bts_handle_rach(bts, 0x78, rach_fn, qta);</span><br><span style="color: hsl(120, 100%, 40%);">+        rc = bts_handle_rach(bts, 0x79, rach_fn, qta);</span><br><span style="color: hsl(120, 100%, 40%);">+        rc = bts_handle_rach(bts, 0x7a, rach_fn, qta);</span><br><span style="color: hsl(120, 100%, 40%);">+        rc = bts_handle_rach(bts, 0x7b, rach_fn, qta);</span><br><span style="color: hsl(120, 100%, 40%);">+        rc = bts_handle_rach(bts, 0x7c, rach_fn, qta);</span><br><span style="color: hsl(120, 100%, 40%);">+        rc = bts_handle_rach(bts, 0x7d, rach_fn, qta);</span><br><span style="color: hsl(120, 100%, 40%);">+        rc = bts_handle_rach(bts, 0x7e, rach_fn, qta);</span><br><span style="color: hsl(120, 100%, 40%);">+        rc = bts_handle_rach(bts, 0x7f, rach_fn, qta);</span><br><span> </span><br><span>   OSMO_ASSERT(rc == -EBUSY);</span><br><span> </span><br><span>@@ -1874,7 +1857,7 @@</span><br><span> {</span><br><span>  the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       int ts_no = 7;</span><br><span>       uint32_t fn = 2654218;</span><br><span>       uint16_t qta = 31;</span><br><span>@@ -1885,13 +1868,13 @@</span><br><span> </span><br><span>     fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  setup_bts(the_bts, ts_no, 4);</span><br><span style="color: hsl(120, 100%, 40%);">+ setup_bts(bts, ts_no, 4);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli, &fn, qta,</span><br><span style="color: hsl(120, 100%, 40%);">+       ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli, &fn, qta,</span><br><span>          ms_class, 0);</span><br><span> </span><br><span>    print_ta_tlli(ul_tbf, true);</span><br><span style="color: hsl(0, 100%, 40%);">-    send_dl_data(the_bts, tlli, imsi, (const uint8_t *)"TEST", 4);</span><br><span style="color: hsl(120, 100%, 40%);">+      send_dl_data(bts, tlli, imsi, (const uint8_t *)"TEST", 4);</span><br><span> </span><br><span>     TALLOC_FREE(the_pcu);</span><br><span>        fprintf(stderr, "=== end %s ===\n", __func__);</span><br><span>@@ -1907,7 +1890,7 @@</span><br><span> {</span><br><span>        the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       int ts_no = 7;</span><br><span>       uint32_t fn = 2654218;</span><br><span>       uint16_t qta = 31;</span><br><span>@@ -1920,15 +1903,15 @@</span><br><span> </span><br><span>     fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  setup_bts(the_bts, ts_no, 4);</span><br><span style="color: hsl(120, 100%, 40%);">+ setup_bts(bts, ts_no, 4);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli1, &fn, qta,</span><br><span style="color: hsl(120, 100%, 40%);">+      ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta,</span><br><span>                 ms_class, 0);</span><br><span> </span><br><span>    ms1 = ul_tbf->ms();</span><br><span>       print_ta_tlli(ul_tbf, false);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)"RAU_ACCEPT", 10);</span><br><span style="color: hsl(120, 100%, 40%);">+      send_dl_data(bts, tlli1, imsi, (const uint8_t *)"RAU_ACCEPT", 10);</span><br><span>         print_ms(ms1, true);</span><br><span> </span><br><span>     /* Send Packet Downlink Assignment to MS */</span><br><span>@@ -1939,11 +1922,11 @@</span><br><span> </span><br><span>    /* Make sure the RAU Accept gets sent to the MS */</span><br><span>   OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 1);</span><br><span style="color: hsl(0, 100%, 40%);">-    transmit_dl_data(the_bts, tlli1, &fn);</span><br><span style="color: hsl(120, 100%, 40%);">+    transmit_dl_data(bts, tlli1, &fn);</span><br><span>       OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 0);</span><br><span> </span><br><span>     /* Now establish a new TBF for the RA UPDATE COMPLETE (new TLLI) */</span><br><span style="color: hsl(0, 100%, 40%);">-     ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli2, &fn, qta,</span><br><span style="color: hsl(120, 100%, 40%);">+      ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli2, &fn, qta,</span><br><span>                 ms_class, 0);</span><br><span> </span><br><span>    ms2 = ul_tbf->ms();</span><br><span>@@ -1954,16 +1937,16 @@</span><br><span> </span><br><span>         /* Send some downlink data along with the new TLLI and the IMSI so that</span><br><span>       * the PCU can see, that both MS objects belong to same MS */</span><br><span style="color: hsl(0, 100%, 40%);">-   send_dl_data(the_bts, tlli2, imsi, (const uint8_t *)"DATA", 4);</span><br><span style="color: hsl(120, 100%, 40%);">+     send_dl_data(bts, tlli2, imsi, (const uint8_t *)"DATA", 4);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       ms = the_bts->ms_by_imsi(imsi);</span><br><span style="color: hsl(120, 100%, 40%);">+    ms = bts_ms_by_imsi(bts, imsi);</span><br><span>      OSMO_ASSERT(ms == ms2);</span><br><span> </span><br><span>  print_ms(ms2, false);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       ms = the_bts->ms_by_tlli(tlli1);</span><br><span style="color: hsl(120, 100%, 40%);">+   ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);</span><br><span>  OSMO_ASSERT(ms == NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-        ms = the_bts->ms_by_tlli(tlli2);</span><br><span style="color: hsl(120, 100%, 40%);">+   ms = bts_ms_by_tlli(bts, tlli2, GSM_RESERVED_TMSI);</span><br><span>  OSMO_ASSERT(ms == ms2);</span><br><span> </span><br><span>  TALLOC_FREE(the_pcu);</span><br><span>@@ -1974,7 +1957,7 @@</span><br><span> {</span><br><span>   the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       int ts_no = 7;</span><br><span>       uint32_t fn = 2654218;</span><br><span>       uint16_t qta = 31;</span><br><span>@@ -1987,16 +1970,16 @@</span><br><span> </span><br><span>     fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  setup_bts(the_bts, ts_no, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ setup_bts(bts, ts_no, 1);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli1, &fn, qta,</span><br><span style="color: hsl(120, 100%, 40%);">+      ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta,</span><br><span>                 ms_class, 0);</span><br><span> </span><br><span>    ms1 = ul_tbf->ms();</span><br><span>       print_ta_tlli(ul_tbf, false);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);</span><br><span style="color: hsl(0, 100%, 40%);">-      send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);</span><br><span style="color: hsl(120, 100%, 40%);">+    send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);</span><br><span style="color: hsl(120, 100%, 40%);">+        send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);</span><br><span>       print_ms(ms1, true);</span><br><span> </span><br><span>     OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 2);</span><br><span>@@ -2005,11 +1988,11 @@</span><br><span> </span><br><span>   /* Get rid of old UL TBF */</span><br><span>  tbf_free(ul_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-       ms = the_bts->ms_by_tlli(tlli1);</span><br><span style="color: hsl(120, 100%, 40%);">+   ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);</span><br><span>  OSMO_ASSERT(ms1 == ms);</span><br><span> </span><br><span>  /* Now establish a new UL TBF, this will consume one LLC packet */</span><br><span style="color: hsl(0, 100%, 40%);">-      ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli1, &fn, qta,</span><br><span style="color: hsl(120, 100%, 40%);">+      ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta,</span><br><span>                 ms_class, 0);</span><br><span> </span><br><span>    ms2 = ul_tbf->ms();</span><br><span>@@ -2018,7 +2001,7 @@</span><br><span>       /* This should be the same MS object */</span><br><span>      OSMO_ASSERT(ms2 == ms1);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    ms = the_bts->ms_by_tlli(tlli1);</span><br><span style="color: hsl(120, 100%, 40%);">+   ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);</span><br><span>  OSMO_ASSERT(ms2 == ms);</span><br><span> </span><br><span>  /* A DL TBF should still exist */</span><br><span>@@ -2036,7 +2019,7 @@</span><br><span> {</span><br><span>       the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       int ts_no = 7;</span><br><span>       uint32_t fn = 2654218;</span><br><span>       uint16_t qta = 31;</span><br><span>@@ -2049,16 +2032,16 @@</span><br><span> </span><br><span>     fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  setup_bts(the_bts, ts_no, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ setup_bts(bts, ts_no, 1);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli1, &fn, qta,</span><br><span style="color: hsl(120, 100%, 40%);">+      ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta,</span><br><span>                 ms_class, 0);</span><br><span> </span><br><span>    ms1 = ul_tbf->ms();</span><br><span>       print_ta_tlli(ul_tbf, false);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);</span><br><span style="color: hsl(0, 100%, 40%);">-      send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);</span><br><span style="color: hsl(120, 100%, 40%);">+    send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);</span><br><span style="color: hsl(120, 100%, 40%);">+        send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);</span><br><span>       print_ms(ms1, true);</span><br><span> </span><br><span>     OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 2);</span><br><span>@@ -2067,11 +2050,11 @@</span><br><span> </span><br><span>   /* Get rid of old UL TBF */</span><br><span>  tbf_free(ul_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-       ms = the_bts->ms_by_tlli(tlli1);</span><br><span style="color: hsl(120, 100%, 40%);">+   ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);</span><br><span>  OSMO_ASSERT(ms1 == ms);</span><br><span> </span><br><span>  /* Now establish a new UL TBF */</span><br><span style="color: hsl(0, 100%, 40%);">-        ul_tbf = establish_ul_tbf_single_phase(the_bts, ts_no, tlli1, &fn, qta);</span><br><span style="color: hsl(120, 100%, 40%);">+  ul_tbf = establish_ul_tbf_single_phase(bts, ts_no, tlli1, &fn, qta);</span><br><span> </span><br><span>         ms2 = ul_tbf->ms();</span><br><span>       print_ms(ms2, false);</span><br><span>@@ -2079,7 +2062,7 @@</span><br><span>        /* There should be a different MS object */</span><br><span>  OSMO_ASSERT(ms2 != ms1);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    ms = the_bts->ms_by_tlli(tlli1);</span><br><span style="color: hsl(120, 100%, 40%);">+   ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);</span><br><span>  OSMO_ASSERT(ms2 == ms);</span><br><span>      OSMO_ASSERT(ms1 != ms);</span><br><span> </span><br><span>@@ -2097,7 +2080,7 @@</span><br><span> {</span><br><span>     the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       int ts_no = 7;</span><br><span>       uint32_t fn = 2654218;</span><br><span>       uint16_t qta = 31;</span><br><span>@@ -2112,9 +2095,9 @@</span><br><span> </span><br><span>       fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  setup_bts(the_bts, ts_no, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ setup_bts(bts, ts_no, 1);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli1, &fn, qta,</span><br><span style="color: hsl(120, 100%, 40%);">+      ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta,</span><br><span>                 ms_class, 0);</span><br><span> </span><br><span>    ms1 = ul_tbf->ms();</span><br><span>@@ -2128,7 +2111,7 @@</span><br><span>               rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i", i);</span><br><span>             OSMO_ASSERT(rc > 0);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-             send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)buf, rc);</span><br><span style="color: hsl(120, 100%, 40%);">+         send_dl_data(bts, tlli1, imsi, (const uint8_t *)buf, rc);</span><br><span>    }</span><br><span> </span><br><span>        print_ms(ms1, true);</span><br><span>@@ -2140,7 +2123,7 @@</span><br><span>         send_control_ack(ul_tbf);</span><br><span> </span><br><span>        /* Transmit all data */</span><br><span style="color: hsl(0, 100%, 40%);">- transmit_dl_data(the_bts, tlli1, &fn);</span><br><span style="color: hsl(120, 100%, 40%);">+    transmit_dl_data(bts, tlli1, &fn);</span><br><span>       OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 0);</span><br><span>         OSMO_ASSERT(ms_dl_tbf(ms1));</span><br><span>         OSMO_ASSERT(ms_dl_tbf(ms1)->state_is(GPRS_RLCMAC_FINISHED));</span><br><span>@@ -2155,7 +2138,7 @@</span><br><span>              rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i (TBF 2)", i);</span><br><span>             OSMO_ASSERT(rc > 0);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-             send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)buf, rc);</span><br><span style="color: hsl(120, 100%, 40%);">+         send_dl_data(bts, tlli1, imsi, (const uint8_t *)buf, rc);</span><br><span>    }</span><br><span> </span><br><span>        /* Fake Final DL Ack/Nack */</span><br><span>@@ -2166,13 +2149,13 @@</span><br><span>       ack->DOWNLINK_TFI = dl_tbf1->tfi();</span><br><span>    ack->Ack_Nack_Description.FINAL_ACK_INDICATION = 1;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      send_ul_mac_block(the_bts, 0, dl_tbf1->poll_ts, &ulreq, dl_tbf1->poll_fn);</span><br><span style="color: hsl(120, 100%, 40%);">+  send_ul_mac_block(bts, 0, dl_tbf1->poll_ts, &ulreq, dl_tbf1->poll_fn);</span><br><span> </span><br><span>         OSMO_ASSERT(dl_tbf1->state_is(GPRS_RLCMAC_WAIT_RELEASE));</span><br><span> </span><br><span>     request_dl_rlc_block(dl_tbf1, &fn);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     ms2 = the_bts->ms_by_tlli(tlli1);</span><br><span style="color: hsl(120, 100%, 40%);">+  ms2 = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);</span><br><span>         OSMO_ASSERT(ms2 == ms1);</span><br><span>     OSMO_ASSERT(ms_dl_tbf(ms2));</span><br><span>         OSMO_ASSERT(ms_dl_tbf(ms2)->state_is(GPRS_RLCMAC_ASSIGN));</span><br><span>@@ -2185,7 +2168,7 @@</span><br><span>        OSMO_ASSERT(dl_tbf2->state_is(GPRS_RLCMAC_FLOW));</span><br><span> </span><br><span>     /* Transmit all data */</span><br><span style="color: hsl(0, 100%, 40%);">- transmit_dl_data(the_bts, tlli1, &fn);</span><br><span style="color: hsl(120, 100%, 40%);">+    transmit_dl_data(bts, tlli1, &fn);</span><br><span>       OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms2)) == 0);</span><br><span>         OSMO_ASSERT(ms_dl_tbf(ms2));</span><br><span>         OSMO_ASSERT(ms_dl_tbf(ms2)->state_is(GPRS_RLCMAC_FINISHED));</span><br><span>@@ -2198,8 +2181,7 @@</span><br><span> {</span><br><span>         the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(0, 100%, 40%);">- gprs_rlcmac_bts *bts;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       uint8_t ts_no = 4;</span><br><span>   uint8_t ms_class = 45;</span><br><span>       int rc = 0;</span><br><span>@@ -2211,14 +2193,13 @@</span><br><span> </span><br><span>    fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  bts = the_bts->bts_data();</span><br><span style="color: hsl(0, 100%, 40%);">-   the_bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (!the_bts->pcu->nsi) {</span><br><span style="color: hsl(120, 100%, 40%);">+       bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!bts->pcu->nsi) {</span><br><span>          LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");</span><br><span>                abort();</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   setup_bts(the_bts, ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+    setup_bts(bts, ts_no);</span><br><span> </span><br><span>   /* EGPRS-only */</span><br><span> </span><br><span>@@ -2238,7 +2219,7 @@</span><br><span> static inline void ws_check(gprs_rlcmac_dl_tbf *dl_tbf, const char *test, uint8_t exp_slots, uint16_t exp_ws,</span><br><span>                            bool free, bool end)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   gprs_rlcmac_bts *bts = dl_tbf->bts->bts_data();</span><br><span style="color: hsl(120, 100%, 40%);">+ gprs_rlcmac_bts *bts = dl_tbf->bts;</span><br><span>       if (!dl_tbf) {</span><br><span>               fprintf(stderr, "%s(): FAILED (NULL TBF)\n", test);</span><br><span>                return;</span><br><span>@@ -2268,8 +2249,7 @@</span><br><span> {</span><br><span>         the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(0, 100%, 40%);">- gprs_rlcmac_bts *bts;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       GprsMs *ms;</span><br><span>  uint8_t ts_no = 4;</span><br><span>   uint8_t ms_class = 12;</span><br><span>@@ -2277,14 +2257,13 @@</span><br><span> </span><br><span>         fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  bts = the_bts->bts_data();</span><br><span style="color: hsl(0, 100%, 40%);">-   the_bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (!the_bts->pcu->nsi) {</span><br><span style="color: hsl(120, 100%, 40%);">+       bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!bts->pcu->nsi) {</span><br><span>          LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");</span><br><span>                abort();</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   setup_bts(the_bts, ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+    setup_bts(bts, ts_no);</span><br><span> </span><br><span>   the_pcu->vty.ws_base = 128;</span><br><span>       the_pcu->vty.ws_pdch = 64;</span><br><span>@@ -2297,7 +2276,7 @@</span><br><span>        gprs_bssgp_init(bts, 4234, 4234, 1, 1, false, 0, 0, 0);</span><br><span> </span><br><span>  /* Does no support EGPRS */</span><br><span style="color: hsl(0, 100%, 40%);">-     ms = the_bts->ms_alloc(ms_class, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+       ms = bts_alloc_ms(bts, ms_class, 0);</span><br><span>         dl_tbf = tbf_alloc_dl_tbf(bts, ms, 0, false);</span><br><span> </span><br><span>    ws_check(dl_tbf, __func__, 4, 64, true, false);</span><br><span>@@ -2305,7 +2284,7 @@</span><br><span>      /* EGPRS-only */</span><br><span> </span><br><span>         /* Does support EGPRS */</span><br><span style="color: hsl(0, 100%, 40%);">-        ms = the_bts->ms_alloc(ms_class, ms_class);</span><br><span style="color: hsl(120, 100%, 40%);">+        ms = bts_alloc_ms(bts, ms_class, ms_class);</span><br><span>  dl_tbf = tbf_alloc_dl_tbf(bts, ms, 0, false);</span><br><span> </span><br><span>    ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true, true);</span><br><span>@@ -2316,8 +2295,7 @@</span><br><span> {</span><br><span>        the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(0, 100%, 40%);">- gprs_rlcmac_bts *bts;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       GprsMs *ms;</span><br><span>  uint8_t ts_no = 4;</span><br><span>   uint8_t ms_class = 11;</span><br><span>@@ -2325,14 +2303,13 @@</span><br><span> </span><br><span>         fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  bts = the_bts->bts_data();</span><br><span style="color: hsl(0, 100%, 40%);">-   the_bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (!the_bts->pcu->nsi) {</span><br><span style="color: hsl(120, 100%, 40%);">+       bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!bts->pcu->nsi) {</span><br><span>          LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");</span><br><span>                abort();</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   setup_bts(the_bts, ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+    setup_bts(bts, ts_no);</span><br><span> </span><br><span>   the_pcu->vty.ws_base = 128;</span><br><span>       the_pcu->vty.ws_pdch = 64;</span><br><span>@@ -2347,7 +2324,7 @@</span><br><span>        /* EGPRS-only */</span><br><span> </span><br><span>         /* Does support EGPRS */</span><br><span style="color: hsl(0, 100%, 40%);">-        ms = the_bts->ms_alloc(ms_class, ms_class);</span><br><span style="color: hsl(120, 100%, 40%);">+        ms = bts_alloc_ms(bts, ms_class, ms_class);</span><br><span>  dl_tbf = tbf_alloc_dl_tbf(bts, ms, 0, true);</span><br><span> </span><br><span>     ws_check(dl_tbf, __func__, 1, 128 + 1 * 64, false, false);</span><br><span>@@ -2363,7 +2340,7 @@</span><br><span> {</span><br><span>      the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       int ts_no = 7;</span><br><span>       uint32_t fn = 2654218;</span><br><span>       uint16_t qta = 31;</span><br><span>@@ -2378,20 +2355,20 @@</span><br><span> </span><br><span>     memset(test_data, 1, sizeof(test_data));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    setup_bts(the_bts, ts_no, 4);</span><br><span style="color: hsl(0, 100%, 40%);">-   the_bts->bts_data()->initial_mcs_dl = 9;</span><br><span style="color: hsl(120, 100%, 40%);">+        setup_bts(bts, ts_no, 4);</span><br><span style="color: hsl(120, 100%, 40%);">+     bts->initial_mcs_dl = 9;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- ul_tbf = puan_urbb_len_issue(the_bts, ts_no, tlli, &fn, qta,</span><br><span style="color: hsl(120, 100%, 40%);">+      ul_tbf = puan_urbb_len_issue(bts, ts_no, tlli, &fn, qta,</span><br><span>                 ms_class, egprs_ms_class);</span><br><span> </span><br><span>       print_ta_tlli(ul_tbf, true);</span><br><span style="color: hsl(0, 100%, 40%);">-    send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));</span><br><span style="color: hsl(120, 100%, 40%);">+      send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));</span><br><span> </span><br><span>     TALLOC_FREE(the_pcu);</span><br><span>        fprintf(stderr, "=== end %s ===\n", __func__);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static gprs_rlcmac_ul_tbf *tbf_li_decoding(BTS *the_bts,</span><br><span style="color: hsl(120, 100%, 40%);">+static gprs_rlcmac_ul_tbf *tbf_li_decoding(struct gprs_rlcmac_bts *bts,</span><br><span>   uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,</span><br><span>    uint8_t ms_class, uint8_t egprs_ms_class)</span><br><span> {</span><br><span>@@ -2402,15 +2379,12 @@</span><br><span>     int tfi = 0;</span><br><span>         gprs_rlcmac_ul_tbf *ul_tbf;</span><br><span>  struct gprs_rlcmac_pdch *pdch;</span><br><span style="color: hsl(0, 100%, 40%);">-  gprs_rlcmac_bts *bts;</span><br><span>        RlcMacUplink_t ulreq = {0};</span><br><span>  struct gprs_rlc_ul_header_egprs_3 *egprs3  = NULL;</span><br><span>   Packet_Resource_Request_t *presreq = NULL;</span><br><span>   MS_Radio_Access_capability_t *pmsradiocap = NULL;</span><br><span>    Multislot_capability_t *pmultislotcap = NULL;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       bts = the_bts->bts_data();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>        /* needed to set last_rts_fn in the PDCH object */</span><br><span>   request_dl_rlc_block(bts, trx_no, ts_no, fn);</span><br><span> </span><br><span>@@ -2418,10 +2392,10 @@</span><br><span>   * simulate RACH, this sends an Immediate</span><br><span>     * Assignment Uplink on the AGCH</span><br><span>      */</span><br><span style="color: hsl(0, 100%, 40%);">-     bts_handle_rach(the_bts, 0x73, rach_fn, qta);</span><br><span style="color: hsl(120, 100%, 40%);">+ bts_handle_rach(bts, 0x73, rach_fn, qta);</span><br><span> </span><br><span>        /* get next free TFI */</span><br><span style="color: hsl(0, 100%, 40%);">- tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+ tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);</span><br><span> </span><br><span>       /* fake a resource request */</span><br><span>        ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;</span><br><span>@@ -2444,10 +2418,10 @@</span><br><span>                 pmultislotcap->EGPRS_multislot_class = ms_class;</span><br><span>  }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);</span><br><span style="color: hsl(120, 100%, 40%);">+        send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);</span><br><span> </span><br><span>       /* check the TBF */</span><br><span style="color: hsl(0, 100%, 40%);">-     ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+       ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);</span><br><span>         OSMO_ASSERT(ul_tbf);</span><br><span>         OSMO_ASSERT(ul_tbf->ta() == qta / 4);</span><br><span> </span><br><span>@@ -2462,9 +2436,9 @@</span><br><span> </span><br><span>     uint8_t data_msg[49] = {0};</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];</span><br><span style="color: hsl(120, 100%, 40%);">+       pdch = &bts->trx[trx_no].pdch[ts_no];</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        ms = the_bts->ms_by_tlli(tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+    ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);</span><br><span>   OSMO_ASSERT(ms != NULL);</span><br><span>     OSMO_ASSERT(ms_ta(ms) == qta/4);</span><br><span>     OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);</span><br><span>@@ -2506,7 +2480,7 @@</span><br><span> {</span><br><span>   the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       int ts_no = 7;</span><br><span>       uint32_t fn = 2654218;</span><br><span>       uint16_t qta = 31;</span><br><span>@@ -2521,14 +2495,14 @@</span><br><span> </span><br><span>     memset(test_data, 1, sizeof(test_data));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    setup_bts(the_bts, ts_no, 4);</span><br><span style="color: hsl(0, 100%, 40%);">-   the_bts->bts_data()->initial_mcs_dl = 9;</span><br><span style="color: hsl(120, 100%, 40%);">+        setup_bts(bts, ts_no, 4);</span><br><span style="color: hsl(120, 100%, 40%);">+     bts->initial_mcs_dl = 9;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- ul_tbf = tbf_li_decoding(the_bts, ts_no, tlli, &fn, qta,</span><br><span style="color: hsl(120, 100%, 40%);">+  ul_tbf = tbf_li_decoding(bts, ts_no, tlli, &fn, qta,</span><br><span>             ms_class, egprs_ms_class);</span><br><span> </span><br><span>       print_ta_tlli(ul_tbf, true);</span><br><span style="color: hsl(0, 100%, 40%);">-    send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));</span><br><span style="color: hsl(120, 100%, 40%);">+      send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));</span><br><span> </span><br><span>     TALLOC_FREE(the_pcu);</span><br><span>        fprintf(stderr, "=== end %s ===\n", __func__);</span><br><span>@@ -2543,7 +2517,7 @@</span><br><span> {</span><br><span>        the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       uint8_t ms_class = 11;</span><br><span>       uint8_t egprs_ms_class = 11;</span><br><span>         uint8_t trx_no;</span><br><span>@@ -2564,7 +2538,7 @@</span><br><span> </span><br><span>  fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  setup_bts(the_bts, ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+    setup_bts(bts, ts_no);</span><br><span>       OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);</span><br><span>       /* ARQ II */</span><br><span>         the_pcu->vty.dl_arq_type = EGPRS_ARQ2;</span><br><span>@@ -2579,7 +2553,7 @@</span><br><span>                            0xff, 0xff, 0xfb, 0x80, 0x00, 0x00,</span><br><span>                          0x00, 0x00, 0x00, 0x00, 0x00, 0x00};</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no);</span><br><span style="color: hsl(120, 100%, 40%);">+       dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);</span><br><span>  dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);</span><br><span>      prlcdlwindow = static_cast<gprs_rlc_dl_window *>(dl_tbf->window());</span><br><span>         prlcmvb = &prlcdlwindow->m_v_b;</span><br><span>@@ -2635,7 +2609,7 @@</span><br><span> {</span><br><span>  the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       int ts_no = 7;</span><br><span>       uint32_t fn = 2654218;</span><br><span>       uint16_t qta = 31;</span><br><span>@@ -2650,14 +2624,14 @@</span><br><span> </span><br><span>     memset(test_data, 1, sizeof(test_data));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    setup_bts(the_bts, ts_no, 4);</span><br><span style="color: hsl(0, 100%, 40%);">-   the_bts->bts_data()->initial_mcs_dl = 9;</span><br><span style="color: hsl(120, 100%, 40%);">+        setup_bts(bts, ts_no, 4);</span><br><span style="color: hsl(120, 100%, 40%);">+     bts->initial_mcs_dl = 9;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- ul_tbf = establish_ul_tbf_two_phase_spb(the_bts, ts_no, tlli, &fn, qta,</span><br><span style="color: hsl(120, 100%, 40%);">+   ul_tbf = establish_ul_tbf_two_phase_spb(bts, ts_no, tlli, &fn, qta,</span><br><span>              ms_class, egprs_ms_class);</span><br><span> </span><br><span>       print_ta_tlli(ul_tbf, true);</span><br><span style="color: hsl(0, 100%, 40%);">-    send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));</span><br><span style="color: hsl(120, 100%, 40%);">+      send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));</span><br><span> </span><br><span>     TALLOC_FREE(the_pcu);</span><br><span>        fprintf(stderr, "=== end %s ===\n", __func__);</span><br><span>@@ -2667,7 +2641,7 @@</span><br><span> {</span><br><span>        the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       int ts_no = 7;</span><br><span>       uint32_t fn = 2654218;</span><br><span>       uint16_t qta = 31;</span><br><span>@@ -2682,20 +2656,20 @@</span><br><span> </span><br><span>     memset(test_data, 1, sizeof(test_data));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    setup_bts(the_bts, ts_no, 4);</span><br><span style="color: hsl(0, 100%, 40%);">-   the_bts->bts_data()->initial_mcs_dl = 9;</span><br><span style="color: hsl(120, 100%, 40%);">+        setup_bts(bts, ts_no, 4);</span><br><span style="color: hsl(120, 100%, 40%);">+     bts->initial_mcs_dl = 9;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli, &fn, qta,</span><br><span style="color: hsl(120, 100%, 40%);">+       ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli, &fn, qta,</span><br><span>          ms_class, egprs_ms_class);</span><br><span> </span><br><span>       print_ta_tlli(ul_tbf, true);</span><br><span style="color: hsl(0, 100%, 40%);">-    send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));</span><br><span style="color: hsl(120, 100%, 40%);">+      send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));</span><br><span> </span><br><span>     TALLOC_FREE(the_pcu);</span><br><span>        fprintf(stderr, "=== end %s ===\n", __func__);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void establish_and_use_egprs_dl_tbf(BTS *the_bts, int mcs)</span><br><span style="color: hsl(120, 100%, 40%);">+static void establish_and_use_egprs_dl_tbf(struct gprs_rlcmac_bts *bts, int mcs)</span><br><span> {</span><br><span>    unsigned i;</span><br><span>  uint8_t ms_class = 11;</span><br><span>@@ -2712,9 +2686,9 @@</span><br><span>       fprintf(stderr, "Testing MCS-%d\n", mcs);</span><br><span> </span><br><span>      memset(test_data, 1, sizeof(test_data));</span><br><span style="color: hsl(0, 100%, 40%);">-        the_bts->bts_data()->initial_mcs_dl = mcs;</span><br><span style="color: hsl(120, 100%, 40%);">+      bts->initial_mcs_dl = mcs;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no);</span><br><span style="color: hsl(120, 100%, 40%);">+       dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);</span><br><span>  dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);</span><br><span> </span><br><span>  for (i = 0; i < sizeof(llc_data); i++)</span><br><span>@@ -2753,7 +2727,7 @@</span><br><span>    tbf_free(dl_tbf);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static gprs_rlcmac_dl_tbf *tbf_init(BTS *the_bts,</span><br><span style="color: hsl(120, 100%, 40%);">+static gprs_rlcmac_dl_tbf *tbf_init(struct gprs_rlcmac_bts *bts,</span><br><span>                int mcs)</span><br><span> {</span><br><span>        unsigned i;</span><br><span>@@ -2766,9 +2740,9 @@</span><br><span>  gprs_rlcmac_dl_tbf *dl_tbf;</span><br><span> </span><br><span>      memset(test_data, 1, sizeof(test_data));</span><br><span style="color: hsl(0, 100%, 40%);">-        the_bts->bts_data()->initial_mcs_dl = mcs;</span><br><span style="color: hsl(120, 100%, 40%);">+      bts->initial_mcs_dl = mcs;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no);</span><br><span style="color: hsl(120, 100%, 40%);">+       dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);</span><br><span>  dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);</span><br><span> </span><br><span>  for (i = 0; i < sizeof(test_data); i++)</span><br><span>@@ -2830,7 +2804,7 @@</span><br><span>                   CHECK_NACKED(tbf, cs, 0);                       \</span><br><span>    } while(0)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void egprs_spb_to_normal_validation(BTS *the_bts,</span><br><span style="color: hsl(120, 100%, 40%);">+static void egprs_spb_to_normal_validation(struct gprs_rlcmac_bts *bts,</span><br><span>              unsigned int mcs, unsigned int demanded_mcs)</span><br><span> {</span><br><span>    uint32_t fn = 0;</span><br><span>@@ -2842,7 +2816,7 @@</span><br><span> </span><br><span>         fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  dl_tbf = tbf_init(the_bts, mcs);</span><br><span style="color: hsl(120, 100%, 40%);">+      dl_tbf = tbf_init(bts, mcs);</span><br><span> </span><br><span>     /*</span><br><span>    * Table 10.4.8a.3.1 of 44.060.</span><br><span>@@ -2908,7 +2882,7 @@</span><br><span>      tbf_cleanup(dl_tbf);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void establish_and_use_egprs_dl_tbf_for_spb(BTS *the_bts,</span><br><span style="color: hsl(120, 100%, 40%);">+static void establish_and_use_egprs_dl_tbf_for_spb(struct gprs_rlcmac_bts *bts,</span><br><span>               unsigned int mcs, unsigned int demanded_mcs)</span><br><span> {</span><br><span>    uint32_t fn = 0;</span><br><span>@@ -2918,7 +2892,7 @@</span><br><span> </span><br><span>         fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  dl_tbf = tbf_init(the_bts, mcs);</span><br><span style="color: hsl(120, 100%, 40%);">+      dl_tbf = tbf_init(bts, mcs);</span><br><span> </span><br><span>     /*</span><br><span>    * Table 10.4.8a.3.1 of 44.060.</span><br><span>@@ -2995,7 +2969,7 @@</span><br><span>      tbf_cleanup(dl_tbf);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void establish_and_use_egprs_dl_tbf_for_retx(BTS *the_bts,</span><br><span style="color: hsl(120, 100%, 40%);">+static void establish_and_use_egprs_dl_tbf_for_retx(struct gprs_rlcmac_bts *bts,</span><br><span>             unsigned int mcs, unsigned int demanded_mcs)</span><br><span> {</span><br><span>    uint32_t fn = 0;</span><br><span>@@ -3004,7 +2978,7 @@</span><br><span> </span><br><span>         fprintf(stderr, "Testing retx for MCS %u - %u\n", mcs, demanded_mcs);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     dl_tbf = tbf_init(the_bts, mcs);</span><br><span style="color: hsl(120, 100%, 40%);">+      dl_tbf = tbf_init(bts, mcs);</span><br><span> </span><br><span>     /* For MCS reduction cases like MCS9->MCS6, MCS7->MCS5</span><br><span>          * The MCS transition are referred from table Table 8.1.1.2</span><br><span>@@ -3091,26 +3065,26 @@</span><br><span> {</span><br><span>   the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       uint8_t ts_no = 4;</span><br><span> </span><br><span>       fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span>       the_pcu->vty.cs_downgrade_threshold = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-     setup_bts(the_bts, ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+    setup_bts(bts, ts_no);</span><br><span>       OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);</span><br><span>       /* ARQ II */</span><br><span>         the_pcu->vty.dl_arq_type = EGPRS_ARQ2;</span><br><span> </span><br><span> </span><br><span>    /* First parameter is current MCS, second one is demanded_mcs */</span><br><span style="color: hsl(0, 100%, 40%);">-        establish_and_use_egprs_dl_tbf_for_retx(the_bts, 6, 6);</span><br><span style="color: hsl(0, 100%, 40%);">- establish_and_use_egprs_dl_tbf_for_retx(the_bts, 1, 9);</span><br><span style="color: hsl(0, 100%, 40%);">- establish_and_use_egprs_dl_tbf_for_retx(the_bts, 2, 8);</span><br><span style="color: hsl(0, 100%, 40%);">- establish_and_use_egprs_dl_tbf_for_retx(the_bts, 5, 7);</span><br><span style="color: hsl(0, 100%, 40%);">- establish_and_use_egprs_dl_tbf_for_retx(the_bts, 6, 9);</span><br><span style="color: hsl(0, 100%, 40%);">- establish_and_use_egprs_dl_tbf_for_retx(the_bts, 7, 5);</span><br><span style="color: hsl(0, 100%, 40%);">- establish_and_use_egprs_dl_tbf_for_retx(the_bts, 9, 6);</span><br><span style="color: hsl(120, 100%, 40%);">+       establish_and_use_egprs_dl_tbf_for_retx(bts, 6, 6);</span><br><span style="color: hsl(120, 100%, 40%);">+   establish_and_use_egprs_dl_tbf_for_retx(bts, 1, 9);</span><br><span style="color: hsl(120, 100%, 40%);">+   establish_and_use_egprs_dl_tbf_for_retx(bts, 2, 8);</span><br><span style="color: hsl(120, 100%, 40%);">+   establish_and_use_egprs_dl_tbf_for_retx(bts, 5, 7);</span><br><span style="color: hsl(120, 100%, 40%);">+   establish_and_use_egprs_dl_tbf_for_retx(bts, 6, 9);</span><br><span style="color: hsl(120, 100%, 40%);">+   establish_and_use_egprs_dl_tbf_for_retx(bts, 7, 5);</span><br><span style="color: hsl(120, 100%, 40%);">+   establish_and_use_egprs_dl_tbf_for_retx(bts, 9, 6);</span><br><span> </span><br><span>      TALLOC_FREE(the_pcu);</span><br><span>        fprintf(stderr, "=== end %s ===\n", __func__);</span><br><span>@@ -3120,13 +3094,13 @@</span><br><span> {</span><br><span>      the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       uint8_t ts_no = 4;</span><br><span> </span><br><span>       fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span>       the_pcu->vty.cs_downgrade_threshold = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-     setup_bts(the_bts, ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+    setup_bts(bts, ts_no);</span><br><span>       OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);</span><br><span> </span><br><span>   /* ARQ I resegmentation support */</span><br><span>@@ -3137,11 +3111,11 @@</span><br><span>          * currently only MCS5->MCS2, MCS6->3, MCS4->MCS1 is tested in UT</span><br><span>    * rest scenarios has been integration tested</span><br><span>         */</span><br><span style="color: hsl(0, 100%, 40%);">-     establish_and_use_egprs_dl_tbf_for_spb(the_bts, 6, 3);</span><br><span style="color: hsl(0, 100%, 40%);">-  establish_and_use_egprs_dl_tbf_for_spb(the_bts, 5, 2);</span><br><span style="color: hsl(0, 100%, 40%);">-  establish_and_use_egprs_dl_tbf_for_spb(the_bts, 4, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+        establish_and_use_egprs_dl_tbf_for_spb(bts, 6, 3);</span><br><span style="color: hsl(120, 100%, 40%);">+    establish_and_use_egprs_dl_tbf_for_spb(bts, 5, 2);</span><br><span style="color: hsl(120, 100%, 40%);">+    establish_and_use_egprs_dl_tbf_for_spb(bts, 4, 1);</span><br><span>   /* check MCS6->(MCS3+MCS3)->MCS6 case */</span><br><span style="color: hsl(0, 100%, 40%);">-  egprs_spb_to_normal_validation(the_bts, 6, 3);</span><br><span style="color: hsl(120, 100%, 40%);">+        egprs_spb_to_normal_validation(bts, 6, 3);</span><br><span> </span><br><span>       TALLOC_FREE(the_pcu);</span><br><span>        fprintf(stderr, "=== end %s ===\n", __func__);</span><br><span>@@ -3151,19 +3125,19 @@</span><br><span> {</span><br><span>      the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       uint8_t ts_no = 4;</span><br><span>   int i;</span><br><span> </span><br><span>   fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  setup_bts(the_bts, ts_no);</span><br><span style="color: hsl(120, 100%, 40%);">+    setup_bts(bts, ts_no);</span><br><span>       OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);</span><br><span>       /* ARQ II */</span><br><span>         the_pcu->vty.dl_arq_type = EGPRS_ARQ2;</span><br><span> </span><br><span>        for (i = 1; i <= 9; i++)</span><br><span style="color: hsl(0, 100%, 40%);">-             establish_and_use_egprs_dl_tbf(the_bts, i);</span><br><span style="color: hsl(120, 100%, 40%);">+           establish_and_use_egprs_dl_tbf(bts, i);</span><br><span> </span><br><span>  TALLOC_FREE(the_pcu);</span><br><span>        fprintf(stderr, "=== end %s ===\n", __func__);</span><br><span>@@ -3175,7 +3149,7 @@</span><br><span> {</span><br><span>        the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       uint32_t fn = 2654218;</span><br><span>       int ts_no = 7;</span><br><span>       uint8_t trx_no = 0;</span><br><span>@@ -3184,11 +3158,11 @@</span><br><span> </span><br><span>    fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  setup_bts(the_bts, ts_no, 4);</span><br><span style="color: hsl(120, 100%, 40%);">+ setup_bts(bts, ts_no, 4);</span><br><span> </span><br><span>        int rc = 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- ul_tbf = handle_tbf_reject(the_bts->bts_data(), NULL, tlli,</span><br><span style="color: hsl(120, 100%, 40%);">+        ul_tbf = handle_tbf_reject(bts, NULL, tlli,</span><br><span>                          trx_no, ts_no);</span><br><span> </span><br><span>  OSMO_ASSERT(ul_tbf != 0);</span><br><span>@@ -3196,7 +3170,7 @@</span><br><span>    /* trigger packet access reject */</span><br><span>   uint8_t bn = fn2bn(fn);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     rc = gprs_rlcmac_rcv_rts_block(the_bts->bts_data(),</span><br><span style="color: hsl(120, 100%, 40%);">+        rc = gprs_rlcmac_rcv_rts_block(bts,</span><br><span>          trx_no, ts_no, fn, bn);</span><br><span> </span><br><span>  OSMO_ASSERT(rc == 0);</span><br><span>@@ -3211,7 +3185,7 @@</span><br><span> {</span><br><span>   the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       uint32_t fn = 2654218;</span><br><span>       uint16_t qta = 31;</span><br><span>   int ts_no = 7;</span><br><span>@@ -3228,20 +3202,20 @@</span><br><span> </span><br><span>         fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  setup_bts(the_bts, ts_no, 4);</span><br><span style="color: hsl(120, 100%, 40%);">+ setup_bts(bts, ts_no, 4);</span><br><span> </span><br><span>        int rc = 0;</span><br><span> </span><br><span>      /*</span><br><span>    * Trigger rach till resources(USF) exhaust</span><br><span>   */</span><br><span style="color: hsl(0, 100%, 40%);">-     rc = bts_handle_rach(the_bts, 0x78, rach_fn, qta);</span><br><span style="color: hsl(0, 100%, 40%);">-      rc = bts_handle_rach(the_bts, 0x79, rach_fn, qta);</span><br><span style="color: hsl(0, 100%, 40%);">-      rc = bts_handle_rach(the_bts, 0x7a, rach_fn, qta);</span><br><span style="color: hsl(0, 100%, 40%);">-      rc = bts_handle_rach(the_bts, 0x7b, rach_fn, qta);</span><br><span style="color: hsl(0, 100%, 40%);">-      rc = bts_handle_rach(the_bts, 0x7c, rach_fn, qta);</span><br><span style="color: hsl(0, 100%, 40%);">-      rc = bts_handle_rach(the_bts, 0x7d, rach_fn, qta);</span><br><span style="color: hsl(0, 100%, 40%);">-      rc = bts_handle_rach(the_bts, 0x7e, rach_fn, qta);</span><br><span style="color: hsl(120, 100%, 40%);">+    rc = bts_handle_rach(bts, 0x78, rach_fn, qta);</span><br><span style="color: hsl(120, 100%, 40%);">+        rc = bts_handle_rach(bts, 0x79, rach_fn, qta);</span><br><span style="color: hsl(120, 100%, 40%);">+        rc = bts_handle_rach(bts, 0x7a, rach_fn, qta);</span><br><span style="color: hsl(120, 100%, 40%);">+        rc = bts_handle_rach(bts, 0x7b, rach_fn, qta);</span><br><span style="color: hsl(120, 100%, 40%);">+        rc = bts_handle_rach(bts, 0x7c, rach_fn, qta);</span><br><span style="color: hsl(120, 100%, 40%);">+        rc = bts_handle_rach(bts, 0x7d, rach_fn, qta);</span><br><span style="color: hsl(120, 100%, 40%);">+        rc = bts_handle_rach(bts, 0x7e, rach_fn, qta);</span><br><span> </span><br><span>   /* fake a resource request */</span><br><span>        ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;</span><br><span>@@ -3264,12 +3238,12 @@</span><br><span>                 pmultislotcap->EGPRS_multislot_class = egprs_ms_class;</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);</span><br><span style="color: hsl(120, 100%, 40%);">+        send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);</span><br><span> </span><br><span>       /* trigger packet access reject */</span><br><span>   uint8_t bn = fn2bn(fn);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     rc = gprs_rlcmac_rcv_rts_block(the_bts->bts_data(),</span><br><span style="color: hsl(120, 100%, 40%);">+        rc = gprs_rlcmac_rcv_rts_block(bts,</span><br><span>          trx_no, ts_no, fn, bn);</span><br><span> </span><br><span>  OSMO_ASSERT(rc == 0);</span><br><span>@@ -3282,7 +3256,7 @@</span><br><span> {</span><br><span>   the_pcu = gprs_pcu_alloc(tall_pcu_ctx);</span><br><span>      the_pcu->bts = bts_alloc(the_pcu);</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS *the_bts = the_pcu->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_bts *bts = the_pcu->bts;</span><br><span>       uint32_t tlli = 0xffeeddcc;</span><br><span>  static uint8_t exp[] = { 0x40, 0x84, 0x7f, 0xf7, 0x6e, 0xe6, 0x41, 0x4b,</span><br><span>                              0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,</span><br><span>@@ -3290,8 +3264,8 @@</span><br><span>     };</span><br><span> </span><br><span>       fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span style="color: hsl(0, 100%, 40%);">-      setup_bts(the_bts, 4);</span><br><span style="color: hsl(0, 100%, 40%);">-  static gprs_rlcmac_dl_tbf *dl_tbf = tbf_init(the_bts, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+     setup_bts(bts, 4);</span><br><span style="color: hsl(120, 100%, 40%);">+    static gprs_rlcmac_dl_tbf *dl_tbf = tbf_init(bts, 1);</span><br><span> </span><br><span>    dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);</span><br><span> </span><br><span>diff --git a/tests/types/TypesTest.cpp b/tests/types/TypesTest.cpp</span><br><span>index 7e5d35a..2da6a64 100644</span><br><span>--- a/tests/types/TypesTest.cpp</span><br><span>+++ b/tests/types/TypesTest.cpp</span><br><span>@@ -23,6 +23,7 @@</span><br><span> #include "bts.h"</span><br><span> #include "tbf.h"</span><br><span> #include "tbf_ul.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "tbf_dl.h"</span><br><span> #include "pcu_utils.h"</span><br><span> #include "gprs_debug.h"</span><br><span> #include "encoding.h"</span><br><span>@@ -352,7 +353,7 @@</span><br><span>               uint16_t lost = 0, recv = 0;</span><br><span>                 char show_rbb[65];</span><br><span>           uint8_t bits_data[8];</span><br><span style="color: hsl(0, 100%, 40%);">-           BTS dummy_bts(the_pcu);</span><br><span style="color: hsl(120, 100%, 40%);">+               struct gprs_rlcmac_bts *dummy_bts = bts_alloc(the_pcu);</span><br><span>              gprs_rlc_dl_window dl_win;</span><br><span>           bitvec bits;</span><br><span>                 int bsn_begin, bsn_end, num_blocks;</span><br><span>@@ -391,7 +392,7 @@</span><br><span>            Decoding::extract_rbb(&bits, show_rbb);</span><br><span>          printf("show_rbb: %s\n", show_rbb);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-               dl_win.update(&dummy_bts, &bits, 0, &lost, &recv);</span><br><span style="color: hsl(120, 100%, 40%);">+            dl_win.update(dummy_bts, &bits, 0, &lost, &recv);</span><br><span>                OSMO_ASSERT(lost == 0);</span><br><span>              OSMO_ASSERT(recv == 35);</span><br><span>             OSMO_ASSERT(bsn_begin == 0);</span><br><span>@@ -423,7 +424,7 @@</span><br><span>           printf("show_rbb: %s\n", show_rbb);</span><br><span> </span><br><span>            lost = recv = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                dl_win.update(&dummy_bts, &bits, 0, &lost, &recv);</span><br><span style="color: hsl(120, 100%, 40%);">+            dl_win.update(dummy_bts, &bits, 0, &lost, &recv);</span><br><span>                OSMO_ASSERT(lost == 5);</span><br><span>              OSMO_ASSERT(recv == 3);</span><br><span>              OSMO_ASSERT(bitvec_get_bit_pos(&bits, 0) == 0);</span><br><span>@@ -431,6 +432,7 @@</span><br><span>            OSMO_ASSERT(bsn_begin == 35);</span><br><span>                OSMO_ASSERT(bsn_end == 43);</span><br><span>          OSMO_ASSERT(num_blocks == 8);</span><br><span style="color: hsl(120, 100%, 40%);">+         talloc_free(dummy_bts);</span><br><span>      }</span><br><span> }</span><br><span> </span><br><span>@@ -669,12 +671,12 @@</span><br><span> </span><br><span>       fprintf(stderr, "############## test_egprs_ul_ack_nack\n");</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       BTS the_bts(the_pcu);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);</span><br><span>    the_pcu->alloc_algorithm = alloc_algorithm_a;</span><br><span style="color: hsl(0, 100%, 40%);">-        the_bts.bts_data()->trx[0].pdch[4].enable();</span><br><span style="color: hsl(120, 100%, 40%);">+       bts->trx[0].pdch[4].enable();</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    GprsMs *ms = the_bts.ms_alloc(1, 1);</span><br><span style="color: hsl(0, 100%, 40%);">-    struct gprs_rlcmac_ul_tbf *tbf = tbf_alloc_ul_tbf(the_bts.bts_data(), ms, 0, true);</span><br><span style="color: hsl(120, 100%, 40%);">+   GprsMs *ms = bts_alloc_ms(bts, 1, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_ul_tbf *tbf = tbf_alloc_ul_tbf(bts, ms, 0, true);</span><br><span>         struct crbb_test crbb_test = {0};</span><br><span>    bitvec *rbb = NULL;</span><br><span>  unsigned int rbb_size;</span><br><span>@@ -722,6 +724,7 @@</span><br><span>         extract_egprs_ul_ack_nack(tbf, dest, &ssn, &crbb_test, &rbb, false);</span><br><span>     check_egprs_bitmap(tbf, ssn, &crbb_test, rbb, &rbb_size);</span><br><span>    free_egprs_ul_ack_nack(&rbb, &crbb_test);</span><br><span style="color: hsl(120, 100%, 40%);">+     talloc_free(bts);</span><br><span> }</span><br><span> </span><br><span> static void check_imm_ass(struct gprs_rlcmac_tbf *tbf, bool dl, enum ph_burst_type bt, const uint8_t *exp, uint8_t len,</span><br><span>@@ -759,13 +762,13 @@</span><br><span> </span><br><span> void test_immediate_assign_dl()</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-       BTS the_bts(the_pcu);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);</span><br><span>    the_pcu->alloc_algorithm = alloc_algorithm_a;</span><br><span style="color: hsl(0, 100%, 40%);">-        the_bts.bts_data()->trx[0].pdch[2].enable();</span><br><span style="color: hsl(0, 100%, 40%);">- the_bts.bts_data()->trx[0].pdch[3].enable();</span><br><span style="color: hsl(0, 100%, 40%);">- GprsMs *ms = the_bts.ms_alloc(1, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+  bts->trx[0].pdch[2].enable();</span><br><span style="color: hsl(120, 100%, 40%);">+      bts->trx[0].pdch[3].enable();</span><br><span style="color: hsl(120, 100%, 40%);">+      GprsMs *ms = bts_alloc_ms(bts, 1, 0);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       struct gprs_rlcmac_tbf *tbf = tbf_alloc_dl_tbf(the_bts.bts_data(), ms, 0, false);</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gprs_rlcmac_tbf *tbf = tbf_alloc_dl_tbf(bts, ms, 0, false);</span><br><span>   static uint8_t res[] = { 0x06,</span><br><span>                                0x3f, /* Immediate Assignment Message Type */</span><br><span>                                0x30, /* §10.5.2.26 Page Mode and §10.5.2.25b Dedicated mode/TBF */</span><br><span>@@ -779,17 +782,18 @@</span><br><span>                                0xdf, 0xff, 0xff, 0xff, 0xf8, 0x17, 0x47, 0x08, 0x0b, 0x5b, 0x2b, 0x2b, };</span><br><span> </span><br><span>      check_imm_ass(tbf, true, GSM_L1_BURST_TYPE_ACCESS_2, res, sizeof(res), "ia_rest_downlink");</span><br><span style="color: hsl(120, 100%, 40%);">+ talloc_free(bts);</span><br><span> }</span><br><span> </span><br><span> void test_immediate_assign_ul0m()</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-    BTS the_bts(the_pcu);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);</span><br><span>    the_pcu->alloc_algorithm = alloc_algorithm_a;</span><br><span style="color: hsl(0, 100%, 40%);">-        the_bts.bts_data()->trx[0].pdch[4].enable();</span><br><span style="color: hsl(0, 100%, 40%);">- the_bts.bts_data()->trx[0].pdch[5].enable();</span><br><span style="color: hsl(120, 100%, 40%);">+       bts->trx[0].pdch[4].enable();</span><br><span style="color: hsl(120, 100%, 40%);">+      bts->trx[0].pdch[5].enable();</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    GprsMs *ms = the_bts.ms_alloc(1, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-    struct gprs_rlcmac_tbf *tbf = tbf_alloc_ul_tbf(the_bts.bts_data(), ms, 0, false);</span><br><span style="color: hsl(120, 100%, 40%);">+     GprsMs *ms = bts_alloc_ms(bts, 1, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_tbf *tbf = tbf_alloc_ul_tbf(bts, ms, 0, false);</span><br><span>   static uint8_t res[] = { 0x06,</span><br><span>                                0x3f, /* Immediate Assignment Message Type */</span><br><span>                                0x10, /* §10.5.2.26 Page Mode and §10.5.2.25b Dedicated mode/TBF */</span><br><span>@@ -803,6 +807,7 @@</span><br><span>                                  0xc8, 0x02, 0x1b, 0xa2, 0x0b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, };</span><br><span> </span><br><span>      check_imm_ass(tbf, false, GSM_L1_BURST_TYPE_ACCESS_0, res, sizeof(res), "ia_rest_uplink(MBA)");</span><br><span style="color: hsl(120, 100%, 40%);">+     talloc_free(bts);</span><br><span> }</span><br><span> </span><br><span> void test_immediate_assign_ul0s()</span><br><span>@@ -824,13 +829,13 @@</span><br><span> </span><br><span> void test_immediate_assign_ul1s()</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS the_bts(the_pcu);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);</span><br><span>    the_pcu->alloc_algorithm = alloc_algorithm_a;</span><br><span style="color: hsl(0, 100%, 40%);">-        the_bts.bts_data()->trx[0].pdch[1].enable();</span><br><span style="color: hsl(0, 100%, 40%);">- the_bts.bts_data()->trx[0].pdch[2].enable();</span><br><span style="color: hsl(120, 100%, 40%);">+       bts->trx[0].pdch[1].enable();</span><br><span style="color: hsl(120, 100%, 40%);">+      bts->trx[0].pdch[2].enable();</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    GprsMs *ms = the_bts.ms_alloc(1, 1);</span><br><span style="color: hsl(0, 100%, 40%);">-    struct gprs_rlcmac_tbf *tbf = tbf_alloc_ul_tbf(the_bts.bts_data(), ms, 0, false);</span><br><span style="color: hsl(120, 100%, 40%);">+     GprsMs *ms = bts_alloc_ms(bts, 1, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_tbf *tbf = tbf_alloc_ul_tbf(bts, ms, 0, false);</span><br><span>   static uint8_t res[] = { 0x06,</span><br><span>                                0x3f, /* Immediate Assignment Message Type */</span><br><span>                                0x10, /* §10.5.2.26 Page Mode and §10.5.2.25b Dedicated mode/TBF */</span><br><span>@@ -844,6 +849,7 @@</span><br><span>                                  0x46, 0xa0, 0x08, 0x00, 0x17, 0x44, 0x0b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, };</span><br><span> </span><br><span>      check_imm_ass(tbf, false, GSM_L1_BURST_TYPE_ACCESS_1, res, sizeof(res), "ia_rest_egprs_uplink(SBA)");</span><br><span style="color: hsl(120, 100%, 40%);">+       talloc_free(bts);</span><br><span> }</span><br><span> </span><br><span> void test_immediate_assign_ul1m()</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-pcu/+/22196">change 22196</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-pcu/+/22196"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-pcu </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I7d12c896c5ded659ca9d3bff4cf3a3fc857db9dd </div>
<div style="display:none"> Gerrit-Change-Number: 22196 </div>
<div style="display:none"> Gerrit-PatchSet: 7 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: lynxis lazus <lynxis@fe80.eu> </div>
<div style="display:none"> Gerrit-Reviewer: osmith <osmith@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>