diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bts.cpp | 403 | ||||
-rw-r--r-- | src/bts.h | 324 | ||||
-rw-r--r-- | src/encoding.cpp | 1 | ||||
-rw-r--r-- | src/gprs_bssgp_pcu.cpp | 11 | ||||
-rw-r--r-- | src/gprs_ms.c | 10 | ||||
-rw-r--r-- | src/gprs_ms.h | 6 | ||||
-rw-r--r-- | src/gprs_ms_storage.cpp | 6 | ||||
-rw-r--r-- | src/gprs_ms_storage.h | 8 | ||||
-rw-r--r-- | src/gprs_pcu.c | 12 | ||||
-rw-r--r-- | src/gprs_pcu.h | 3 | ||||
-rw-r--r-- | src/gprs_rlcmac_sched.cpp | 34 | ||||
-rw-r--r-- | src/gprs_rlcmac_ts_alloc.cpp | 10 | ||||
-rw-r--r-- | src/gsm_timer.cpp | 5 | ||||
-rw-r--r-- | src/llc.cpp | 6 | ||||
-rw-r--r-- | src/llc.h | 6 | ||||
-rw-r--r-- | src/pcu_l1_if.cpp | 27 | ||||
-rw-r--r-- | src/pcu_main.cpp | 2 | ||||
-rw-r--r-- | src/pcu_vty_functions.cpp | 35 | ||||
-rw-r--r-- | src/pdch.cpp | 60 | ||||
-rw-r--r-- | src/pdch.h | 2 | ||||
-rw-r--r-- | src/poll_controller.cpp | 17 | ||||
-rw-r--r-- | src/poll_controller.h | 8 | ||||
-rw-r--r-- | src/rlc.cpp | 8 | ||||
-rw-r--r-- | src/rlc.h | 6 | ||||
-rw-r--r-- | src/sba.cpp | 10 | ||||
-rw-r--r-- | src/sba.h | 8 | ||||
-rw-r--r-- | src/tbf.cpp | 91 | ||||
-rw-r--r-- | src/tbf.h | 20 | ||||
-rw-r--r-- | src/tbf_dl.cpp | 78 | ||||
-rw-r--r-- | src/tbf_dl.h | 2 | ||||
-rw-r--r-- | src/tbf_ul.cpp | 54 | ||||
-rw-r--r-- | src/tbf_ul.h | 2 |
32 files changed, 584 insertions, 691 deletions
diff --git a/src/bts.cpp b/src/bts.cpp index a50e8ae8..294739c5 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -31,6 +31,8 @@ #include <gprs_debug.h> #include <cxx_linuxlist.h> #include <pdch.h> +#include <gprs_ms_storage.h> +#include <sba.h> extern "C" { #include <osmocom/core/talloc.h> @@ -190,9 +192,20 @@ static const struct osmo_stat_item_group_desc bts_statg_desc = { bts_stat_item_description, }; -static void bts_init(struct gprs_rlcmac_bts *bts, BTS* bts_obj) +static void bts_init(struct gprs_rlcmac_bts *bts, struct gprs_pcu *pcu) { - memset(bts, 0, sizeof(*bts)); + bts->pcu = pcu; + + bts->pollController = new PollController(*bts); + bts->sba = new SBAController(*bts); + bts->ms_store = new GprsMsStorage(bts); + + bts->cur_fn = 0; + bts->cur_blk_fn = -1; + bts->max_cs_dl = MAX_GPRS_CS; + bts->max_cs_ul = MAX_GPRS_CS; + bts->max_mcs_dl = MAX_EDGE_MCS; + bts->max_mcs_ul = MAX_EDGE_MCS; bts->initial_cs_dl = bts->initial_cs_ul = 1; bts->initial_mcs_dl = bts->initial_mcs_ul = 1; bts->cs_mask = 1 << 0; /* CS-1 always enabled by default */ @@ -202,15 +215,17 @@ static void bts_init(struct gprs_rlcmac_bts *bts, BTS* bts_obj) bts->si13_is_set = false; bts->app_info = NULL; - bts->bts = bts_obj; bts->T_defs_bts = T_defs_bts; osmo_tdefs_reset(bts->T_defs_bts); + INIT_LLIST_HEAD(&bts->ul_tbfs); + INIT_LLIST_HEAD(&bts->dl_tbfs); + /* initialize back pointers */ for (size_t trx_no = 0; trx_no < ARRAY_SIZE(bts->trx); ++trx_no) { struct gprs_rlcmac_trx *trx = &bts->trx[trx_no]; trx->trx_no = trx_no; - trx->bts = bts_obj; + trx->bts = bts; for (size_t ts_no = 0; ts_no < ARRAY_SIZE(trx->pdch); ++ts_no) { struct gprs_rlcmac_pdch *pdch = &trx->pdch[ts_no]; @@ -219,89 +234,57 @@ static void bts_init(struct gprs_rlcmac_bts *bts, BTS* bts_obj) pdch->trx = trx; } } -} -BTS* BTS::main_bts() -{ - return the_pcu->bts; -} + /* The static allocator might have already registered the counter group. + If this happens and we still called explicitly (in tests/ for example) + than just allocate the group with different index. + This shall be removed once weget rid of BTS singleton */ + if (rate_ctr_get_group_by_name_idx(bts_ctrg_desc.group_name_prefix, 0)) + bts->ratectrs = rate_ctr_group_alloc(tall_pcu_ctx, &bts_ctrg_desc, 1); + else + bts->ratectrs = rate_ctr_group_alloc(tall_pcu_ctx, &bts_ctrg_desc, 0); + OSMO_ASSERT(bts->ratectrs); -struct gprs_rlcmac_bts *BTS::bts_data() -{ - return &m_bts; + bts->statg = osmo_stat_item_group_alloc(tall_pcu_ctx, &bts_statg_desc, 0); + OSMO_ASSERT(bts->statg); } struct gprs_rlcmac_bts *bts_main_data() { - return BTS::main_bts()->bts_data(); -} - -void bts_cleanup() -{ - return BTS::main_bts()->cleanup(); + return the_pcu->bts; } struct rate_ctr_group *bts_main_data_stats() { - return BTS::main_bts()->rate_counters(); -} - -BTS::BTS(struct gprs_pcu *pcu) - : pcu(pcu) - , m_cur_fn(0) - , m_cur_blk_fn(-1) - , m_max_cs_dl(MAX_GPRS_CS) - , m_max_cs_ul(MAX_GPRS_CS) - , m_max_mcs_dl(MAX_EDGE_MCS) - , m_max_mcs_ul(MAX_EDGE_MCS) - , m_pollController(*this) - , m_sba(*this) - , m_ms_store(this) -{ - bts_init(&m_bts, this); - - /* The static allocator might have already registered the counter group. - If this happens and we still called explicitly (in tests/ for example) - than just allocate the group with different index. - This shall be removed once weget rid of BTS singleton */ - if (rate_ctr_get_group_by_name_idx(bts_ctrg_desc.group_name_prefix, 0)) - m_ratectrs = rate_ctr_group_alloc(tall_pcu_ctx, &bts_ctrg_desc, 1); - else - m_ratectrs = rate_ctr_group_alloc(tall_pcu_ctx, &bts_ctrg_desc, 0); - OSMO_ASSERT(m_ratectrs); - - m_statg = osmo_stat_item_group_alloc(tall_pcu_ctx, &bts_statg_desc, 0); - OSMO_ASSERT(m_statg); + return bts_rate_counters(the_pcu->bts); } -void BTS::cleanup() +static void bts_cleanup(gprs_rlcmac_bts *bts) { /* this can cause counter updates and must not be left to the * m_ms_store's destructor */ - m_ms_store.cleanup(); - - if (m_ratectrs) { - rate_ctr_group_free(m_ratectrs); - m_ratectrs = NULL; + bts->ms_store->cleanup(); + delete bts->ms_store; + delete bts->sba; + delete bts->pollController; + + if (bts->ratectrs) { + rate_ctr_group_free(bts->ratectrs); + bts->ratectrs = NULL; } - if (m_statg) { - osmo_stat_item_group_free(m_statg); - m_statg = NULL; + if (bts->statg) { + osmo_stat_item_group_free(bts->statg); + bts->statg = NULL; } - if (m_bts.app_info) { - msgb_free(m_bts.app_info); - m_bts.app_info = NULL; + if (bts->app_info) { + msgb_free(bts->app_info); + bts->app_info = NULL; } } -BTS::~BTS() -{ - cleanup(); -} - -void BTS::set_current_frame_number(int fn) +void bts_set_current_frame_number(struct gprs_rlcmac_bts *bts, int fn) { /* The UL frame numbers lag 3 behind the DL frames and the data * indication is only sent after all 4 frames of the block have been @@ -314,8 +297,8 @@ void BTS::set_current_frame_number(int fn) * Values up to 50 frames have been observed under load. */ const static int max_delay = 60; - m_cur_fn = fn; - m_pollController.expireTimedout(m_cur_fn, max_delay); + bts->cur_fn = fn; + bts->pollController->expireTimedout(bts->cur_fn, max_delay); } static inline int delta_fn(int fn, int to) @@ -323,7 +306,7 @@ static inline int delta_fn(int fn, int to) return (fn + GSM_MAX_FN * 3 / 2 - to) % GSM_MAX_FN - GSM_MAX_FN/2; } -void BTS::set_current_block_frame_number(int fn, unsigned max_delay) +void bts_set_current_block_frame_number(struct gprs_rlcmac_bts *bts, int fn, unsigned max_delay) { int delay = 0; const int late_block_delay_thresh = 13; @@ -332,41 +315,41 @@ void BTS::set_current_block_frame_number(int fn, unsigned max_delay) /* frame numbers in the received blocks are assumed to be strongly * monotonic. */ - if (m_cur_blk_fn >= 0) { - int delta = delta_fn(fn, m_cur_blk_fn); + if (bts->cur_blk_fn >= 0) { + int delta = delta_fn(fn, bts->cur_blk_fn); if (delta <= 0) return; } /* Check block delay vs. the current frame number */ - if (current_frame_number() != 0) - delay = delta_fn(fn, current_frame_number()); + if (bts_current_frame_number(bts) != 0) + delay = delta_fn(fn, bts_current_frame_number(bts)); if (delay <= -late_block_delay_thresh) { LOGP(DRLCMAC, LOGL_NOTICE, "Late RLC block, FN delta: %d FN: %d curFN: %d\n", - delay, fn, current_frame_number()); - do_rate_ctr_inc(CTR_RLC_LATE_BLOCK); + delay, fn, bts_current_frame_number(bts)); + bts_do_rate_ctr_inc(bts, CTR_RLC_LATE_BLOCK); } - m_cur_blk_fn = fn; + bts->cur_blk_fn = fn; if (delay < fn_update_ok_min_delay || delay > fn_update_ok_max_delay || - current_frame_number() == 0) - m_cur_fn = fn; + bts_current_frame_number(bts) == 0) + bts->cur_fn = fn; - m_pollController.expireTimedout(fn, max_delay); + bts->pollController->expireTimedout(fn, max_delay); } -int BTS::add_paging(uint8_t chan_needed, const struct osmo_mobile_identity *mi) +int bts_add_paging(struct gprs_rlcmac_bts *bts, uint8_t chan_needed, const struct osmo_mobile_identity *mi) { uint8_t l, trx, ts, any_tbf = 0; struct gprs_rlcmac_tbf *tbf; - LListHead<gprs_rlcmac_tbf> *pos; + struct llist_item *pos; uint8_t slot_mask[8]; int8_t first_ts; /* must be signed */ - LListHead<gprs_rlcmac_tbf> *tbfs_lists[] = { - &m_ul_tbfs, - &m_dl_tbfs, + struct llist_head *tbfs_lists[] = { + &bts->ul_tbfs, + &bts->dl_tbfs, NULL }; @@ -382,8 +365,8 @@ int BTS::add_paging(uint8_t chan_needed, const struct osmo_mobile_identity *mi) * Don't mark, if TBF uses a different slot that is already marked. */ memset(slot_mask, 0, sizeof(slot_mask)); for (l = 0; tbfs_lists[l]; l++) { - llist_for_each(pos, tbfs_lists[l]) { - tbf = pos->entry(); + llist_for_each_entry(pos, tbfs_lists[l], list) { + tbf = (struct gprs_rlcmac_tbf *)pos->entry; first_ts = -1; for (ts = 0; ts < 8; ts++) { if (tbf->pdch[ts]) { @@ -418,7 +401,7 @@ int BTS::add_paging(uint8_t chan_needed, const struct osmo_mobile_identity *mi) for (ts = 0; ts < 8; ts++) { if ((slot_mask[trx] & (1 << ts))) { /* schedule */ - if (!m_bts.trx[trx].pdch[ts].add_paging(chan_needed, mi)) + if (!bts->trx[trx].pdch[ts].add_paging(chan_needed, mi)) return -ENOMEM; LOGP(DRLCMAC, LOGL_INFO, "Paging on PACCH of TRX=%d TS=%d\n", trx, ts); @@ -433,8 +416,9 @@ int BTS::add_paging(uint8_t chan_needed, const struct osmo_mobile_identity *mi) return 0; } -void BTS::send_gsmtap_rach(enum pcu_gsmtap_category categ, uint8_t channel, - const struct rach_ind_params *rip) +void bts_send_gsmtap_rach(struct gprs_rlcmac_bts *bts, + enum pcu_gsmtap_category categ, uint8_t channel, + const struct rach_ind_params *rip) { struct pcu_l1_meas meas = { 0 }; uint8_t ra_buf[2]; @@ -450,37 +434,39 @@ void BTS::send_gsmtap_rach(enum pcu_gsmtap_category categ, uint8_t channel, ra_buf[0] = (uint8_t) (rip->ra & 0xff); } - send_gsmtap_meas(categ, true, rip->trx_nr, rip->ts_nr, channel, - rfn_to_fn(rip->rfn), ra_buf, + bts_send_gsmtap_meas(bts, categ, true, rip->trx_nr, rip->ts_nr, channel, + bts_rfn_to_fn(bts, rip->rfn), ra_buf, rip->is_11bit ? 2 : 1, &meas); } -void BTS::send_gsmtap(enum pcu_gsmtap_category categ, bool uplink, uint8_t trx_no, - uint8_t ts_no, uint8_t channel, uint32_t fn, - const uint8_t *data, unsigned int len) +void bts_send_gsmtap(struct gprs_rlcmac_bts *bts, + enum pcu_gsmtap_category categ, bool uplink, uint8_t trx_no, + uint8_t ts_no, uint8_t channel, uint32_t fn, + const uint8_t *data, unsigned int len) { struct pcu_l1_meas meas = { 0 }; - send_gsmtap_meas(categ, uplink, trx_no, ts_no, channel, fn, data, len, &meas); + bts_send_gsmtap_meas(bts, categ, uplink, trx_no, ts_no, channel, fn, data, len, &meas); } -void BTS::send_gsmtap_meas(enum pcu_gsmtap_category categ, bool uplink, uint8_t trx_no, - uint8_t ts_no, uint8_t channel, uint32_t fn, - const uint8_t *data, unsigned int len, struct pcu_l1_meas *meas) +void bts_send_gsmtap_meas(struct gprs_rlcmac_bts *bts, + enum pcu_gsmtap_category categ, bool uplink, uint8_t trx_no, + uint8_t ts_no, uint8_t channel, uint32_t fn, + const uint8_t *data, unsigned int len, struct pcu_l1_meas *meas) { uint16_t arfcn; /* check if category is activated at all */ - if (!(pcu->gsmtap_categ_mask & (1 << categ))) + if (!(bts->pcu->gsmtap_categ_mask & (1 << categ))) return; - arfcn = m_bts.trx[trx_no].arfcn; + arfcn = bts->trx[trx_no].arfcn; if (uplink) arfcn |= GSMTAP_ARFCN_F_UPLINK; /* GSMTAP needs the SNR here, but we only have C/I (meas->link_qual). Those are not the same, but there is no known way to convert them, let's pass C/I instead of nothing */ - gsmtap_send(pcu->gsmtap, arfcn, ts_no, channel, 0, fn, + gsmtap_send(bts->pcu->gsmtap, arfcn, ts_no, channel, 0, fn, meas->rssi, meas->link_qual, data, len); } @@ -493,48 +479,52 @@ static inline bool tbf_check(gprs_rlcmac_tbf *tbf, uint32_t fn, uint8_t trx_no, return false; } -gprs_rlcmac_dl_tbf *BTS::dl_tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts) +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) { - LListHead<gprs_rlcmac_tbf> *pos; + struct llist_item *pos; + struct gprs_rlcmac_tbf *tbf; /* only one TBF can poll on specific TS/FN, because scheduler can only * schedule one downlink control block (with polling) at a FN per TS */ - llist_for_each(pos, &m_dl_tbfs) { - if (tbf_check(pos->entry(), fn, trx, ts)) - return as_dl_tbf(pos->entry()); + llist_for_each_entry(pos, &bts->dl_tbfs, list) { + tbf = (struct gprs_rlcmac_tbf *)pos->entry; + if (tbf_check(tbf, fn, trx, ts)) + return as_dl_tbf(tbf); } return NULL; } -gprs_rlcmac_ul_tbf *BTS::ul_tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts) +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) { - LListHead<gprs_rlcmac_tbf> *pos; + struct llist_item *pos; + struct gprs_rlcmac_tbf *tbf; /* only one TBF can poll on specific TS/FN, because scheduler can only * schedule one downlink control block (with polling) at a FN per TS */ - llist_for_each(pos, &m_ul_tbfs) { - if (tbf_check(pos->entry(), fn, trx, ts)) - return as_ul_tbf(pos->entry()); + llist_for_each_entry(pos, &bts->ul_tbfs, list) { + tbf = (struct gprs_rlcmac_tbf *)pos->entry; + if (tbf_check(tbf, fn, trx, ts)) + return as_ul_tbf(tbf); } return NULL; } /* lookup downlink TBF Entity (by TFI) */ -gprs_rlcmac_dl_tbf *BTS::dl_tbf_by_tfi(uint8_t tfi, uint8_t trx, uint8_t ts) +struct gprs_rlcmac_dl_tbf *bts_dl_tbf_by_tfi(struct gprs_rlcmac_bts *bts, uint8_t tfi, uint8_t trx, uint8_t ts) { if (trx >= 8 || ts >= 8) return NULL; - return m_bts.trx[trx].pdch[ts].dl_tbf_by_tfi(tfi); + return bts->trx[trx].pdch[ts].dl_tbf_by_tfi(tfi); } /* lookup uplink TBF Entity (by TFI) */ -gprs_rlcmac_ul_tbf *BTS::ul_tbf_by_tfi(uint8_t tfi, uint8_t trx, uint8_t ts) +struct gprs_rlcmac_ul_tbf *bts_ul_tbf_by_tfi(struct gprs_rlcmac_bts *bts, uint8_t tfi, uint8_t trx, uint8_t ts) { if (trx >= 8 || ts >= 8) return NULL; - return m_bts.trx[trx].pdch[ts].ul_tbf_by_tfi(tfi); + return bts->trx[trx].pdch[ts].ul_tbf_by_tfi(tfi); } static unsigned int trx_count_free_tfi(const struct gprs_rlcmac_trx *trx, enum gprs_rlcmac_tbf_direction dir, uint8_t *first_free_tfi) @@ -576,7 +566,8 @@ static unsigned int trx_count_free_tfi(const struct gprs_rlcmac_trx *trx, enum g * that is currently not used in any PDCH of a the TRX with least TFIs currently * assigned. Negative values indicate errors. */ -int BTS::tfi_find_free(enum gprs_rlcmac_tbf_direction dir, uint8_t *_trx, int8_t use_trx) const +int bts_tfi_find_free(const struct gprs_rlcmac_bts *bts, enum gprs_rlcmac_tbf_direction dir, + uint8_t *_trx, int8_t use_trx) { uint8_t trx_from, trx_to, trx; uint8_t best_trx_nr = 0xff; @@ -594,7 +585,7 @@ int BTS::tfi_find_free(enum gprs_rlcmac_tbf_direction dir, uint8_t *_trx, int8_t for (trx = trx_from; trx <= trx_to; trx++) { uint8_t tmp_first_tfi; unsigned int tmp_cnt; - tmp_cnt = trx_count_free_tfi(&m_bts.trx[trx], dir, &tmp_first_tfi); + tmp_cnt = trx_count_free_tfi(&bts->trx[trx], dir, &tmp_first_tfi); if (tmp_cnt > best_cnt) { best_cnt = tmp_cnt; best_first_tfi = tmp_first_tfi; @@ -615,7 +606,7 @@ int BTS::tfi_find_free(enum gprs_rlcmac_tbf_direction dir, uint8_t *_trx, int8_t return best_first_tfi; } -int BTS::rcv_imm_ass_cnf(const uint8_t *data, uint32_t fn) +int bts_rcv_imm_ass_cnf(struct gprs_rlcmac_bts *bts, const uint8_t *data, uint32_t fn) { struct gprs_rlcmac_dl_tbf *dl_tbf = NULL; uint8_t plen; @@ -640,7 +631,7 @@ int BTS::rcv_imm_ass_cnf(const uint8_t *data, uint32_t fn) tlli |= (*data++) << 4; tlli |= (*data++) >> 4; - ms = ms_by_tlli(tlli); + ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI); if (ms) dl_tbf = ms_dl_tbf(ms); if (!dl_tbf) { @@ -658,7 +649,7 @@ int BTS::rcv_imm_ass_cnf(const uint8_t *data, uint32_t fn) } /* Determine the full frame number from a relative frame number */ -uint32_t BTS::rfn_to_fn(int32_t rfn) +uint32_t bts_rfn_to_fn(const struct gprs_rlcmac_bts *bts, int32_t rfn) { int32_t m_cur_rfn; int32_t fn; @@ -682,11 +673,11 @@ uint32_t BTS::rfn_to_fn(int32_t rfn) /* Compute an internal relative frame number from the full internal frame number */ - m_cur_rfn = m_cur_fn % RFN_MODULUS; + m_cur_rfn = bts->cur_fn % RFN_MODULUS; /* Compute a "rounded" version of the internal frame number, which * exactly fits in the RFN_MODULUS raster */ - fn_rounded = m_cur_fn - m_cur_rfn; + fn_rounded = bts->cur_fn - m_cur_rfn; /* If the delta between the internal and the external relative frame * number exceeds a certain limit, we need to assume that the incoming @@ -695,7 +686,7 @@ uint32_t BTS::rfn_to_fn(int32_t rfn) if (abs(rfn - m_cur_rfn) > RFN_THRESHOLD) { LOGP(DRLCMAC, LOGL_DEBUG, "Race condition between rfn (%u) and m_cur_fn (%u) detected: rfn belongs to the previous modulus %u cycle, wrapping...\n", - rfn, m_cur_fn, RFN_MODULUS); + rfn, bts->cur_fn, RFN_MODULUS); if (fn_rounded < RFN_MODULUS) { LOGP(DRLCMAC, LOGL_DEBUG, "Cornercase detected: wrapping crosses %u border\n", @@ -819,7 +810,7 @@ static int parse_rach_ind(const struct rach_ind_params *rip, return 0; } -int BTS::rcv_rach(const struct rach_ind_params *rip) +int bts_rcv_rach(struct gprs_rlcmac_bts *bts, const struct rach_ind_params *rip) { struct chan_req_params chan_req = { 0 }; struct gprs_rlcmac_ul_tbf *tbf = NULL; @@ -829,16 +820,16 @@ int BTS::rcv_rach(const struct rach_ind_params *rip) uint8_t tsc = 0; int plen, rc; - do_rate_ctr_inc(CTR_RACH_REQUESTS); + bts_do_rate_ctr_inc(bts, CTR_RACH_REQUESTS); if (rip->is_11bit) - do_rate_ctr_inc(CTR_11BIT_RACH_REQUESTS); + bts_do_rate_ctr_inc(bts, CTR_11BIT_RACH_REQUESTS); /* Determine full frame number */ - uint32_t Fn = rfn_to_fn(rip->rfn); + uint32_t Fn = bts_rfn_to_fn(bts, rip->rfn); uint8_t ta = qta2ta(rip->qta); - send_gsmtap_rach(PCU_GSMTAP_C_UL_RACH, GSMTAP_CHANNEL_RACH, rip); + bts_send_gsmtap_rach(bts, PCU_GSMTAP_C_UL_RACH, GSMTAP_CHANNEL_RACH, rip); LOGP(DRLCMAC, LOGL_DEBUG, "MS requests Uplink resource on CCCH/RACH: " "ra=0x%02x (%d bit) Fn=%u qta=%d\n", rip->ra, @@ -851,7 +842,7 @@ int BTS::rcv_rach(const struct rach_ind_params *rip) if (chan_req.single_block) LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block allocation\n"); - else if (pcu->vty.force_two_phase) { + else if (bts->pcu->vty.force_two_phase) { LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block allocation, " "but we force two phase access\n"); chan_req.single_block = true; @@ -864,7 +855,7 @@ int BTS::rcv_rach(const struct rach_ind_params *rip) /* Should we allocate a single block or an Uplink TBF? */ if (chan_req.single_block) { - rc = sba()->alloc(&trx_no, &ts_no, &sb_fn, ta); + rc = bts_sba(bts)->alloc(&trx_no, &ts_no, &sb_fn, ta); if (rc < 0) { LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource for " "single block allocation: rc=%d\n", rc); @@ -872,12 +863,12 @@ int BTS::rcv_rach(const struct rach_ind_params *rip) goto send_imm_ass_rej; } - tsc = m_bts.trx[trx_no].pdch[ts_no].tsc; + tsc = bts->trx[trx_no].pdch[ts_no].tsc; LOGP(DRLCMAC, LOGL_DEBUG, "Allocated a single block at " "SBFn=%u TRX=%u TS=%u\n", sb_fn, trx_no, ts_no); } else { - GprsMs *ms = ms_alloc(0, chan_req.egprs_mslot_class); - tbf = tbf_alloc_ul_tbf(&m_bts, ms, -1, true); + GprsMs *ms = bts_alloc_ms(bts, 0, chan_req.egprs_mslot_class); + tbf = tbf_alloc_ul_tbf(bts, ms, -1, true); if (!tbf) { LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource for Uplink TBF\n"); /* Send RR Immediate Assignment Reject */ @@ -905,18 +896,18 @@ send_imm_ass_rej: LOGP(DRLCMAC, LOGL_DEBUG, "Tx Immediate Assignment Reject on AGCH\n"); plen = Encoding::write_immediate_assignment_reject( bv, rip->ra, Fn, rip->burst_type); - do_rate_ctr_inc(CTR_IMMEDIATE_ASSIGN_REJ); + bts_do_rate_ctr_inc(bts, CTR_IMMEDIATE_ASSIGN_REJ); } else { LOGP(DRLCMAC, LOGL_DEBUG, "Tx Immediate Assignment on AGCH: " "TRX=%u (ARFCN %u) TS=%u TA=%u TSC=%u TFI=%d USF=%d\n", - trx_no, m_bts.trx[trx_no].arfcn & ~ARFCN_FLAG_MASK, + trx_no, bts->trx[trx_no].arfcn & ~ARFCN_FLAG_MASK, ts_no, ta, tsc, tbf ? tbf->tfi() : -1, usf); plen = Encoding::write_immediate_assignment( - &m_bts.trx[trx_no].pdch[ts_no], tbf, bv, + &bts->trx[trx_no].pdch[ts_no], tbf, bv, false, rip->ra, Fn, ta, usf, false, sb_fn, - pcu->vty.alpha, pcu->vty.gamma, -1, + bts->pcu->vty.alpha, bts->pcu->vty.gamma, -1, rip->burst_type); - do_rate_ctr_inc(CTR_IMMEDIATE_ASSIGN_UL_TBF); + bts_do_rate_ctr_inc(bts, CTR_IMMEDIATE_ASSIGN_UL_TBF); } if (plen >= 0) @@ -937,14 +928,13 @@ static uint32_t ptcch_slot_map[PTCCH_TAI_NUM] = { 324, 350, 376, 402, }; -int BTS::rcv_ptcch_rach(const struct rach_ind_params *rip) +int bts_rcv_ptcch_rach(struct gprs_rlcmac_bts *bts, const struct rach_ind_params *rip) { - uint32_t fn416 = rfn_to_fn(rip->rfn) % 416; - struct gprs_rlcmac_bts *bts = bts_data(); + uint32_t fn416 = bts_rfn_to_fn(bts, rip->rfn) % 416; struct gprs_rlcmac_pdch *pdch; uint8_t ss; - send_gsmtap_rach(PCU_GSMTAP_C_UL_PTCCH, GSMTAP_CHANNEL_PTCCH, rip); + bts_send_gsmtap_rach(bts, PCU_GSMTAP_C_UL_PTCCH, GSMTAP_CHANNEL_PTCCH, rip); /* Prevent buffer overflow */ if (rip->trx_nr >= ARRAY_SIZE(bts->trx) || rip->ts_nr >= 8) { @@ -979,7 +969,7 @@ int BTS::rcv_ptcch_rach(const struct rach_ind_params *rip) return 0; } -void BTS::snd_dl_ass(gprs_rlcmac_tbf *tbf, bool poll, uint16_t pgroup) +void bts_snd_dl_ass(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *tbf, bool poll, uint16_t pgroup) { uint8_t trx_no = tbf->trx->trx_no; uint8_t ts_no = tbf->first_ts; @@ -992,14 +982,14 @@ void BTS::snd_dl_ass(gprs_rlcmac_tbf *tbf, bool poll, uint16_t pgroup) * so the assignment will not conflict with possible RACH requests. */ LOGP(DRLCMAC, LOGL_DEBUG, " - TRX=%d (%d) TS=%d TA=%d pollFN=%d\n", trx_no, tbf->trx->arfcn, ts_no, tbf->ta(), poll ? tbf->poll_fn : -1); - plen = Encoding::write_immediate_assignment(&m_bts.trx[trx_no].pdch[ts_no], + plen = Encoding::write_immediate_assignment(&bts->trx[trx_no].pdch[ts_no], tbf, immediate_assignment, true, 125, (tbf->pdch[ts_no]->last_rts_fn + 21216) % GSM_MAX_FN, tbf->ta(), 7, poll, tbf->poll_fn, - pcu->vty.alpha, pcu->vty.gamma, -1, + bts->pcu->vty.alpha, bts->pcu->vty.gamma, -1, GSM_L1_BURST_TYPE_ACCESS_0); if (plen >= 0) { - do_rate_ctr_inc(CTR_IMMEDIATE_ASSIGN_DL_TBF); + bts_do_rate_ctr_inc(bts, CTR_IMMEDIATE_ASSIGN_DL_TBF); pcu_l1if_tx_pch(immediate_assignment, plen, pgroup); } @@ -1007,70 +997,70 @@ void BTS::snd_dl_ass(gprs_rlcmac_tbf *tbf, bool poll, uint16_t pgroup) } /* return maximum DL CS supported by BTS and allowed by VTY */ -uint8_t BTS::max_cs_dl(void) const +uint8_t bts_max_cs_dl(const struct gprs_rlcmac_bts* bts) { - return m_max_cs_dl; + return bts->max_cs_dl; } /* return maximum UL CS supported by BTS and allowed by VTY */ -uint8_t BTS::max_cs_ul(void) const +uint8_t bts_max_cs_ul(const struct gprs_rlcmac_bts* bts) { - return m_max_cs_ul; + return bts->max_cs_ul; } /* return maximum DL MCS supported by BTS and allowed by VTY */ -uint8_t BTS::max_mcs_dl(void) const +uint8_t bts_max_mcs_dl(const struct gprs_rlcmac_bts* bts) { - return m_max_mcs_dl; + return bts->max_mcs_dl; } /* return maximum UL MCS supported by BTS and allowed by VTY */ -uint8_t BTS::max_mcs_ul(void) const +uint8_t bts_max_mcs_ul(const struct gprs_rlcmac_bts* bts) { - return m_max_mcs_ul; + return bts->max_mcs_ul; } /* Set maximum DL CS supported by BTS and allowed by VTY */ -void BTS::set_max_cs_dl(uint8_t cs_dl) +void bts_set_max_cs_dl(struct gprs_rlcmac_bts* bts, uint8_t cs_dl) { - m_max_cs_dl = cs_dl; + bts->max_cs_dl = cs_dl; } /* Set maximum UL CS supported by BTS and allowed by VTY */ -void BTS::set_max_cs_ul(uint8_t cs_ul) +void bts_set_max_cs_ul(struct gprs_rlcmac_bts* bts, uint8_t cs_ul) { - m_max_cs_ul = cs_ul; + bts->max_cs_ul = cs_ul; } /* Set maximum DL MCS supported by BTS and allowed by VTY */ -void BTS::set_max_mcs_dl(uint8_t mcs_dl) +void bts_set_max_mcs_dl(struct gprs_rlcmac_bts* bts, uint8_t mcs_dl) { - m_max_mcs_dl = mcs_dl; + bts->max_mcs_dl = mcs_dl; } /* Set maximum UL MCS supported by BTS and allowed by VTY */ -void BTS::set_max_mcs_ul(uint8_t mcs_ul) +void bts_set_max_mcs_ul(struct gprs_rlcmac_bts* bts, uint8_t mcs_ul) { - m_max_mcs_ul = mcs_ul; + bts->max_mcs_ul = mcs_ul; } -bool BTS::cs_dl_is_supported(CodingScheme cs) +bool bts_cs_dl_is_supported(const struct gprs_rlcmac_bts* bts, CodingScheme cs) { OSMO_ASSERT(mcs_is_valid(cs)); uint8_t num = mcs_chan_code(cs); if (mcs_is_gprs(cs)) { - return (max_cs_dl() >= num) && (m_bts.cs_mask & (1U << num)); + return (bts_max_cs_dl(bts) >= num) && (bts->cs_mask & (1U << num)); } else { - return (max_mcs_dl() >= num) && (m_bts.mcs_mask & (1U << num)); + return (bts_max_mcs_dl(bts) >= num) && (bts->mcs_mask & (1U << num)); } } -GprsMs *BTS::ms_alloc(uint8_t ms_class, uint8_t egprs_ms_class) +GprsMs *bts_alloc_ms(struct gprs_rlcmac_bts* bts, uint8_t ms_class, uint8_t egprs_ms_class) { GprsMs *ms; - ms = ms_store().create_ms(); + ms = bts_ms_store(bts)->create_ms(); - ms_set_timeout(ms, osmo_tdef_get(pcu->T_defs, -2030, OSMO_TDEF_S, -1)); + ms_set_timeout(ms, osmo_tdef_get(bts->pcu->T_defs, -2030, OSMO_TDEF_S, -1)); ms_set_ms_class(ms, ms_class); ms_set_egprs_ms_class(ms, egprs_ms_class); @@ -1078,23 +1068,38 @@ GprsMs *BTS::ms_alloc(uint8_t ms_class, uint8_t egprs_ms_class) } -static int bts_talloc_destructor(struct BTS* bts) +static int bts_talloc_destructor(struct gprs_rlcmac_bts* bts) { - bts->~BTS(); + bts_cleanup(bts); return 0; } -struct BTS* bts_alloc(struct gprs_pcu *pcu) +struct gprs_rlcmac_bts* bts_alloc(struct gprs_pcu *pcu) { - struct BTS* bts; - bts = talloc(pcu, struct BTS); + struct gprs_rlcmac_bts* bts; + bts = talloc_zero(pcu, struct gprs_rlcmac_bts); if (!bts) return bts; talloc_set_destructor(bts, bts_talloc_destructor); - new (bts) BTS(pcu); + bts_init(bts, pcu); return bts; } +struct SBAController *bts_sba(struct gprs_rlcmac_bts *bts) +{ + return bts->sba; +} + +struct GprsMsStorage *bts_ms_store(struct gprs_rlcmac_bts *bts) +{ + return bts->ms_store; +} + +struct GprsMs *bts_ms_by_tlli(struct gprs_rlcmac_bts *bts, uint32_t tlli, uint32_t old_tlli) +{ + return bts_ms_store(bts)->get_ms(tlli, old_tlli); +} + /* update TA based on TA provided by PH-DATA-IND */ void update_tbf_ta(struct gprs_rlcmac_ul_tbf *tbf, int8_t ta_delta) { @@ -1136,7 +1141,7 @@ void set_tbf_ta(struct gprs_rlcmac_ul_tbf *tbf, uint8_t ta) void bts_update_tbf_ta(const char *p, uint32_t fn, uint8_t trx_no, uint8_t ts, int8_t ta, bool is_rach) { struct gprs_rlcmac_ul_tbf *tbf = - bts_main_data()->bts->ul_tbf_by_poll_fn(fn, trx_no, ts); + bts_ul_tbf_by_poll_fn(the_pcu->bts, fn, trx_no, ts); if (!tbf) LOGP(DL1IF, LOGL_DEBUG, "[%s] update TA = %u ignored due to " "unknown UL TBF on TRX = %d, TS = %d, FN = %d\n", @@ -1182,7 +1187,7 @@ void bts_recalc_initial_cs(struct gprs_rlcmac_bts *bts) return; } - max_cs_dl = bts->bts->max_cs_dl(); + max_cs_dl = bts_max_cs_dl(bts); if (bts->pcuif_info_ind.initial_cs > max_cs_dl) { LOGP(DL1IF, LOGL_DEBUG, " downgrading initial_cs_dl to %d\n", max_cs_dl); bts->initial_cs_dl = max_cs_dl; @@ -1192,7 +1197,7 @@ void bts_recalc_initial_cs(struct gprs_rlcmac_bts *bts) if (bts->initial_cs_dl == 0) bts->initial_cs_dl = 1; /* CS1 Must always be supported */ - max_cs_ul = bts->bts->max_cs_ul(); + max_cs_ul = bts_max_cs_ul(bts); if (bts->pcuif_info_ind.initial_cs > max_cs_ul) { LOGP(DL1IF, LOGL_DEBUG, " downgrading initial_cs_ul to %d\n", max_cs_ul); bts->initial_cs_ul = max_cs_ul; @@ -1212,14 +1217,14 @@ void bts_recalc_initial_mcs(struct gprs_rlcmac_bts *bts) return; } - max_mcs_dl = bts->bts->max_mcs_dl(); + max_mcs_dl = bts_max_mcs_dl(bts); if (bts->pcuif_info_ind.initial_mcs > max_mcs_dl) { LOGP(DL1IF, LOGL_DEBUG, " downgrading initial_mcs_dl to %d\n", max_mcs_dl); bts->initial_mcs_dl = max_mcs_dl; } else { bts->initial_mcs_dl = bts->pcuif_info_ind.initial_mcs; } - max_mcs_ul = bts->bts->max_mcs_ul(); + max_mcs_ul = bts_max_mcs_ul(bts); if (bts->pcuif_info_ind.initial_mcs > max_mcs_ul) { LOGP(DL1IF, LOGL_DEBUG, " downgrading initial_mcs_ul to %d\n", max_mcs_ul); bts->initial_mcs_ul = max_mcs_ul; @@ -1232,7 +1237,7 @@ void bts_recalc_max_cs(struct gprs_rlcmac_bts *bts) { int i; uint8_t cs_dl, cs_ul; - struct gprs_pcu *pcu = bts->bts->pcu; + struct gprs_pcu *pcu = bts->pcu; cs_dl = 0; for (i = pcu->vty.max_cs_dl - 1; i >= 0; i--) { @@ -1251,15 +1256,15 @@ void bts_recalc_max_cs(struct gprs_rlcmac_bts *bts) } LOGP(DRLCMAC, LOGL_DEBUG, "New max CS: DL=%u UL=%u\n", cs_dl, cs_ul); - bts->bts->set_max_cs_dl(cs_dl); - bts->bts->set_max_cs_ul(cs_ul); + bts_set_max_cs_dl(bts, cs_dl); + bts_set_max_cs_ul(bts, cs_ul); } void bts_recalc_max_mcs(struct gprs_rlcmac_bts *bts) { int i; uint8_t mcs_dl, mcs_ul; - struct gprs_pcu *pcu = bts->bts->pcu; + struct gprs_pcu *pcu = bts->pcu; mcs_dl = 0; for (i = pcu->vty.max_mcs_dl - 1; i >= 0; i--) { @@ -1278,37 +1283,11 @@ void bts_recalc_max_mcs(struct gprs_rlcmac_bts *bts) } LOGP(DRLCMAC, LOGL_DEBUG, "New max MCS: DL=%u UL=%u\n", mcs_dl, mcs_ul); - bts->bts->set_max_mcs_dl(mcs_dl); - bts->bts->set_max_mcs_ul(mcs_ul); -} - - -struct gprs_rlcmac_bts *bts_data(struct BTS *bts) -{ - return &bts->m_bts; -} - -struct GprsMs *bts_ms_by_imsi(struct BTS *bts, const char *imsi) -{ - return bts->ms_by_imsi(imsi); -} - -uint8_t bts_max_cs_dl(const struct BTS *bts) -{ - return bts->max_cs_dl(); -} - -uint8_t bts_max_cs_ul(const struct BTS *bts) -{ - return bts->max_cs_ul(); -} - -uint8_t bts_max_mcs_dl(const struct BTS *bts) -{ - return bts->max_mcs_dl(); + bts_set_max_mcs_dl(bts, mcs_dl); + bts_set_max_mcs_ul(bts, mcs_ul); } -uint8_t bts_max_mcs_ul(const struct BTS *bts) +struct GprsMs *bts_ms_by_imsi(struct gprs_rlcmac_bts *bts, const char *imsi) { - return bts->max_mcs_ul(); + return bts_ms_store(bts)->get_ms(0, 0, imsi); } @@ -20,11 +20,13 @@ #pragma once +#include <pdch.h> +#include <stdint.h> +#include <stdbool.h> #ifdef __cplusplus extern "C" { #endif - #include <osmocom/core/linuxlist.h> #include <osmocom/core/rate_ctr.h> #include <osmocom/core/stat_item.h> @@ -40,21 +42,11 @@ extern "C" { } #endif -#ifdef __cplusplus -#include "poll_controller.h" -#include "sba.h" #include "tbf.h" -#include "gprs_ms_storage.h" #include "coding_scheme.h" -#include <cxx_linuxlist.h> -#endif - -#include <pdch.h> -#include <stdint.h> -#include <stdbool.h> -struct BTS; struct GprsMs; +struct gprs_rlcmac_bts; struct gprs_rlcmac_trx { void *fl1h; @@ -62,11 +54,12 @@ struct gprs_rlcmac_trx { struct gprs_rlcmac_pdch pdch[8]; /* back pointers */ - struct BTS *bts; + struct gprs_rlcmac_bts *bts; uint8_t trx_no; }; + #ifdef __cplusplus extern "C" { #endif @@ -78,48 +71,7 @@ void bts_update_tbf_ta(const char *p, uint32_t fn, uint8_t trx_no, uint8_t ts, i } #endif -/** - * This is the data from C. As soon as our minimal compiler is gcc 4.7 - * we can start to compile pcu_vty.c with c++ and remove the split. - */ -struct gprs_rlcmac_bts { - bool active; - uint8_t bsic; - uint8_t cs_mask; /* Allowed CS mask from BTS */ - uint16_t mcs_mask; /* Allowed MCS mask from BTS */ - struct { /* information stored from last received PCUIF info_ind message */ - uint8_t initial_cs; - uint8_t initial_mcs; - } pcuif_info_ind; - uint8_t initial_cs_dl, initial_cs_ul; - uint8_t initial_mcs_dl, initial_mcs_ul; - /* Timer defintions */ - struct osmo_tdef *T_defs_bts; /* timers controlled by BTS, received through PCUIF */ - uint8_t n3101; - uint8_t n3103; - uint8_t n3105; - struct gprs_rlcmac_trx trx[8]; - - uint8_t si13[GSM_MACBLOCK_LEN]; - bool si13_is_set; - - /* State for dynamic algorithm selection */ - int multislot_disabled; - - /** - * Point back to the C++ object. This is used during the transition - * period. - */ - struct BTS *bts; - - /* Packet Application Information (3GPP TS 44.060 11.2.47, usually ETWS primary message). We don't need to store - * more than one message, because they get sent so rarely. */ - struct msgb *app_info; - uint32_t app_info_pending; /* Count of MS with active TBF, to which we did not send app_info yet */ - /* main nsei */ - struct gprs_ns2_nse *nse; -}; enum { CTR_TBF_DL_ALLOCATED, @@ -230,189 +182,159 @@ struct chan_req_params { bool single_block; }; -#ifdef __cplusplus +struct PollController; +struct SBAController; +struct GprsMsStorage; +struct pcu_l1_meas; + /** * I represent a GSM BTS. I have one or more TRX, I know the current * GSM time and I have controllers that help with allocating resources * on my TRXs. */ -struct BTS { -public: - BTS(struct gprs_pcu *pcu); - ~BTS(); - void cleanup(); - - static BTS* main_bts(); - - struct gprs_rlcmac_bts *bts_data(); - SBAController *sba(); - - /** TODO: change the number to unsigned */ - void set_current_frame_number(int frame_number); - void set_current_block_frame_number(int frame_number, unsigned max_delay); - int current_frame_number() const; - - /** add paging to paging queue(s) */ - int add_paging(uint8_t chan_needed, const struct osmo_mobile_identity *mi); - - gprs_rlcmac_dl_tbf *dl_tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts); - gprs_rlcmac_ul_tbf *ul_tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts); - gprs_rlcmac_dl_tbf *dl_tbf_by_tfi(uint8_t tfi, uint8_t trx, uint8_t ts); - gprs_rlcmac_ul_tbf *ul_tbf_by_tfi(uint8_t tfi, uint8_t trx, uint8_t ts); - - int tfi_find_free(enum gprs_rlcmac_tbf_direction dir, uint8_t *_trx, int8_t use_trx) const; - - int rcv_imm_ass_cnf(const uint8_t *data, uint32_t fn); - - uint32_t rfn_to_fn(int32_t rfn); - int rcv_rach(const struct rach_ind_params *rip); - int rcv_ptcch_rach(const struct rach_ind_params *rip); - - void snd_dl_ass(gprs_rlcmac_tbf *tbf, bool poll, uint16_t pgroup); - - uint8_t max_cs_dl(void) const; - uint8_t max_cs_ul(void) const; - uint8_t max_mcs_dl(void) const; - uint8_t max_mcs_ul(void) const; - void set_max_cs_dl(uint8_t cs_dl); - void set_max_cs_ul(uint8_t cs_ul); - void set_max_mcs_dl(uint8_t mcs_dl); - void set_max_mcs_ul(uint8_t mcs_ul); - bool cs_dl_is_supported(CodingScheme cs); - - GprsMsStorage &ms_store(); - GprsMs *ms_by_tlli(uint32_t tlli, uint32_t old_tlli = GSM_RESERVED_TMSI); - GprsMs *ms_by_imsi(const char *imsi); - GprsMs *ms_alloc(uint8_t ms_class, uint8_t egprs_ms_class = 0); - - void send_gsmtap(enum pcu_gsmtap_category categ, bool uplink, uint8_t trx_no, - uint8_t ts_no, uint8_t channel, uint32_t fn, - const uint8_t *data, unsigned int len); - void send_gsmtap_meas(enum pcu_gsmtap_category categ, bool uplink, uint8_t trx_no, - uint8_t ts_no, uint8_t channel, uint32_t fn, - const uint8_t *data, unsigned int len, struct pcu_l1_meas *meas); - void send_gsmtap_rach(enum pcu_gsmtap_category categ, uint8_t channel, - const struct rach_ind_params *rip); - - /* - * Below for C interface for the VTY - */ - struct rate_ctr_group *rate_counters() const; - struct osmo_stat_item_group *stat_items() const; - void do_rate_ctr_inc(unsigned int ctr_id); - void do_rate_ctr_add(unsigned int ctr_id, int inc); - void stat_item_add(unsigned int stat_id, int inc); - - LListHead<gprs_rlcmac_tbf>& ul_tbfs(); - LListHead<gprs_rlcmac_tbf>& dl_tbfs(); - - struct gprs_rlcmac_bts m_bts; +struct gprs_rlcmac_bts { + bool active; + uint8_t bsic; + uint8_t cs_mask; /* Allowed CS mask from BTS */ + uint16_t mcs_mask; /* Allowed MCS mask from BTS */ + struct { /* information stored from last received PCUIF info_ind message */ + uint8_t initial_cs; + uint8_t initial_mcs; + } pcuif_info_ind; + uint8_t initial_cs_dl, initial_cs_ul; + uint8_t initial_mcs_dl, initial_mcs_ul; + /* Timer defintions */ + struct osmo_tdef *T_defs_bts; /* timers controlled by BTS, received through PCUIF */ + uint8_t n3101; + uint8_t n3103; + uint8_t n3105; + struct gprs_rlcmac_trx trx[8]; + + uint8_t si13[GSM_MACBLOCK_LEN]; + bool si13_is_set; + + /* State for dynamic algorithm selection */ + int multislot_disabled; + + /* Packet Application Information (3GPP TS 44.060 11.2.47, usually ETWS primary message). We don't need to store + * more than one message, because they get sent so rarely. */ + struct msgb *app_info; + uint32_t app_info_pending; /* Count of MS with active TBF, to which we did not send app_info yet */ + + /* main nsei */ + struct gprs_ns2_nse *nse; /* back pointer to PCU object */ struct gprs_pcu *pcu; -private: - int m_cur_fn; - int m_cur_blk_fn; - uint8_t m_max_cs_dl, m_max_cs_ul; - uint8_t m_max_mcs_dl, m_max_mcs_ul; - PollController m_pollController; - SBAController m_sba; - struct rate_ctr_group *m_ratectrs; - struct osmo_stat_item_group *m_statg; + int cur_fn; + int cur_blk_fn; + uint8_t max_cs_dl, max_cs_ul; + uint8_t max_mcs_dl, max_mcs_ul; + struct PollController *pollController; + struct SBAController *sba; + struct rate_ctr_group *ratectrs; + struct osmo_stat_item_group *statg; - GprsMsStorage m_ms_store; + struct GprsMsStorage *ms_store; /* list of uplink TBFs */ - LListHead<gprs_rlcmac_tbf> m_ul_tbfs; + struct llist_head ul_tbfs; /* list of gprs_rlcmac_tbf */ /* list of downlink TBFs */ - LListHead<gprs_rlcmac_tbf> m_dl_tbfs; - - /* disable copying to avoid slicing */ - BTS(const BTS&); - BTS& operator=(const BTS&); + struct llist_head dl_tbfs; /* list of gprs_rlcmac_tbf */ }; -inline int BTS::current_frame_number() const -{ - return m_cur_fn; -} +#ifdef __cplusplus +extern "C" { +#endif -inline SBAController *BTS::sba() -{ - return &m_sba; -} +struct GprsMs *bts_alloc_ms(struct gprs_rlcmac_bts *bts, uint8_t ms_class, uint8_t egprs_ms_class); +int bts_add_paging(struct gprs_rlcmac_bts *bts, uint8_t chan_needed, const struct osmo_mobile_identity *mi); -inline GprsMsStorage &BTS::ms_store() -{ - return m_ms_store; -} +uint32_t bts_rfn_to_fn(const struct gprs_rlcmac_bts *bts, int32_t rfn); -inline GprsMs *BTS::ms_by_tlli(uint32_t tlli, uint32_t old_tlli) -{ - return ms_store().get_ms(tlli, old_tlli); -} +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); +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); +struct gprs_rlcmac_dl_tbf *bts_dl_tbf_by_tfi(struct gprs_rlcmac_bts *bts, uint8_t tfi, uint8_t trx, uint8_t ts); +struct gprs_rlcmac_ul_tbf *bts_ul_tbf_by_tfi(struct gprs_rlcmac_bts *bts, uint8_t tfi, uint8_t trx, uint8_t ts); -inline GprsMs *BTS::ms_by_imsi(const char *imsi) -{ - return ms_store().get_ms(0, 0, imsi); -} +void bts_snd_dl_ass(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *tbf, bool poll, uint16_t pgroup); -inline LListHead<gprs_rlcmac_tbf>& BTS::ul_tbfs() +/** TODO: change the number to unsigned */ +void bts_set_current_frame_number(struct gprs_rlcmac_bts *bts, int frame_number); +void bts_set_current_block_frame_number(struct gprs_rlcmac_bts *bts, int frame_number, unsigned max_delay); +static inline int bts_current_frame_number(const struct gprs_rlcmac_bts *bts) { - return m_ul_tbfs; + return bts->cur_fn; } -inline LListHead<gprs_rlcmac_tbf>& BTS::dl_tbfs() -{ - return m_dl_tbfs; -} +int bts_tfi_find_free(const struct gprs_rlcmac_bts *bts, enum gprs_rlcmac_tbf_direction dir, + uint8_t *_trx, int8_t use_trx); + +int bts_rcv_rach(struct gprs_rlcmac_bts *bts, const struct rach_ind_params *rip); +int bts_rcv_ptcch_rach(struct gprs_rlcmac_bts *bts, const struct rach_ind_params *rip); +int bts_rcv_imm_ass_cnf(struct gprs_rlcmac_bts *bts, const uint8_t *data, uint32_t fn); + +void bts_send_gsmtap(struct gprs_rlcmac_bts *bts, + enum pcu_gsmtap_category categ, bool uplink, uint8_t trx_no, + uint8_t ts_no, uint8_t channel, uint32_t fn, + const uint8_t *data, unsigned int len); +void bts_send_gsmtap_meas(struct gprs_rlcmac_bts *bts, + enum pcu_gsmtap_category categ, bool uplink, uint8_t trx_no, + uint8_t ts_no, uint8_t channel, uint32_t fn, + const uint8_t *data, unsigned int len, struct pcu_l1_meas *meas); +void bts_send_gsmtap_rach(struct gprs_rlcmac_bts *bts, + enum pcu_gsmtap_category categ, uint8_t channel, + const struct rach_ind_params *rip); + +struct SBAController *bts_sba(struct gprs_rlcmac_bts *bts); + +struct GprsMsStorage *bts_ms_store(struct gprs_rlcmac_bts *bts); + +struct GprsMs *bts_ms_by_tlli(struct gprs_rlcmac_bts *bts, uint32_t tlli, uint32_t old_tlli); -inline struct rate_ctr_group *BTS::rate_counters() const +static inline struct rate_ctr_group *bts_rate_counters(struct gprs_rlcmac_bts *bts) { - return m_ratectrs; + return bts->ratectrs; } -inline struct osmo_stat_item_group *BTS::stat_items() const +static inline struct osmo_stat_item_group *bts_stat_items(struct gprs_rlcmac_bts *bts) { - return m_statg; + return bts->statg; } -inline void BTS::do_rate_ctr_inc(unsigned int ctr_id) { - rate_ctr_inc(&m_ratectrs->ctr[ctr_id]); +static inline void bts_do_rate_ctr_inc(struct gprs_rlcmac_bts *bts, unsigned int ctr_id) { + rate_ctr_inc(&bts->ratectrs->ctr[ctr_id]); } -inline void BTS::do_rate_ctr_add(unsigned int ctr_id, int inc) { - rate_ctr_add(&m_ratectrs->ctr[ctr_id], inc); +static inline void bts_do_rate_ctr_add(struct gprs_rlcmac_bts *bts, unsigned int ctr_id, int inc) { + rate_ctr_add(&bts->ratectrs->ctr[ctr_id], inc); } -inline void BTS::stat_item_add(unsigned int stat_id, int inc) { - int32_t val = osmo_stat_item_get_last(m_statg->items[stat_id]); - osmo_stat_item_set(m_statg->items[stat_id], val + inc); +static inline void bts_stat_item_add(struct gprs_rlcmac_bts *bts, unsigned int stat_id, int inc) { + int32_t val = osmo_stat_item_get_last(bts->statg->items[stat_id]); + osmo_stat_item_set(bts->statg->items[stat_id], val + inc); } -struct gprs_pcu; -struct BTS* bts_alloc(struct gprs_pcu *pcu); -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void bts_cleanup(); - struct gprs_rlcmac_bts *bts_data(struct BTS *bts); - struct gprs_rlcmac_bts *bts_main_data(); - struct rate_ctr_group *bts_main_data_stats(); - struct osmo_stat_item_group *bts_main_data_stat_items(); - void bts_recalc_initial_cs(struct gprs_rlcmac_bts *bts); - void bts_recalc_initial_mcs(struct gprs_rlcmac_bts *bts); - void bts_recalc_max_cs(struct gprs_rlcmac_bts *bts); - void bts_recalc_max_mcs(struct gprs_rlcmac_bts *bts); - struct GprsMs *bts_ms_by_imsi(struct BTS *bts, const char *imsi); - uint8_t bts_max_cs_dl(const struct BTS *bts); - uint8_t bts_max_cs_ul(const struct BTS *bts); - uint8_t bts_max_mcs_dl(const struct BTS *bts); - uint8_t bts_max_mcs_ul(const struct BTS *bts); +struct gprs_rlcmac_bts *bts_alloc(struct gprs_pcu *pcu); + +struct gprs_rlcmac_bts *bts_main_data(); +struct rate_ctr_group *bts_main_data_stats(); +struct osmo_stat_item_group *bts_main_data_stat_items(); +void bts_recalc_initial_cs(struct gprs_rlcmac_bts *bts); +void bts_recalc_initial_mcs(struct gprs_rlcmac_bts *bts); +void bts_recalc_max_cs(struct gprs_rlcmac_bts *bts); +void bts_recalc_max_mcs(struct gprs_rlcmac_bts *bts); +struct GprsMs *bts_ms_by_imsi(struct gprs_rlcmac_bts *bts, const char *imsi); +uint8_t bts_max_cs_dl(const struct gprs_rlcmac_bts *bts); +uint8_t bts_max_cs_ul(const struct gprs_rlcmac_bts *bts); +uint8_t bts_max_mcs_dl(const struct gprs_rlcmac_bts *bts); +uint8_t bts_max_mcs_ul(const struct gprs_rlcmac_bts *bts); +void bts_set_max_cs_dl(struct gprs_rlcmac_bts *bts, uint8_t cs_dl); +void bts_set_max_cs_ul(struct gprs_rlcmac_bts *bts, uint8_t cs_ul); +void bts_set_max_mcs_dl(struct gprs_rlcmac_bts *bts, uint8_t mcs_dl); +void bts_set_max_mcs_ul(struct gprs_rlcmac_bts *bts, uint8_t mcs_ul); +bool bts_cs_dl_is_supported(const struct gprs_rlcmac_bts *bts, enum CodingScheme cs); #ifdef __cplusplus } - #endif diff --git a/src/encoding.cpp b/src/encoding.cpp index e7b1fb41..f605ca2f 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -24,6 +24,7 @@ #include <bts.h> #include <tbf.h> #include <tbf_ul.h> +#include <tbf_dl.h> #include <gprs_debug.h> #include <egprs_rlc_compression.h> diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp index 1596d67c..92fa8452 100644 --- a/src/gprs_bssgp_pcu.cpp +++ b/src/gprs_bssgp_pcu.cpp @@ -34,6 +34,7 @@ extern "C" { #include <osmocom/core/utils.h> #include <osmocom/gsm/gsm48.h> #include "coding_scheme.h" + #include "tbf_dl.h" } /* Tuning parameters for BSSGP flow control */ @@ -208,7 +209,7 @@ static int gprs_bssgp_pcu_rx_paging_cs(struct msgb *msg, const struct tlv_parsed if ((rc = get_paging_mi(&mi, tp)) > 0) return bssgp_tx_status((enum gprs_bssgp_cause) rc, NULL, msg); - return BTS::main_bts()->add_paging(tlvp_val8(tp, BSSGP_IE_CHAN_NEEDED, 0), &mi); + return bts_add_paging(the_pcu->bts, tlvp_val8(tp, BSSGP_IE_CHAN_NEEDED, 0), &mi); } static int gprs_bssgp_pcu_rx_paging_ps(struct msgb *msg, const struct tlv_parsed *tp) @@ -761,8 +762,8 @@ static enum CodingScheme max_coding_scheme_dl(struct gprs_rlcmac_bts *bts) } else { /* We found "num" for free in the loop above */ } - } else if (bts->bts->max_mcs_dl()) { - num = bts->bts->max_mcs_dl(); + } else if (bts_max_mcs_dl(bts)) { + num = bts_max_mcs_dl(bts); } else { num = 9; } @@ -782,8 +783,8 @@ static enum CodingScheme max_coding_scheme_dl(struct gprs_rlcmac_bts *bts) } } } - } else if (bts->bts->max_cs_dl()) { - num = bts->bts->max_cs_dl(); + } else if (bts_max_cs_dl(bts)) { + num = bts_max_cs_dl(bts); } if (!num) diff --git a/src/gprs_ms.c b/src/gprs_ms.c index 9d303d6f..ea497a3c 100644 --- a/src/gprs_ms.c +++ b/src/gprs_ms.c @@ -91,7 +91,7 @@ void ms_timeout(void *data) } static int ms_talloc_destructor(struct GprsMs *ms); -struct GprsMs *ms_alloc(struct BTS *bts, uint32_t tlli) +struct GprsMs *ms_alloc(struct gprs_rlcmac_bts *bts, uint32_t tlli) { struct GprsMs *ms = talloc_zero(tall_pcu_ctx, struct GprsMs); @@ -249,13 +249,13 @@ void ms_set_mode(struct GprsMs *ms, enum mcs_kind mode) case GPRS: if (!mcs_is_gprs(ms->current_cs_ul)) { ms->current_cs_ul = mcs_get_gprs_by_num( - bts_data(ms->bts)->initial_cs_ul); + ms->bts->initial_cs_ul); if (!mcs_is_valid(ms->current_cs_ul)) ms->current_cs_ul = CS1; } if (!mcs_is_gprs(ms->current_cs_dl)) { ms->current_cs_dl = mcs_get_gprs_by_num( - bts_data(ms->bts)->initial_cs_dl); + ms->bts->initial_cs_dl); if (!mcs_is_valid(ms->current_cs_dl)) ms->current_cs_dl = CS1; } @@ -265,13 +265,13 @@ void ms_set_mode(struct GprsMs *ms, enum mcs_kind mode) case EGPRS: if (!mcs_is_edge(ms->current_cs_ul)) { ms->current_cs_ul = mcs_get_egprs_by_num( - bts_data(ms->bts)->initial_mcs_ul); + ms->bts->initial_mcs_ul); if (!mcs_is_valid(ms->current_cs_ul)) ms->current_cs_ul = MCS1; } if (!mcs_is_edge(ms->current_cs_dl)) { ms->current_cs_dl = mcs_get_egprs_by_num( - bts_data(ms->bts)->initial_mcs_dl); + ms->bts->initial_mcs_dl); if (!mcs_is_valid(ms->current_cs_dl)) ms->current_cs_dl = MCS1; } diff --git a/src/gprs_ms.h b/src/gprs_ms.h index 6391f726..12809f10 100644 --- a/src/gprs_ms.h +++ b/src/gprs_ms.h @@ -49,7 +49,7 @@ enum ms_counter_id { MS_CTR_DL_CTRL_MSG_SCHED, }; -struct BTS; +struct gprs_rlcmac_bts; struct gprs_rlcmac_trx; struct GprsMs; @@ -63,7 +63,7 @@ struct GprsMs { struct gpr_ms_callback cb; bool app_info_pending; - struct BTS *bts; + struct gprs_rlcmac_bts *bts; struct gprs_rlcmac_ul_tbf *ul_tbf; struct gprs_rlcmac_dl_tbf *dl_tbf; struct llist_head old_tbfs; /* list of gprs_rlcmac_tbf */ @@ -102,7 +102,7 @@ struct GprsMs { struct rate_ctr_group *ctrs; }; -struct GprsMs *ms_alloc(struct BTS *bts, uint32_t tlli); +struct GprsMs *ms_alloc(struct gprs_rlcmac_bts *bts, uint32_t tlli); int ms_first_common_ts(const struct GprsMs *ms); void ms_set_reserved_slots(struct GprsMs *ms, struct gprs_rlcmac_trx *trx, diff --git a/src/gprs_ms_storage.cpp b/src/gprs_ms_storage.cpp index 6d5b09ec..6245ed9f 100644 --- a/src/gprs_ms_storage.cpp +++ b/src/gprs_ms_storage.cpp @@ -35,7 +35,7 @@ static void ms_storage_ms_idle_cb(struct GprsMs *ms) { llist_del(&ms->list); if (ms->bts) - ms->bts->stat_item_add(STAT_MS_PRESENT, -1); + bts_stat_item_add(ms->bts, STAT_MS_PRESENT, -1); if (ms_is_idle(ms)) talloc_free(ms); } @@ -50,7 +50,7 @@ static struct gpr_ms_callback ms_storage_ms_cb = { .ms_active = ms_storage_ms_active_cb, }; -GprsMsStorage::GprsMsStorage(BTS *bts) : +GprsMsStorage::GprsMsStorage(struct gprs_rlcmac_bts *bts) : m_bts(bts) { INIT_LLIST_HEAD(&m_list); @@ -109,7 +109,7 @@ GprsMs *GprsMsStorage::create_ms() ms_set_callback(ms, &ms_storage_ms_cb); llist_add(&ms->list, &m_list); if (m_bts) - m_bts->stat_item_add(STAT_MS_PRESENT, 1); + bts_stat_item_add(m_bts, STAT_MS_PRESENT, 1); return ms; } diff --git a/src/gprs_ms_storage.h b/src/gprs_ms_storage.h index af496887..dcb6d8df 100644 --- a/src/gprs_ms_storage.h +++ b/src/gprs_ms_storage.h @@ -25,11 +25,11 @@ #include <stdint.h> #include <stddef.h> -struct BTS; +struct gprs_rlcmac_bts; -class GprsMsStorage { +struct GprsMsStorage { public: - GprsMsStorage(BTS *bts); + GprsMsStorage(struct gprs_rlcmac_bts *bts); ~GprsMsStorage(); void cleanup(); @@ -39,6 +39,6 @@ public: const struct llist_head* ms_list() const {return &m_list;} private: - BTS *m_bts; + struct gprs_rlcmac_bts *m_bts; struct llist_head m_list; /* list of struct GprsMs */ }; diff --git a/src/gprs_pcu.c b/src/gprs_pcu.c index bc9b350a..b2806524 100644 --- a/src/gprs_pcu.c +++ b/src/gprs_pcu.c @@ -109,8 +109,7 @@ void gprs_pcu_set_initial_cs(struct gprs_pcu *pcu, uint8_t cs_dl, uint8_t cs_ul) the_pcu->vty.initial_cs_ul = cs_ul; /*TODO: once we support multiple bts, foreach(bts) apply */ - struct gprs_rlcmac_bts *bts = bts_data(pcu->bts); - bts_recalc_initial_cs(bts); + bts_recalc_initial_cs(pcu->bts); } void gprs_pcu_set_initial_mcs(struct gprs_pcu *pcu, uint8_t mcs_dl, uint8_t mcs_ul) { @@ -118,8 +117,7 @@ void gprs_pcu_set_initial_mcs(struct gprs_pcu *pcu, uint8_t mcs_dl, uint8_t mcs_ the_pcu->vty.initial_mcs_ul = mcs_ul; /*TODO: once we support multiple bts, foreach(bts) apply */ - struct gprs_rlcmac_bts *bts = bts_data(pcu->bts); - bts_recalc_initial_mcs(bts); + bts_recalc_initial_mcs(pcu->bts); } void gprs_pcu_set_max_cs(struct gprs_pcu *pcu, uint8_t cs_dl, uint8_t cs_ul) @@ -127,14 +125,12 @@ void gprs_pcu_set_max_cs(struct gprs_pcu *pcu, uint8_t cs_dl, uint8_t cs_ul) the_pcu->vty.max_cs_dl = cs_dl; the_pcu->vty.max_cs_ul = cs_ul; /*TODO: once we support multiple bts, foreach(bts) apply */ - struct gprs_rlcmac_bts *bts = bts_data(pcu->bts); - bts_recalc_max_cs(bts); + bts_recalc_max_cs(pcu->bts); } void gprs_pcu_set_max_mcs(struct gprs_pcu *pcu, uint8_t mcs_dl, uint8_t mcs_ul) { the_pcu->vty.max_mcs_dl = mcs_dl; the_pcu->vty.max_mcs_ul = mcs_ul; /* TODO: once we support multiple bts, foreach(bts) apply */ - struct gprs_rlcmac_bts *bts = bts_data(pcu->bts); - bts_recalc_max_mcs(bts); + bts_recalc_max_mcs(pcu->bts); } diff --git a/src/gprs_pcu.h b/src/gprs_pcu.h index 89130010..37f6e07f 100644 --- a/src/gprs_pcu.h +++ b/src/gprs_pcu.h @@ -55,7 +55,6 @@ enum pcu_gsmtap_category { PCU_GSMTAP_C_UL_PTCCH = 21, /* uplink PTCCH bursts */ }; -struct BTS; struct gprs_rlcmac_bts; struct GprsMs; struct gprs_rlcmac_tbf; @@ -108,7 +107,7 @@ struct gprs_pcu { struct gsmtap_inst *gsmtap; uint32_t gsmtap_categ_mask; - struct BTS *bts; + struct gprs_rlcmac_bts *bts; struct gprs_ns2_inst *nsi; diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp index b5709c92..39e22c0f 100644 --- a/src/gprs_rlcmac_sched.cpp +++ b/src/gprs_rlcmac_sched.cpp @@ -41,13 +41,13 @@ struct tbf_sched_candidates { struct gprs_rlcmac_ul_tbf *ul_ack; }; -static uint32_t sched_poll(BTS *bts, +static uint32_t sched_poll(struct gprs_rlcmac_bts *bts, uint8_t trx, uint8_t ts, uint32_t fn, uint8_t block_nr, struct tbf_sched_candidates *tbf_cand) { struct gprs_rlcmac_ul_tbf *ul_tbf; struct gprs_rlcmac_dl_tbf *dl_tbf; - LListHead<gprs_rlcmac_tbf> *pos; + struct llist_item *pos; uint32_t poll_fn; /* check special TBF for events */ @@ -55,8 +55,8 @@ static uint32_t sched_poll(BTS *bts, if ((block_nr % 3) == 2) poll_fn ++; poll_fn = poll_fn % GSM_MAX_FN; - llist_for_each(pos, &bts->ul_tbfs()) { - ul_tbf = as_ul_tbf(pos->entry()); + llist_for_each_entry(pos, &bts->ul_tbfs, list) { + ul_tbf = as_ul_tbf((struct gprs_rlcmac_tbf *)pos->entry); OSMO_ASSERT(ul_tbf); /* this trx, this ts */ if (ul_tbf->trx->trx_no != trx || !ul_tbf->is_control_ts(ts)) @@ -74,8 +74,8 @@ static uint32_t sched_poll(BTS *bts, /* FIXME: Is this supposed to be fair? The last TBF for each wins? Maybe use llist_add_tail and skip once we have all states? */ } - llist_for_each(pos, &bts->dl_tbfs()) { - dl_tbf = as_dl_tbf(pos->entry()); + llist_for_each_entry(pos, &bts->dl_tbfs, list) { + dl_tbf = as_dl_tbf((struct gprs_rlcmac_tbf *)pos->entry); OSMO_ASSERT(dl_tbf); /* this trx, this ts */ if (dl_tbf->trx->trx_no != trx || !dl_tbf->is_control_ts(ts)) @@ -136,7 +136,7 @@ struct msgb *sched_app_info(struct gprs_rlcmac_tbf *tbf) { if (!tbf || !tbf->ms()->app_info_pending) return NULL; - bts_data = BTS::main_bts()->bts_data(); + bts_data = the_pcu->bts; if (bts_data->app_info) { LOGP(DRLCMACSCHED, LOGL_DEBUG, "Sending Packet Application Information message\n"); @@ -367,7 +367,7 @@ static struct msgb *sched_dummy(void) return msg; } -static inline void tap_n_acc(const struct msgb *msg, const struct gprs_rlcmac_bts *bts, uint8_t trx, uint8_t ts, +static inline void tap_n_acc(const struct msgb *msg, struct gprs_rlcmac_bts *bts, uint8_t trx, uint8_t ts, uint32_t fn, enum pcu_gsmtap_category cat) { if (!msg) @@ -375,19 +375,19 @@ static inline void tap_n_acc(const struct msgb *msg, const struct gprs_rlcmac_bt switch(cat) { case PCU_GSMTAP_C_DL_CTRL: - bts->bts->do_rate_ctr_inc(CTR_RLC_SENT_CONTROL); - bts->bts->send_gsmtap(PCU_GSMTAP_C_DL_CTRL, false, trx, ts, GSMTAP_CHANNEL_PACCH, fn, msg->data, + bts_do_rate_ctr_inc(bts, CTR_RLC_SENT_CONTROL); + bts_send_gsmtap(bts, PCU_GSMTAP_C_DL_CTRL, false, trx, ts, GSMTAP_CHANNEL_PACCH, fn, msg->data, msg->len); break; case PCU_GSMTAP_C_DL_DATA_GPRS: case PCU_GSMTAP_C_DL_DATA_EGPRS: - bts->bts->do_rate_ctr_inc(CTR_RLC_SENT); - bts->bts->send_gsmtap(cat, false, trx, ts, GSMTAP_CHANNEL_PDTCH, fn, msg->data, + bts_do_rate_ctr_inc(bts, CTR_RLC_SENT); + bts_send_gsmtap(bts, cat, false, trx, ts, GSMTAP_CHANNEL_PDTCH, fn, msg->data, msg->len); break; case PCU_GSMTAP_C_DL_DUMMY: - bts->bts->do_rate_ctr_inc(CTR_RLC_SENT_DUMMY); - bts->bts->send_gsmtap(PCU_GSMTAP_C_DL_DUMMY, false, trx, ts, GSMTAP_CHANNEL_PACCH, fn, msg->data, + bts_do_rate_ctr_inc(bts, CTR_RLC_SENT_DUMMY); + bts_send_gsmtap(bts, PCU_GSMTAP_C_DL_DUMMY, false, trx, ts, GSMTAP_CHANNEL_PACCH, fn, msg->data, msg->len); break; default: @@ -438,7 +438,7 @@ int gprs_rlcmac_rcv_rts_block(struct gprs_rlcmac_bts *bts, req_mcs_kind = EGPRS; /* all kinds are fine */ } - poll_fn = sched_poll(bts->bts, trx, ts, fn, block_nr, &tbf_cand); + poll_fn = sched_poll(bts, trx, ts, fn, block_nr, &tbf_cand); /* check uplink resource for polling */ if (tbf_cand.poll) { LOGP(DRLCMACSCHED, LOGL_DEBUG, "Received RTS for PDCH: TRX=%d " @@ -447,7 +447,7 @@ int gprs_rlcmac_rcv_rts_block(struct gprs_rlcmac_bts *bts, block_nr, poll_fn, tbf_name(tbf_cand.poll)); usf = USF_UNUSED; /* else. check for sba */ - } else if ((sba_fn = bts->bts->sba()->sched(trx, ts, fn, block_nr)) != 0xffffffff) { +} else if ((sba_fn = bts_sba(bts)->sched(trx, ts, fn, block_nr)) != 0xffffffff) { LOGP(DRLCMACSCHED, LOGL_DEBUG, "Received RTS for PDCH: TRX=%d " "TS=%d FN=%d block_nr=%d scheduling free USF for " "single block allocation at FN=%d\n", trx, ts, fn, @@ -493,7 +493,7 @@ int gprs_rlcmac_rcv_rts_block(struct gprs_rlcmac_bts *bts, } /* msg is now available */ - bts->bts->do_rate_ctr_add(CTR_RLC_DL_BYTES, msg->data_len); + bts_do_rate_ctr_add(bts, CTR_RLC_DL_BYTES, msg->data_len); /* set USF */ OSMO_ASSERT(msgb_length(msg) > 0); diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index 7c2e8284..f8b1c1fb 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -305,7 +305,7 @@ static bool idle_pdch_avail(const struct gprs_rlcmac_bts *bts_data) * \param[out] trx_no_ TRX number on which TFI was found * \returns negative error code or 0 on success */ -static int tfi_find_free(const BTS *bts, const gprs_rlcmac_trx *trx, const GprsMs *ms, +static int tfi_find_free(const struct gprs_rlcmac_bts *bts, const gprs_rlcmac_trx *trx, const GprsMs *ms, enum gprs_rlcmac_tbf_direction dir, int8_t use_trx, uint8_t *trx_no_) { int tfi; @@ -323,7 +323,7 @@ static int tfi_find_free(const BTS *bts, const gprs_rlcmac_trx *trx, const GprsM if (use_trx == -1 && ms_current_trx(ms)) use_trx = ms_current_trx(ms)->trx_no; - tfi = bts->tfi_find_free(dir, &trx_no, use_trx); + tfi = bts_tfi_find_free(bts, dir, &trx_no, use_trx); if (tfi < 0) return -EBUSY; @@ -423,7 +423,7 @@ int alloc_algorithm_a(struct gprs_rlcmac_bts *bts, GprsMs *ms_, struct gprs_rlcm ms_set_reserved_slots(ms_, trx, 1 << ts, 1 << ts); tbf_->upgrade_to_multislot = 0; - bts->bts->do_rate_ctr_inc(CTR_TBF_ALLOC_ALGO_A); + bts_do_rate_ctr_inc(bts, CTR_TBF_ALLOC_ALGO_A); return 0; } @@ -888,7 +888,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, GprsMs *ms_, struct gprs_rlcm trx = ms_current_trx(ms); /* Step 2a: Find usable TRX and TFI */ - tfi = tfi_find_free(bts->bts, trx, ms, tbf->direction, use_trx, &trx_no); + tfi = tfi_find_free(bts, trx, ms, tbf->direction, use_trx, &trx_no); if (tfi < 0) { LOGPAL(tbf, "B", single, use_trx, LOGL_NOTICE, "failed to allocate a TFI\n"); return tfi; @@ -966,7 +966,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, GprsMs *ms_, struct gprs_rlcm else assign_ul_tbf_slots(as_ul_tbf(tbf_), trx, ul_slots, tfi, usf); - bts->bts->do_rate_ctr_inc(CTR_TBF_ALLOC_ALGO_B); + bts_do_rate_ctr_inc(bts, CTR_TBF_ALLOC_ALGO_B); return 0; } diff --git a/src/gsm_timer.cpp b/src/gsm_timer.cpp index cefe520f..0627753c 100644 --- a/src/gsm_timer.cpp +++ b/src/gsm_timer.cpp @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - + /* These store the amount of frame number that we wait until next timer expires. */ static int nearest; static int *nearest_p; @@ -45,7 +45,7 @@ static struct rb_root timer_root = RB_ROOT; */ int get_current_fn() { - return BTS::main_bts()->current_frame_number(); + return bts_current_frame_number(the_pcu->bts); } static void __add_gsm_timer(struct osmo_gsm_timer_list *timer) @@ -232,4 +232,3 @@ int osmo_gsm_timers_check(void) } /*! }@ */ - diff --git a/src/llc.cpp b/src/llc.cpp index 51cb15a6..470e1545 100644 --- a/src/llc.cpp +++ b/src/llc.cpp @@ -122,13 +122,13 @@ void gprs_llc_queue::enqueue(struct msgb *llc_msg, const struct timespec *expire msgb_enqueue(&m_queue, llc_msg); } -void llc_queue_clear(struct gprs_llc_queue *q, struct BTS *bts) +void llc_queue_clear(struct gprs_llc_queue *q, struct gprs_rlcmac_bts *bts) { struct msgb *msg; while ((msg = msgb_dequeue(&q->m_queue))) { if (bts) - bts->do_rate_ctr_inc(CTR_LLC_FRAME_DROPPED); + bts_do_rate_ctr_inc(bts, CTR_LLC_FRAME_DROPPED); msgb_free(msg); } @@ -221,7 +221,7 @@ struct msgb *gprs_llc_queue::dequeue(const MetaInfo **info) return msg; } -void gprs_llc_queue::calc_pdu_lifetime(BTS *bts, const uint16_t pdu_delay_csec, struct timespec *tv) +void gprs_llc_queue::calc_pdu_lifetime(struct gprs_rlcmac_bts *bts, const uint16_t pdu_delay_csec, struct timespec *tv) { uint16_t delay_csec; if (bts->pcu->vty.force_llc_lifetime) @@ -32,7 +32,7 @@ extern "C" { #define LLC_MAX_LEN 1543 -struct BTS; +struct gprs_rlcmac_bts; /** * I represent the LLC data to a MS @@ -65,7 +65,7 @@ struct MetaInfo { */ struct gprs_llc_queue { #ifdef __cplusplus - static void calc_pdu_lifetime(BTS *bts, const uint16_t pdu_delay_csec, + static void calc_pdu_lifetime(struct gprs_rlcmac_bts *bts, const uint16_t pdu_delay_csec, struct timespec *tv); static bool is_frame_expired(const struct timespec *now, const struct timespec *tv); @@ -84,7 +84,7 @@ struct gprs_llc_queue { extern "C" { #endif void llc_queue_init(struct gprs_llc_queue *q); -void llc_queue_clear(struct gprs_llc_queue *q, struct BTS *bts); +void llc_queue_clear(struct gprs_llc_queue *q, struct gprs_rlcmac_bts *bts); void llc_queue_move_and_merge(struct gprs_llc_queue *q, struct gprs_llc_queue *o); static inline uint16_t llc_chunk_size(const struct gprs_llc *llc) diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp index a11ec7eb..1a47b379 100644 --- a/src/pcu_l1_if.cpp +++ b/src/pcu_l1_if.cpp @@ -53,6 +53,7 @@ extern "C" { #include <pdch.h> #include <tbf_ul.h> #include <tbf_dl.h> +#include <gprs_ms_storage.h> // FIXME: move this, when changed from c++ to c. extern "C" { @@ -271,13 +272,13 @@ void pcu_l1if_tx_pch(bitvec * block, int plen, uint16_t pgroup) extern "C" void pcu_rx_block_time(uint16_t arfcn, uint32_t fn, uint8_t ts_no) { - BTS::main_bts()->set_current_block_frame_number(fn, 0); + bts_set_current_block_frame_number(the_pcu->bts,fn, 0); } extern "C" void pcu_rx_ra_time(uint16_t arfcn, uint32_t fn, uint8_t ts_no) { /* access bursts may arrive some bursts earlier */ - BTS::main_bts()->set_current_block_frame_number(fn, 5); + bts_set_current_block_frame_number(the_pcu->bts,fn, 5); } extern "C" int pcu_rx_data_ind_pdtch(uint8_t trx_no, uint8_t ts_no, uint8_t *data, @@ -368,7 +369,7 @@ static int pcu_rx_data_cnf(struct gsm_pcu_if_data *data_cnf) switch (data_cnf->sapi) { case PCU_IF_SAPI_PCH: if (data_cnf->data[2] == 0x3f) - BTS::main_bts()->rcv_imm_ass_cnf(data_cnf->data, data_cnf->fn); + bts_rcv_imm_ass_cnf(the_pcu->bts, data_cnf->data, data_cnf->fn); break; default: LOGP(DL1IF, LOGL_ERROR, "Received PCU data confirm with " @@ -447,7 +448,7 @@ extern "C" int pcu_rx_rach_ind_ptcch(uint8_t trx_nr, uint8_t ts_nr, uint32_t fn, .qta = qta, }; - return BTS::main_bts()->rcv_ptcch_rach(&rip); + return bts_rcv_ptcch_rach(the_pcu->bts, &rip); } static int pcu_rx_rach_ind(const struct gsm_pcu_if_rach_ind *rach_ind) @@ -471,10 +472,10 @@ static int pcu_rx_rach_ind(const struct gsm_pcu_if_rach_ind *rach_ind) switch (rach_ind->sapi) { case PCU_IF_SAPI_RACH: - rc = BTS::main_bts()->rcv_rach(&rip); + rc = bts_rcv_rach(the_pcu->bts, &rip); break; case PCU_IF_SAPI_PTCCH: - rc = BTS::main_bts()->rcv_ptcch_rach(&rip); + rc = bts_rcv_ptcch_rach(the_pcu->bts, &rip); break; default: LOGP(DL1IF, LOGL_ERROR, "Received PCU rach request with " @@ -751,7 +752,7 @@ static int pcu_rx_time_ind(struct gsm_pcu_if_time_ind *time_ind) LOGP(DL1IF, LOGL_DEBUG, "Time indication received: %d\n", time_ind->fn % 52); - BTS::main_bts()->set_current_frame_number(time_ind->fn); + bts_set_current_frame_number(the_pcu->bts, time_ind->fn); return 0; } @@ -776,12 +777,12 @@ static int pcu_rx_pag_req(struct gsm_pcu_if_pag_req *pag_req) return -EINVAL; } - return BTS::main_bts()->add_paging(pag_req->chan_needed, &mi); + return bts_add_paging(the_pcu->bts, pag_req->chan_needed, &mi); } static int pcu_rx_susp_req(struct gsm_pcu_if_susp_req *susp_req) { - BTS *bts = BTS::main_bts(); + struct gprs_rlcmac_bts *bts = the_pcu->bts; struct bssgp_bvc_ctx *bctx = gprs_bssgp_pcu_current_bctx(); GprsMs *ms; struct gprs_rlcmac_dl_tbf *dl_tbf; @@ -793,7 +794,7 @@ static int pcu_rx_susp_req(struct gsm_pcu_if_susp_req *susp_req) LOGP(DL1IF, LOGL_INFO, "GPRS Suspend request received: TLLI=0x%08x RAI=%s\n", susp_req->tlli, osmo_rai_name(&ra_id)); - if ((ms = bts->ms_store().get_ms(susp_req->tlli))) { + if ((ms = bts_ms_store(bts)->get_ms(susp_req->tlli))) { /* We need to catch both pointers here since MS may become freed after first tbf_free(dl_tbf) if only DL TBF was available */ dl_tbf = ms_dl_tbf(ms); @@ -812,15 +813,15 @@ static int pcu_rx_susp_req(struct gsm_pcu_if_susp_req *susp_req) static int pcu_rx_app_info_req(struct gsm_pcu_if_app_info_req *app_info_req) { - BTS *bts = BTS::main_bts(); - struct gprs_rlcmac_bts *bts_data = bts->bts_data(); + struct gprs_rlcmac_bts *bts = the_pcu->bts; + struct gprs_rlcmac_bts *bts_data = bts; struct llist_head *tmp; LOGP(DL1IF, LOGL_DEBUG, "Application Information Request received: type=0x%08x len=%i\n", app_info_req->application_type, app_info_req->len); bts_data->app_info_pending = 0; - llist_for_each(tmp, bts->ms_store().ms_list()) { + llist_for_each(tmp, bts_ms_store(bts)->ms_list()) { GprsMs *ms = llist_entry(tmp, typeof(*ms), list); if (!ms_dl_tbf(ms)) continue; diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp index e953d431..8bb7c1fe 100644 --- a/src/pcu_main.cpp +++ b/src/pcu_main.cpp @@ -342,7 +342,7 @@ int main(int argc, char *argv[]) pcu_l1if_close(); - bts_cleanup(); + TALLOC_FREE(the_pcu); talloc_report_full(tall_pcu_ctx, stderr); talloc_free(tall_pcu_ctx); diff --git a/src/pcu_vty_functions.cpp b/src/pcu_vty_functions.cpp index 0276b3e3..0e9cc00a 100644 --- a/src/pcu_vty_functions.cpp +++ b/src/pcu_vty_functions.cpp @@ -101,21 +101,23 @@ static void tbf_print_vty_info(struct vty *vty, gprs_rlcmac_tbf *tbf) vty_out(vty, "%s%s", VTY_NEWLINE, VTY_NEWLINE); } -int pcu_vty_show_tbf_all(struct vty *vty, struct gprs_rlcmac_bts *bts_data, uint32_t flags) +int pcu_vty_show_tbf_all(struct vty *vty, struct gprs_rlcmac_bts *bts, uint32_t flags) { - BTS *bts = bts_data->bts; - LListHead<gprs_rlcmac_tbf> *iter; + struct llist_item *iter; + struct gprs_rlcmac_tbf *tbf; vty_out(vty, "UL TBFs%s", VTY_NEWLINE); - llist_for_each(iter, &bts->ul_tbfs()) { - if (iter->entry()->state_flags & flags) - tbf_print_vty_info(vty, iter->entry()); + llist_for_each_entry(iter, &bts->ul_tbfs, list) { + tbf = (struct gprs_rlcmac_tbf *)iter->entry; + if (tbf->state_flags & flags) + tbf_print_vty_info(vty, tbf); } vty_out(vty, "%sDL TBFs%s", VTY_NEWLINE, VTY_NEWLINE); - llist_for_each(iter, &bts->dl_tbfs()) { - if (iter->entry()->state_flags & flags) - tbf_print_vty_info(vty, iter->entry()); + llist_for_each_entry(iter, &bts->dl_tbfs, list) { + tbf = (struct gprs_rlcmac_tbf *)iter->entry; + if (tbf->state_flags & flags) + tbf_print_vty_info(vty, tbf); } return CMD_SUCCESS; @@ -204,12 +206,11 @@ static int show_ms(struct vty *vty, GprsMs *ms) return CMD_SUCCESS; } -int pcu_vty_show_ms_all(struct vty *vty, struct gprs_rlcmac_bts *bts_data) +int pcu_vty_show_ms_all(struct vty *vty, struct gprs_rlcmac_bts *bts) { - BTS *bts = bts_data->bts; struct llist_head *tmp; - llist_for_each(tmp, bts->ms_store().ms_list()) { + llist_for_each(tmp, bts_ms_store(bts)->ms_list()) { GprsMs *ms_iter = llist_entry(tmp, typeof(*ms_iter), list); show_ms(vty, ms_iter); } @@ -217,11 +218,10 @@ int pcu_vty_show_ms_all(struct vty *vty, struct gprs_rlcmac_bts *bts_data) return CMD_SUCCESS; } -int pcu_vty_show_ms_by_tlli(struct vty *vty, struct gprs_rlcmac_bts *bts_data, +int pcu_vty_show_ms_by_tlli(struct vty *vty, struct gprs_rlcmac_bts *bts, uint32_t tlli) { - BTS *bts = bts_data->bts; - GprsMs *ms = bts->ms_store().get_ms(tlli); + GprsMs *ms = bts_ms_store(bts)->get_ms(tlli); if (!ms) { vty_out(vty, "Unknown TLLI %08x.%s", tlli, VTY_NEWLINE); return CMD_WARNING; @@ -230,11 +230,10 @@ int pcu_vty_show_ms_by_tlli(struct vty *vty, struct gprs_rlcmac_bts *bts_data, return show_ms(vty, ms); } -int pcu_vty_show_ms_by_imsi(struct vty *vty, struct gprs_rlcmac_bts *bts_data, +int pcu_vty_show_ms_by_imsi(struct vty *vty, struct gprs_rlcmac_bts *bts, const char *imsi) { - BTS *bts = bts_data->bts; - GprsMs *ms = bts->ms_store().get_ms(0, 0, imsi); + GprsMs *ms = bts_ms_store(bts)->get_ms(0, 0, imsi); if (!ms) { vty_out(vty, "Unknown IMSI '%s'.%s", imsi, VTY_NEWLINE); return CMD_WARNING; diff --git a/src/pdch.cpp b/src/pdch.cpp index 49cce8d3..49f0b854 100644 --- a/src/pdch.cpp +++ b/src/pdch.cpp @@ -113,9 +113,9 @@ static void get_meas(struct pcu_l1_meas *meas, } } -static inline void sched_ul_ass_or_rej(BTS *bts, gprs_rlcmac_bts *bts_data, struct gprs_rlcmac_dl_tbf *tbf) +static inline void sched_ul_ass_or_rej(struct gprs_rlcmac_bts *bts, gprs_rlcmac_bts *bts_data, struct gprs_rlcmac_dl_tbf *tbf) { - bts->do_rate_ctr_inc(CTR_CHANNEL_REQUEST_DESCRIPTION); + bts_do_rate_ctr_inc(bts, CTR_CHANNEL_REQUEST_DESCRIPTION); /* This call will register the new TBF with the MS on success */ gprs_rlcmac_ul_tbf *ul_tbf = tbf_alloc_ul(bts_data, tbf->ms(), tbf->trx->trx_no, tbf->tlli()); @@ -158,7 +158,7 @@ void gprs_rlcmac_pdch::free_resources() while ((pag = dequeue_paging())) talloc_free(pag); - trx->bts->sba()->free_resources(this); + bts_sba(trx->bts)->free_resources(this); } struct gprs_rlcmac_paging *gprs_rlcmac_pdch::dequeue_paging() @@ -292,12 +292,12 @@ void gprs_rlcmac_pdch::rcv_control_ack(Packet_Control_Acknowledgement_t *packet, { struct gprs_rlcmac_tbf *tbf, *new_tbf; uint32_t tlli = packet->TLLI; - GprsMs *ms = bts()->ms_by_tlli(tlli); + GprsMs *ms = bts_ms_by_tlli(bts(), tlli, GSM_RESERVED_TMSI); gprs_rlcmac_ul_tbf *ul_tbf; - tbf = bts()->ul_tbf_by_poll_fn(fn, trx_no(), ts_no); + tbf = bts_ul_tbf_by_poll_fn(bts(), fn, trx_no(), ts_no); if (!tbf) - tbf = bts()->dl_tbf_by_poll_fn(fn, trx_no(), ts_no); + tbf = bts_dl_tbf_by_poll_fn(bts(), fn, trx_no(), ts_no); if (!tbf) { LOGP(DRLCMAC, LOGL_NOTICE, "PACKET CONTROL ACK with " @@ -410,7 +410,7 @@ void gprs_rlcmac_pdch::rcv_control_dl_ack_nack(Packet_Downlink_Ack_Nack_t *ack_n char show_bits[RLC_GPRS_WS + 1]; tfi = ack_nack->DOWNLINK_TFI; - tbf = bts()->dl_tbf_by_poll_fn(fn, trx_no(), ts_no); + tbf = bts_dl_tbf_by_poll_fn(bts(), fn, trx_no(), ts_no); if (!tbf) { LOGP(DRLCMAC, LOGL_NOTICE, "PACKET DOWNLINK ACK with " "unknown FN=%u TFI=%d (TRX %d TS %d)\n", @@ -477,7 +477,7 @@ void gprs_rlcmac_pdch::rcv_control_egprs_dl_ack_nack(EGPRS_PD_AckNack_t *ack_nac int bsn_begin, bsn_end; tfi = ack_nack->DOWNLINK_TFI; - tbf = bts()->dl_tbf_by_poll_fn(fn, trx_no(), ts_no); + tbf = bts_dl_tbf_by_poll_fn(bts(), fn, trx_no(), ts_no); if (!tbf) { LOGP(DRLCMAC, LOGL_NOTICE, "EGPRS PACKET DOWNLINK ACK with " "unknown FN=%u TFI=%d (TRX %d TS %d)\n", @@ -566,10 +566,10 @@ void gprs_rlcmac_pdch::rcv_resource_request(Packet_Resource_Request_t *request, uint32_t tlli = request->ID.u.TLLI; bool ms_found = true; - GprsMs *ms = bts()->ms_by_tlli(tlli); + GprsMs *ms = bts_ms_by_tlli(bts(), tlli, GSM_RESERVED_TMSI); if (!ms) { ms_found = false; - ms = bts()->ms_alloc(0, 0); /* ms class updated later */ + ms = bts_alloc_ms(bts(), 0, 0); /* ms class updated later */ ms_set_tlli(ms, tlli); } ul_tbf = ms_ul_tbf(ms); /* hence ul_tbf may be NULL */ @@ -580,10 +580,10 @@ void gprs_rlcmac_pdch::rcv_resource_request(Packet_Resource_Request_t *request, LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF " "in packet resource request of single " "block, so we provide one:\n"); - sba = bts()->sba()->find(this, fn); + sba = bts_sba(bts())->find(this, fn); if (sba) { ms_set_ta(ms, sba->ta); - bts()->sba()->free_sba(sba); + bts_sba(bts())->free_sba(sba); } else if (!ul_tbf || !ul_tbf->state_is(GPRS_RLCMAC_FINISHED)) { LOGPTBFUL(ul_tbf, LOGL_NOTICE, "MS requests UL TBF in PACKET RESOURCE REQ of " @@ -640,7 +640,7 @@ return_unref: if (request->ID.u.Global_TFI.UnionType) { struct gprs_rlcmac_dl_tbf *dl_tbf; int8_t tfi = request->ID.u.Global_TFI.u.DOWNLINK_TFI; - dl_tbf = bts()->dl_tbf_by_tfi(tfi, trx_no(), ts_no); + dl_tbf = bts_dl_tbf_by_tfi(bts(), tfi, trx_no(), ts_no); if (!dl_tbf) { LOGP(DRLCMAC, LOGL_NOTICE, "PACKET RESOURCE REQ unknown downlink TFI=%d\n", tfi); return; @@ -653,7 +653,7 @@ return_unref: } else { struct gprs_rlcmac_ul_tbf *ul_tbf; int8_t tfi = request->ID.u.Global_TFI.u.UPLINK_TFI; - ul_tbf = bts()->ul_tbf_by_tfi(tfi, trx_no(), ts_no); + ul_tbf = bts_ul_tbf_by_tfi(bts(), tfi, trx_no(), ts_no); if (!ul_tbf) { LOGP(DRLCMAC, LOGL_NOTICE, "PACKET RESOURCE REQ unknown uplink TFI=%d\n", tfi); return; @@ -671,16 +671,16 @@ void gprs_rlcmac_pdch::rcv_measurement_report(Packet_Measurement_Report_t *repor struct gprs_rlcmac_sba *sba; GprsMs *ms; - ms = bts()->ms_by_tlli(report->TLLI); + ms = bts_ms_by_tlli(bts(), report->TLLI, GSM_RESERVED_TMSI); if (!ms) { LOGP(DRLCMAC, LOGL_NOTICE, "MS send measurement " "but TLLI 0x%08x is unknown\n", report->TLLI); - ms = bts()->ms_alloc(0, 0); + ms = bts_alloc_ms(bts(), 0, 0); ms_set_tlli(ms, report->TLLI); } - if ((sba = bts()->sba()->find(this, fn))) { + if ((sba = bts_sba(bts())->find(this, fn))) { ms_set_ta(ms, sba->ta); - bts()->sba()->free_sba(sba); + bts_sba(bts())->free_sba(sba); } gprs_rlcmac_meas_rep(ms, report); } @@ -703,9 +703,9 @@ int gprs_rlcmac_pdch::rcv_control_block(const uint8_t *data, uint8_t data_len, rc = decode_gsm_rlcmac_uplink(rlc_block, ul_control_block); if (ul_control_block->u.MESSAGE_TYPE == MT_PACKET_UPLINK_DUMMY_CONTROL_BLOCK) - bts()->send_gsmtap_meas(PCU_GSMTAP_C_UL_DUMMY, true, trx_no(), ts_no, GSMTAP_CHANNEL_PACCH, fn, data, data_len, meas); + bts_send_gsmtap_meas(bts(), PCU_GSMTAP_C_UL_DUMMY, true, trx_no(), ts_no, GSMTAP_CHANNEL_PACCH, fn, data, data_len, meas); else - bts()->send_gsmtap_meas(PCU_GSMTAP_C_UL_CTRL, true, trx_no(), ts_no, GSMTAP_CHANNEL_PACCH, fn, data, data_len, meas); + bts_send_gsmtap_meas(bts(), PCU_GSMTAP_C_UL_CTRL, true, trx_no(), ts_no, GSMTAP_CHANNEL_PACCH, fn, data, data_len, meas); if (rc < 0) { LOGP(DRLCMACUL, LOGL_ERROR, "Dropping Uplink Control Block with invalid " @@ -714,7 +714,7 @@ int gprs_rlcmac_pdch::rcv_control_block(const uint8_t *data, uint8_t data_len, } LOGP(DRLCMAC, LOGL_DEBUG, "------------------------- RX : Uplink Control Block -------------------------\n"); - bts()->do_rate_ctr_inc(CTR_RLC_RECV_CONTROL); + bts_do_rate_ctr_inc(bts(), CTR_RLC_RECV_CONTROL); switch (ul_control_block->u.MESSAGE_TYPE) { case MT_PACKET_CONTROL_ACK: rcv_control_ack(&ul_control_block->u.Packet_Control_Acknowledgement, fn); @@ -735,7 +735,7 @@ int gprs_rlcmac_pdch::rcv_control_block(const uint8_t *data, uint8_t data_len, /* ignoring it. change the SI to not force sending these? */ break; default: - bts()->do_rate_ctr_inc(CTR_DECODE_ERRORS); + bts_do_rate_ctr_inc(bts(), CTR_DECODE_ERRORS); LOGP(DRLCMAC, LOGL_NOTICE, "RX: [PCU <- BTS] unknown control block(%d) received\n", ul_control_block->u.MESSAGE_TYPE); @@ -752,13 +752,13 @@ int gprs_rlcmac_pdch::rcv_block(uint8_t *data, uint8_t len, uint32_t fn, { enum CodingScheme cs = mcs_get_by_size_ul(len); if (!cs) { - bts()->do_rate_ctr_inc(CTR_DECODE_ERRORS); + bts_do_rate_ctr_inc(bts(), CTR_DECODE_ERRORS); LOGP(DRLCMACUL, LOGL_ERROR, "Dropping data block with invalid " "length %d: %s\n", len, osmo_hexdump(data, len)); return -EINVAL; } - bts()->do_rate_ctr_add(CTR_RLC_UL_BYTES, len); + bts_do_rate_ctr_add(bts(), CTR_RLC_UL_BYTES, len); LOGP(DRLCMACUL, LOGL_DEBUG, "Got RLC block, coding scheme: %s, " "length: %d (%d))\n", mcs_name(cs), len, mcs_used_size_ul(cs)); @@ -769,7 +769,7 @@ int gprs_rlcmac_pdch::rcv_block(uint8_t *data, uint8_t len, uint32_t fn, if (mcs_is_edge(cs)) return rcv_data_block(data, len, fn, meas, cs); - bts()->do_rate_ctr_inc(CTR_DECODE_ERRORS); + bts_do_rate_ctr_inc(bts(), CTR_DECODE_ERRORS); LOGP(DRLCMACUL, LOGL_ERROR, "Unsupported coding scheme %s\n", mcs_name(cs)); return -EINVAL; @@ -788,11 +788,11 @@ int gprs_rlcmac_pdch::rcv_data_block(uint8_t *data, uint8_t data_len, uint32_t f * control blocks (see 44.060, section 10.3, 1st par.) */ if (mcs_is_edge(cs)) { - bts()->send_gsmtap_meas(PCU_GSMTAP_C_UL_DATA_EGPRS, true, + bts_send_gsmtap_meas(bts(), PCU_GSMTAP_C_UL_DATA_EGPRS, true, trx_no(), ts_no, GSMTAP_CHANNEL_PDTCH, fn, data, data_len, meas); } else { - bts()->send_gsmtap_meas(PCU_GSMTAP_C_UL_DATA_GPRS, true, + bts_send_gsmtap_meas(bts(), PCU_GSMTAP_C_UL_DATA_GPRS, true, trx_no(), ts_no, GSMTAP_CHANNEL_PDTCH, fn, data, data_len, meas); } @@ -804,7 +804,7 @@ int gprs_rlcmac_pdch::rcv_data_block(uint8_t *data, uint8_t data_len, uint32_t f LOGP(DRLCMACUL, LOGL_ERROR, "Got %s RLC block but header parsing has failed\n", mcs_name(cs)); - bts()->do_rate_ctr_inc(CTR_DECODE_ERRORS); + bts_do_rate_ctr_inc(bts(), CTR_DECODE_ERRORS); return rc; } @@ -974,7 +974,7 @@ void gprs_rlcmac_pdch::unreserve(enum gprs_rlcmac_tbf_direction dir) m_num_reserved[dir] -= 1; } -inline BTS *gprs_rlcmac_pdch::bts() const +inline struct gprs_rlcmac_bts *gprs_rlcmac_pdch::bts() const { return trx->bts; } @@ -986,7 +986,7 @@ uint8_t gprs_rlcmac_pdch::trx_no() const inline gprs_rlcmac_bts *gprs_rlcmac_pdch::bts_data() const { - return trx->bts->bts_data(); + return trx->bts; } /* PTCCH (Packet Timing Advance Control Channel) */ @@ -70,7 +70,7 @@ struct gprs_rlcmac_pdch { struct pcu_l1_meas *meas, enum CodingScheme cs); gprs_rlcmac_bts *bts_data() const; - BTS *bts() const; + struct gprs_rlcmac_bts *bts() const; uint8_t trx_no() const; struct gprs_rlcmac_ul_tbf *ul_tbf_by_tfi(uint8_t tfi); diff --git a/src/poll_controller.cpp b/src/poll_controller.cpp index ac795101..04ec4fd3 100644 --- a/src/poll_controller.cpp +++ b/src/poll_controller.cpp @@ -24,6 +24,7 @@ #include <bts.h> #include <tbf.h> #include <tbf_ul.h> +#include <tbf_dl.h> #include <cxx_linuxlist.h> #include <sba.h> @@ -32,7 +33,7 @@ extern "C" { #include <osmocom/gsm/gsm_utils.h> } -PollController::PollController(BTS& bts) +PollController::PollController(struct gprs_rlcmac_bts& bts) : m_bts(bts) {} @@ -51,26 +52,26 @@ void PollController::expireTimedout(int frame_number, unsigned max_delay) struct gprs_rlcmac_dl_tbf *dl_tbf; struct gprs_rlcmac_ul_tbf *ul_tbf; struct gprs_rlcmac_sba *sba, *sba2; - LListHead<gprs_rlcmac_tbf> *pos; + struct llist_item *pos; - llist_for_each(pos, &m_bts.ul_tbfs()) { - ul_tbf = as_ul_tbf(pos->entry()); + llist_for_each_entry(pos, &m_bts.ul_tbfs, list) { + ul_tbf = as_ul_tbf((struct gprs_rlcmac_tbf *)pos->entry); if (ul_tbf->poll_scheduled()) { if (elapsed_fn_check(max_delay, frame_number, ul_tbf->poll_fn)) ul_tbf->poll_timeout(); } } - llist_for_each(pos, &m_bts.dl_tbfs()) { - dl_tbf = as_dl_tbf(pos->entry()); + llist_for_each_entry(pos, &m_bts.dl_tbfs, list) { + dl_tbf = as_dl_tbf((struct gprs_rlcmac_tbf *)pos->entry); if (dl_tbf->poll_scheduled()) { if (elapsed_fn_check(max_delay, frame_number, dl_tbf->poll_fn)) dl_tbf->poll_timeout(); } } - llist_for_each_entry_safe(sba, sba2, &m_bts.sba()->m_sbas, list) { + llist_for_each_entry_safe(sba, sba2, &bts_sba(&m_bts)->m_sbas, list) { if (elapsed_fn_check(max_delay, frame_number, sba->fn)) { /* sba will be freed here */ - m_bts.sba()->timeout(sba); + bts_sba(&m_bts)->timeout(sba); } } diff --git a/src/poll_controller.h b/src/poll_controller.h index 65d1fee9..8e709a30 100644 --- a/src/poll_controller.h +++ b/src/poll_controller.h @@ -21,22 +21,22 @@ #pragma once -struct BTS; +struct gprs_rlcmac_bts; /** * I belong to a BTS and I am responsible for finding TBFs and * SBAs that should have been polled and execute the timeout * action on them. */ -class PollController { +struct PollController { public: - PollController(BTS& bts); + PollController(struct gprs_rlcmac_bts& bts); /* check for poll timeout */ void expireTimedout(int frame_number, unsigned max_delay); private: - BTS& m_bts; + struct gprs_rlcmac_bts& m_bts; private: /* disable copying to avoid slicing */ diff --git a/src/rlc.cpp b/src/rlc.cpp index 8f56a8e3..a2cc52c2 100644 --- a/src/rlc.cpp +++ b/src/rlc.cpp @@ -127,7 +127,7 @@ static uint16_t bitnum_to_bsn(int bitnum, uint16_t ssn) return (ssn - 1 - bitnum); } -void gprs_rlc_dl_window::update(BTS *bts, const struct bitvec *rbb, +void gprs_rlc_dl_window::update(struct gprs_rlcmac_bts *bts, const struct bitvec *rbb, uint16_t first_bsn, uint16_t *lost, uint16_t *received) { @@ -154,13 +154,13 @@ void gprs_rlc_dl_window::update(BTS *bts, const struct bitvec *rbb, } else { LOGP(DRLCMACDL, LOGL_DEBUG, "- got NACK for BSN=%d\n", bsn); m_v_b.mark_nacked(bsn); - bts->do_rate_ctr_inc(CTR_RLC_NACKED); + bts_do_rate_ctr_inc(bts, CTR_RLC_NACKED); *lost += 1; } } } -void gprs_rlc_dl_window::update(BTS *bts, char *show_rbb, uint16_t ssn, +void gprs_rlc_dl_window::update(struct gprs_rlcmac_bts *bts, char *show_rbb, uint16_t ssn, uint16_t *lost, uint16_t *received) { /* SSN - 1 is in range V(A)..V(S)-1 */ @@ -178,7 +178,7 @@ void gprs_rlc_dl_window::update(BTS *bts, char *show_rbb, uint16_t ssn, } else { LOGP(DRLCMACDL, LOGL_DEBUG, "- got NACK for BSN=%d\n", bsn); m_v_b.mark_nacked(bsn); - bts->do_rate_ctr_inc(CTR_RLC_NACKED); + bts_do_rate_ctr_inc(bts, CTR_RLC_NACKED); *lost += 1; } } @@ -38,7 +38,7 @@ extern "C" { #define RLC_MAX_WS RLC_EGPRS_MAX_WS #define RLC_MAX_LEN 74 /* MCS-9 data unit */ -struct BTS; +struct gprs_rlcmac_bts; /* The state of a BSN in the send/receive window */ enum gprs_rlc_ul_bsn_state { @@ -307,9 +307,9 @@ struct gprs_rlc_dl_window: public gprs_rlc_window { /* Methods to manage reception */ int resend_needed() const; int mark_for_resend(); - void update(BTS *bts, char *show_rbb, uint16_t ssn, + void update(struct gprs_rlcmac_bts *bts, char *show_rbb, uint16_t ssn, uint16_t *lost, uint16_t *received); - void update(BTS *bts, const struct bitvec *rbb, + void update(struct gprs_rlcmac_bts *bts, const struct bitvec *rbb, uint16_t first_bsn, uint16_t *lost, uint16_t *received); int move_window(); diff --git a/src/sba.cpp b/src/sba.cpp index cc58405a..53eb847f 100644 --- a/src/sba.cpp +++ b/src/sba.cpp @@ -40,7 +40,7 @@ extern void *tall_pcu_ctx; * This offset must be a multiple of 13. */ #define AGCH_START_OFFSET 52 -SBAController::SBAController(BTS &bts) +SBAController::SBAController(struct gprs_rlcmac_bts &bts) : m_bts(bts) { INIT_LLIST_HEAD(&m_sbas); @@ -64,7 +64,7 @@ int SBAController::alloc( for (trx = 0; trx < 8; trx++) { for (ts = 7; ts >= 0; ts--) { - pdch = &m_bts.bts_data()->trx[trx].pdch[ts]; + pdch = &m_bts.trx[trx].pdch[ts]; if (!pdch->is_enabled()) continue; break; @@ -86,7 +86,7 @@ int SBAController::alloc( sba->ta = ta; llist_add(&sba->list, &m_sbas); - m_bts.do_rate_ctr_inc(CTR_SBA_ALLOCATED); + bts_do_rate_ctr_inc(&m_bts, CTR_SBA_ALLOCATED); *_trx = trx; *_ts = ts; @@ -132,14 +132,14 @@ int SBAController::timeout(struct gprs_rlcmac_sba *sba) LOGP(DRLCMAC, LOGL_NOTICE, "Poll timeout for SBA (TRX=%u, TS=%u, FN=%u, TA=%u)\n", sba->trx_no, sba->ts_no, sba->fn, sba->ta); - m_bts.do_rate_ctr_inc(CTR_SBA_TIMEDOUT); + bts_do_rate_ctr_inc(&m_bts, CTR_SBA_TIMEDOUT); free_sba(sba); return 0; } void SBAController::free_sba(gprs_rlcmac_sba *sba) { - m_bts.do_rate_ctr_inc(CTR_SBA_FREED); + bts_do_rate_ctr_inc(&m_bts, CTR_SBA_FREED); llist_del(&sba->list); talloc_free(sba); } @@ -26,7 +26,7 @@ extern "C" { #include <osmocom/core/linuxlist.h> } -struct BTS; +struct gprs_rlcmac_bts; struct gprs_rlcmac_pdch; /* @@ -45,10 +45,10 @@ struct gprs_rlcmac_sba { * * TODO: Add a flush method.. */ -class SBAController { +struct SBAController { friend class PollController; public: - SBAController(BTS &bts); + SBAController(struct gprs_rlcmac_bts &bts); int alloc(uint8_t *_trx, uint8_t *_ts, uint32_t *_fn, uint8_t ta); gprs_rlcmac_sba *find(uint8_t trx, uint8_t ts, uint32_t fn); @@ -62,6 +62,6 @@ public: void free_sba(gprs_rlcmac_sba *sba); private: - BTS &m_bts; + struct gprs_rlcmac_bts &m_bts; llist_head m_sbas; }; diff --git a/src/tbf.cpp b/src/tbf.cpp index 43c8cbfd..05f4e2c4 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -124,7 +124,7 @@ gprs_rlcmac_tbf::Meas::Meas() : timespecclear(&rssi_tv); } -gprs_rlcmac_tbf::gprs_rlcmac_tbf(BTS *bts_, GprsMs *ms, gprs_rlcmac_tbf_direction dir) : +gprs_rlcmac_tbf::gprs_rlcmac_tbf(struct gprs_rlcmac_bts *bts_, GprsMs *ms, gprs_rlcmac_tbf_direction dir) : state_flags(0), direction(dir), trx(NULL), @@ -147,7 +147,6 @@ gprs_rlcmac_tbf::gprs_rlcmac_tbf(BTS *bts_, GprsMs *ms, gprs_rlcmac_tbf_directio ul_ass_state(GPRS_RLCMAC_UL_ASS_NONE), ul_ack_state(GPRS_RLCMAC_UL_ACK_NONE), poll_state(GPRS_RLCMAC_POLL_NONE), - m_list(this), m_egprs_enabled(false) { /* The classes of these members do not have proper constructors yet. @@ -160,6 +159,9 @@ gprs_rlcmac_tbf::gprs_rlcmac_tbf(BTS *bts_, GprsMs *ms, gprs_rlcmac_tbf_directio memset(&m_ms_list, 0, sizeof(m_ms_list)); m_ms_list.entry = this; + memset(&m_bts_list, 0, sizeof(m_bts_list)); + m_bts_list.entry = this; + m_rlc.init(); m_llc.init(); @@ -168,7 +170,7 @@ gprs_rlcmac_tbf::gprs_rlcmac_tbf(BTS *bts_, GprsMs *ms, gprs_rlcmac_tbf_directio gprs_rlcmac_bts *gprs_rlcmac_tbf::bts_data() const { - return bts->bts_data(); + return bts; } uint32_t gprs_rlcmac_tbf::tlli() const @@ -245,7 +247,7 @@ void gprs_rlcmac_tbf::update_ms(uint32_t tlli, enum gprs_rlcmac_tbf_direction di if (!ms_check_tlli(ms(), tlli)) { GprsMs *old_ms; - old_ms = bts->ms_store().get_ms(tlli, 0, NULL); + old_ms = bts_ms_store(bts)->get_ms(tlli, 0, NULL); if (old_ms) ms_merge_and_clear_ms(ms(), old_ms); } @@ -274,9 +276,9 @@ void tbf_free(struct gprs_rlcmac_tbf *tbf) /* update counters */ if (tbf->direction == GPRS_RLCMAC_UL_TBF) { gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(tbf); - tbf->bts->do_rate_ctr_inc(CTR_TBF_UL_FREED); + bts_do_rate_ctr_inc(tbf->bts, CTR_TBF_UL_FREED); if (tbf->state_is(GPRS_RLCMAC_FLOW)) - tbf->bts->do_rate_ctr_inc(CTR_TBF_UL_ABORTED); + bts_do_rate_ctr_inc(tbf->bts, CTR_TBF_UL_ABORTED); rate_ctr_group_free(ul_tbf->m_ul_egprs_ctrs); rate_ctr_group_free(ul_tbf->m_ul_gprs_ctrs); } else { @@ -286,9 +288,9 @@ void tbf_free(struct gprs_rlcmac_tbf *tbf) } else { rate_ctr_group_free(dl_tbf->m_dl_gprs_ctrs); } - tbf->bts->do_rate_ctr_inc(CTR_TBF_DL_FREED); + bts_do_rate_ctr_inc(tbf->bts, CTR_TBF_DL_FREED); if (tbf->state_is(GPRS_RLCMAC_FLOW)) - tbf->bts->do_rate_ctr_inc(CTR_TBF_DL_ABORTED); + bts_do_rate_ctr_inc(tbf->bts, CTR_TBF_DL_ABORTED); } /* Give final measurement report */ @@ -304,7 +306,7 @@ void tbf_free(struct gprs_rlcmac_tbf *tbf) tbf->stop_timers("freeing TBF"); /* TODO: Could/Should generate bssgp_tx_llc_discarded */ tbf_unlink_pdch(tbf); - llist_del(&tbf->list()); + llist_del(tbf_bts_list(tbf)); if (tbf->ms()) tbf->set_ms(NULL); @@ -326,7 +328,7 @@ uint16_t egprs_window_size(const struct gprs_rlcmac_bts *bts_data, uint8_t slots int gprs_rlcmac_tbf::update() { - struct gprs_rlcmac_bts *bts_data = bts->bts_data(); + struct gprs_rlcmac_bts *bts_data = bts; int rc; if (direction != GPRS_RLCMAC_DL_TBF) @@ -399,13 +401,13 @@ bool gprs_rlcmac_tbf::n_inc(enum tbf_counters n) switch(n) { case N3101: - chk = bts->bts_data()->n3101; + chk = bts->n3101; break; case N3103: - chk = bts->bts_data()->n3103; + chk = bts->n3103; break; case N3105: - chk = bts->bts_data()->n3105; + chk = bts->n3105; break; default: LOGPTBF(this, LOGL_ERROR, "unhandled counter %s\n", @@ -492,7 +494,7 @@ void gprs_rlcmac_tbf::t_start(enum tbf_timers t, int T, const char *reason, bool int microsec; struct osmo_tdef *tdef; - if (!(tdef = osmo_tdef_get_entry(bts->bts_data()->T_defs_bts, T))) + if (!(tdef = osmo_tdef_get_entry(bts->T_defs_bts, T))) tdef = osmo_tdef_get_entry(bts->pcu->T_defs, T); if (t >= T_MAX || !tdef) { @@ -563,7 +565,7 @@ int gprs_rlcmac_tbf::check_polling(uint32_t fn, uint8_t ts, LOGPTBF(this, LOGL_DEBUG, "Polling is already scheduled\n"); return -EBUSY; } - if (bts->sba()->find(trx->trx_no, ts, next_fn(fn, 13))) { + if (bts_sba(bts)->find(trx->trx_no, ts, next_fn(fn, 13))) { LOGPTBF(this, LOGL_DEBUG, "Polling is already scheduled " "for single block allocation at FN %d TS %d ...\n", new_poll_fn, ts); @@ -628,7 +630,7 @@ void gprs_rlcmac_tbf::poll_timeout() gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(this); LOGPTBF(this, LOGL_NOTICE, "poll timeout for FN=%d, TS=%d (curr FN %d)\n", - poll_fn, poll_ts, bts->current_frame_number()); + poll_fn, poll_ts, bts_current_frame_number(bts)); poll_state = GPRS_RLCMAC_POLL_NONE; @@ -644,11 +646,11 @@ void gprs_rlcmac_tbf::poll_timeout() "Timeout for polling PACKET CONTROL ACK for PACKET UPLINK ACK: %s\n", rlcmac_diag().c_str()); } - bts->do_rate_ctr_inc(CTR_RLC_ACK_TIMEDOUT); - bts->do_rate_ctr_inc(CTR_PUAN_POLL_TIMEDOUT); + bts_do_rate_ctr_inc(bts, CTR_RLC_ACK_TIMEDOUT); + bts_do_rate_ctr_inc(bts, CTR_PUAN_POLL_TIMEDOUT); if (state_is(GPRS_RLCMAC_FINISHED)) { if (ul_tbf->n_inc(N3103)) { - bts->do_rate_ctr_inc(CTR_PUAN_POLL_FAILED); + bts_do_rate_ctr_inc(bts, CTR_PUAN_POLL_FAILED); TBF_SET_STATE(ul_tbf, GPRS_RLCMAC_RELEASING); T_START(ul_tbf, T3169, 3169, "MAX N3103 reached", false); return; @@ -665,13 +667,13 @@ void gprs_rlcmac_tbf::poll_timeout() state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS); } ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE; - bts->do_rate_ctr_inc(CTR_RLC_ASS_TIMEDOUT); - bts->do_rate_ctr_inc(CTR_PUA_POLL_TIMEDOUT); + bts_do_rate_ctr_inc(bts, CTR_RLC_ASS_TIMEDOUT); + bts_do_rate_ctr_inc(bts, CTR_PUA_POLL_TIMEDOUT); if (n_inc(N3105)) { TBF_SET_STATE(this, GPRS_RLCMAC_RELEASING); T_START(this, T3195, 3195, "MAX N3105 reached", true); - bts->do_rate_ctr_inc(CTR_RLC_ASS_FAILED); - bts->do_rate_ctr_inc(CTR_PUA_POLL_FAILED); + bts_do_rate_ctr_inc(bts, CTR_RLC_ASS_FAILED); + bts_do_rate_ctr_inc(bts, CTR_PUA_POLL_FAILED); return; } /* reschedule UL assignment */ @@ -684,13 +686,13 @@ void gprs_rlcmac_tbf::poll_timeout() state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS); } dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE; - bts->do_rate_ctr_inc(CTR_RLC_ASS_TIMEDOUT); - bts->do_rate_ctr_inc(CTR_PDA_POLL_TIMEDOUT); + bts_do_rate_ctr_inc(bts, CTR_RLC_ASS_TIMEDOUT); + bts_do_rate_ctr_inc(bts, CTR_PDA_POLL_TIMEDOUT); if (n_inc(N3105)) { TBF_SET_STATE(this, GPRS_RLCMAC_RELEASING); T_START(this, T3195, 3195, "MAX N3105 reached", true); - bts->do_rate_ctr_inc(CTR_RLC_ASS_FAILED); - bts->do_rate_ctr_inc(CTR_PDA_POLL_FAILED); + bts_do_rate_ctr_inc(bts, CTR_RLC_ASS_FAILED); + bts_do_rate_ctr_inc(bts, CTR_PDA_POLL_FAILED); return; } /* reschedule DL assignment */ @@ -706,17 +708,17 @@ void gprs_rlcmac_tbf::poll_timeout() } if (dl_tbf->state_is(GPRS_RLCMAC_RELEASING)) - bts->do_rate_ctr_inc(CTR_RLC_REL_TIMEDOUT); + bts_do_rate_ctr_inc(bts, CTR_RLC_REL_TIMEDOUT); else { - bts->do_rate_ctr_inc(CTR_RLC_ACK_TIMEDOUT); - bts->do_rate_ctr_inc(CTR_PDAN_POLL_TIMEDOUT); + bts_do_rate_ctr_inc(bts, CTR_RLC_ACK_TIMEDOUT); + bts_do_rate_ctr_inc(bts, CTR_PDAN_POLL_TIMEDOUT); } if (dl_tbf->n_inc(N3105)) { TBF_SET_STATE(dl_tbf, GPRS_RLCMAC_RELEASING); T_START(dl_tbf, T3195, 3195, "MAX N3105 reached", true); - bts->do_rate_ctr_inc(CTR_PDAN_POLL_FAILED); - bts->do_rate_ctr_inc(CTR_RLC_ACK_FAILED); + bts_do_rate_ctr_inc(bts, CTR_PDAN_POLL_FAILED); + bts_do_rate_ctr_inc(bts, CTR_RLC_ACK_FAILED); return; } /* resend IMM.ASS on CCCH on timeout */ @@ -727,7 +729,7 @@ void gprs_rlcmac_tbf::poll_timeout() /* send immediate assignment */ if ((pgroup = imsi2paging_group(imsi())) > 999) LOGPTBF(dl_tbf, LOGL_ERROR, "IMSI to paging group failed! (%s)\n", imsi()); - dl_tbf->bts->snd_dl_ass(dl_tbf, false, pgroup); + bts_snd_dl_ass(dl_tbf->bts, dl_tbf, false, pgroup); dl_tbf->m_wait_confirm = 1; } } else @@ -736,7 +738,7 @@ void gprs_rlcmac_tbf::poll_timeout() int gprs_rlcmac_tbf::setup(int8_t use_trx, bool single_slot) { - struct gprs_rlcmac_bts *bts_data = bts->bts_data(); + struct gprs_rlcmac_bts *bts_data = bts; int rc; if (ms_mode(m_ms) != GPRS) @@ -935,7 +937,7 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts) goto free_ret; } LOGP(DTBF, LOGL_DEBUG, "------------------------- TX : Packet Downlink Assignment -------------------------\n"); - bts->do_rate_ctr_inc(CTR_PKT_DL_ASSIGNMENT); + bts_do_rate_ctr_inc(bts, CTR_PKT_DL_ASSIGNMENT); if (poll_ass_dl) { set_polling(new_poll_fn, ts, GPRS_RLCMAC_POLL_DL_ASS); @@ -970,7 +972,7 @@ struct msgb *gprs_rlcmac_tbf::create_packet_access_reject() Encoding::write_packet_access_reject( packet_access_rej, tlli()); - bts->do_rate_ctr_inc(CTR_PKT_ACCESS_REJ); + bts_do_rate_ctr_inc(bts, CTR_PKT_ACCESS_REJ); bitvec_pack(packet_access_rej, msgb_put(msg, GSM_MACBLOCK_LEN)); @@ -1039,7 +1041,7 @@ struct msgb *gprs_rlcmac_tbf::create_ul_ass(uint32_t fn, uint8_t ts) goto free_ret; } LOGP(DTBF, LOGL_DEBUG, "------------------------- TX : Packet Uplink Assignment -------------------------\n"); - bts->do_rate_ctr_inc(CTR_PKT_UL_ASSIGNMENT); + bts_do_rate_ctr_inc(bts, CTR_PKT_UL_ASSIGNMENT); set_polling(new_poll_fn, ts, GPRS_RLCMAC_POLL_UL_ASS); @@ -1076,9 +1078,9 @@ int gprs_rlcmac_tbf::establish_dl_tbf_on_pacch() { struct gprs_rlcmac_dl_tbf *new_tbf = NULL; - bts->do_rate_ctr_inc(CTR_TBF_REUSED); + bts_do_rate_ctr_inc(bts, CTR_TBF_REUSED); - new_tbf = tbf_alloc_dl_tbf(bts->bts_data(), ms(), + new_tbf = tbf_alloc_dl_tbf(bts, ms(), this->trx->trx_no, false); if (!new_tbf) { @@ -1112,11 +1114,11 @@ const char *gprs_rlcmac_tbf::name() const void gprs_rlcmac_tbf::rotate_in_list() { - llist_del(&list()); + llist_del(tbf_bts_list((struct gprs_rlcmac_tbf *)this)); if (direction == GPRS_RLCMAC_UL_TBF) - llist_add(&list(), &bts->ul_tbfs()); + llist_add(tbf_bts_list((struct gprs_rlcmac_tbf *)this), &bts->ul_tbfs); else - llist_add(&list(), &bts->dl_tbfs()); + llist_add(tbf_bts_list((struct gprs_rlcmac_tbf *)this), &bts->dl_tbfs); } uint8_t gprs_rlcmac_tbf::tsc() const @@ -1186,6 +1188,11 @@ struct llist_head *tbf_ms_list(struct gprs_rlcmac_tbf *tbf) return &tbf->m_ms_list.list; } +struct llist_head *tbf_bts_list(struct gprs_rlcmac_tbf *tbf) +{ + return &tbf->m_bts_list.list; +} + struct GprsMs *tbf_ms(struct gprs_rlcmac_tbf *tbf) { return tbf->ms(); @@ -196,6 +196,7 @@ enum gprs_rlcmac_tbf_state tbf_state(const struct gprs_rlcmac_tbf *tbf); enum gprs_rlcmac_tbf_direction tbf_direction(const struct gprs_rlcmac_tbf *tbf); void tbf_set_ms(struct gprs_rlcmac_tbf *tbf, struct GprsMs *ms); struct llist_head *tbf_ms_list(struct gprs_rlcmac_tbf *tbf); +struct llist_head *tbf_bts_list(struct gprs_rlcmac_tbf *tbf); struct GprsMs *tbf_ms(struct gprs_rlcmac_tbf *tbf); bool tbf_timers_pending(struct gprs_rlcmac_tbf *tbf, enum tbf_timers t); void tbf_free(struct gprs_rlcmac_tbf *tbf); @@ -212,7 +213,7 @@ int tbf_assign_control_ts(struct gprs_rlcmac_tbf *tbf); #ifdef __cplusplus struct gprs_rlcmac_tbf { - gprs_rlcmac_tbf(BTS *bts_, GprsMs *ms, gprs_rlcmac_tbf_direction dir); + gprs_rlcmac_tbf(struct gprs_rlcmac_bts *bts_, GprsMs *ms, gprs_rlcmac_tbf_direction dir); virtual ~gprs_rlcmac_tbf() {} static void free_all(struct gprs_rlcmac_trx *trx); @@ -296,9 +297,6 @@ struct gprs_rlcmac_tbf { /* attempt to make things a bit more fair */ void rotate_in_list(); - LListHead<gprs_rlcmac_tbf>& list(); - const LListHead<gprs_rlcmac_tbf>& list() const; - uint32_t state_flags; enum gprs_rlcmac_tbf_direction direction; struct gprs_rlcmac_trx *trx; @@ -335,7 +333,7 @@ struct gprs_rlcmac_tbf { uint8_t upgrade_to_multislot; /* store the BTS this TBF belongs to */ - BTS *bts; + struct gprs_rlcmac_bts *bts; /* * private fields. We can't make it private as it is breaking the @@ -347,6 +345,7 @@ struct gprs_rlcmac_tbf { struct rate_ctr_group *m_ctrs; enum gprs_rlcmac_tbf_state state; struct llist_item m_ms_list; + struct llist_item m_bts_list; protected: gprs_rlcmac_bts *bts_data() const; @@ -364,7 +363,6 @@ private: enum gprs_rlcmac_tbf_ul_ass_state ul_ass_state; enum gprs_rlcmac_tbf_ul_ack_state ul_ack_state; enum gprs_rlcmac_tbf_poll_state poll_state; - LListHead<gprs_rlcmac_tbf> m_list; bool m_egprs_enabled; struct osmo_timer_list Tarr[T_MAX]; uint8_t Narr[N_MAX]; @@ -522,16 +520,6 @@ inline bool gprs_rlcmac_tbf::check_n_clear(uint8_t state_flag) return false; } -inline LListHead<gprs_rlcmac_tbf>& gprs_rlcmac_tbf::list() -{ - return this->m_list; -} - -inline const LListHead<gprs_rlcmac_tbf>& gprs_rlcmac_tbf::list() const -{ - return this->m_list; -} - inline GprsMs *gprs_rlcmac_tbf::ms() const { return m_ms; diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index ab34ea11..962c31da 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -139,7 +139,7 @@ struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts, GprsMs return NULL; talloc_set_destructor(tbf, dl_tbf_dtor); - new (tbf) gprs_rlcmac_dl_tbf(bts->bts, ms); + new (tbf) gprs_rlcmac_dl_tbf(bts, ms); rc = tbf->setup(use_trx, single_slot); /* if no resource */ @@ -169,8 +169,8 @@ struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts, GprsMs } } - llist_add(&tbf->list(), &bts->bts->dl_tbfs()); - tbf->bts->do_rate_ctr_inc(CTR_TBF_DL_ALLOCATED); + llist_add(tbf_bts_list((struct gprs_rlcmac_tbf *)tbf), &bts->dl_tbfs); + bts_do_rate_ctr_inc(tbf->bts, CTR_TBF_DL_ALLOCATED); tbf->m_last_dl_poll_fn = -1; tbf->m_last_dl_drained_fn = -1; @@ -181,7 +181,7 @@ struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts, GprsMs return tbf; } -gprs_rlcmac_dl_tbf::gprs_rlcmac_dl_tbf(BTS *bts_, GprsMs *ms) : +gprs_rlcmac_dl_tbf::gprs_rlcmac_dl_tbf(struct gprs_rlcmac_bts *bts_, GprsMs *ms) : gprs_rlcmac_tbf(bts_, ms, GPRS_RLCMAC_DL_TBF), m_tx_counter(0), m_wait_confirm(0), @@ -289,10 +289,10 @@ int gprs_rlcmac_dl_tbf::handle(struct gprs_rlcmac_bts *bts, GprsMs *ms, *ms_old; /* check for existing TBF */ - ms = bts->bts->ms_store().get_ms(tlli, tlli_old, imsi); + ms = bts_ms_store(bts)->get_ms(tlli, tlli_old, imsi); if (ms && strlen(ms_imsi(ms)) == 0) { - ms_old = bts->bts->ms_store().get_ms(0, 0, imsi); + ms_old = bts_ms_store(bts)->get_ms(0, 0, imsi); if (ms_old && ms_old != ms) { /* The TLLI has changed (RAU), so there are two MS * objects for the same MS */ @@ -317,7 +317,7 @@ int gprs_rlcmac_dl_tbf::handle(struct gprs_rlcmac_bts *bts, } if (!ms) - ms = bts->bts->ms_alloc(ms_class, egprs_ms_class); + ms = bts_alloc_ms(bts, ms_class, egprs_ms_class); ms_set_imsi(ms, imsi); ms_confirm_tlli(ms, tlli); if (!ms_ms_class(ms) && ms_class) { @@ -391,12 +391,12 @@ struct msgb *gprs_rlcmac_dl_tbf::llc_dequeue(bssgp_bvc_ctx *bctx) break; } - bts->do_rate_ctr_inc(CTR_LLC_FRAME_TIMEDOUT); + bts_do_rate_ctr_inc(bts, CTR_LLC_FRAME_TIMEDOUT); drop_frame: frames++; octets += msg->len; msgb_free(msg); - bts->do_rate_ctr_inc(CTR_LLC_FRAME_DROPPED); + bts_do_rate_ctr_inc(bts, CTR_LLC_FRAME_DROPPED); continue; } @@ -463,9 +463,9 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn, * MCS1-4, because USF for GPRS-only MS will be sent */ force_cs = ms_current_cs_dl(m_ms); if (force_cs > MCS4) { - force_cs = bts->cs_dl_is_supported(MCS4) ? MCS4 : - bts->cs_dl_is_supported(MCS3) ? MCS3 : - bts->cs_dl_is_supported(MCS2) ? MCS2 : + force_cs = bts_cs_dl_is_supported(bts, MCS4) ? MCS4 : + bts_cs_dl_is_supported(bts, MCS3) ? MCS3 : + bts_cs_dl_is_supported(bts, MCS2) ? MCS2 : MCS1; LOGPTBFDL(this, LOGL_DEBUG, "Force downgrading DL %s -> %s due to USF for GPRS-only MS\n", @@ -515,7 +515,7 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn, LOGPTBFDL(this, LOGL_DEBUG, "Resending BSN %d\n", bsn); /* re-send block with negative aknowlegement */ m_window.m_v_b.mark_unacked(bsn); - bts->do_rate_ctr_inc(CTR_RLC_RESENT); + bts_do_rate_ctr_inc(bts, CTR_RLC_RESENT); } else if (state_is(GPRS_RLCMAC_FINISHED)) { /* If the TBF is in finished, we already sent all packages at least once. * If any packages could have been sent (because of unacked) it should have @@ -523,7 +523,7 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn, LOGPTBFDL(this, LOGL_DEBUG, "Restarting at BSN %d, because all blocks have been transmitted.\n", m_window.v_a()); - bts->do_rate_ctr_inc(CTR_RLC_RESTARTED); + bts_do_rate_ctr_inc(bts, CTR_RLC_RESTARTED); if (restart_bsn_cycle()) return take_next_bsn(fn, previous_bsn, req_mcs_kind, may_combine); } else if (dl_window_stalled()) { @@ -532,7 +532,7 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn, LOGPTBFDL(this, LOGL_NOTICE, "Restarting at BSN %d, because the window is stalled.\n", m_window.v_a()); - bts->do_rate_ctr_inc(CTR_RLC_STALLED); + bts_do_rate_ctr_inc(bts, CTR_RLC_STALLED); if (restart_bsn_cycle()) return take_next_bsn(fn, previous_bsn, req_mcs_kind, may_combine); } else if (have_data()) { @@ -551,7 +551,7 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn, LOGPTBFDL(this, LOGL_DEBUG, "Restarting at BSN %d, because all blocks have been transmitted (FLOW).\n", m_window.v_a()); - bts->do_rate_ctr_inc(CTR_RLC_RESTARTED); + bts_do_rate_ctr_inc(bts, CTR_RLC_RESTARTED); if (restart_bsn_cycle()) return take_next_bsn(fn, previous_bsn, req_mcs_kind, may_combine); } else { @@ -568,8 +568,8 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn, LOGPTBFDL(this, LOGL_DEBUG, "Nothing else to send, Re-transmit final block!\n"); bsn = m_window.v_s_mod(-1); - bts->do_rate_ctr_inc(CTR_RLC_FINAL_BLOCK_RESENT); - bts->do_rate_ctr_inc(CTR_RLC_RESENT); + bts_do_rate_ctr_inc(bts, CTR_RLC_FINAL_BLOCK_RESENT); + bts_do_rate_ctr_inc(bts, CTR_RLC_RESENT); } *may_combine = num_data_blocks(mcs_header_type(m_rlc.block(bsn)->cs_current_trans)) > 1; @@ -628,7 +628,7 @@ void gprs_rlcmac_dl_tbf::trigger_ass(struct gprs_rlcmac_tbf *old_tbf) /* send immediate assignment */ if ((pgroup = imsi2paging_group(imsi())) > 999) LOGPTBFDL(this, LOGL_ERROR, "IMSI to paging group failed! (%s)\n", imsi()); - bts->snd_dl_ass(this, false, pgroup); + bts_snd_dl_ass(bts, this, false, pgroup); m_wait_confirm = 1; } } @@ -648,7 +648,7 @@ void gprs_rlcmac_dl_tbf::schedule_next_frame() LOGPTBFDL(this, LOGL_DEBUG, "Dequeue next LLC (len=%d)\n", msg->len); m_llc.put_frame(msg->data, msg->len); - bts->do_rate_ctr_inc(CTR_LLC_FRAME_SCHED); + bts_do_rate_ctr_inc(bts, CTR_LLC_FRAME_SCHED); msgb_free(msg); m_last_dl_drained_fn = -1; } @@ -742,14 +742,14 @@ int gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, enum CodingScheme cs) &m_llc, &write_offset, &num_chunks, data, is_final, &payload_written); if (payload_written > 0) - bts->do_rate_ctr_add(CTR_RLC_DL_PAYLOAD_BYTES, payload_written); + bts_do_rate_ctr_add(bts, CTR_RLC_DL_PAYLOAD_BYTES, payload_written); if (ar == Encoding::AR_NEED_MORE_BLOCKS) break; LOGPTBFDL(this, LOGL_DEBUG, "Complete DL frame, len=%d\n", llc_frame_length(&m_llc)); gprs_rlcmac_dl_bw(this, llc_frame_length(&m_llc)); - bts->do_rate_ctr_add(CTR_LLC_DL_BYTES, llc_frame_length(&m_llc)); + bts_do_rate_ctr_add(bts, CTR_LLC_DL_BYTES, llc_frame_length(&m_llc)); m_llc.reset(); if (is_final) { @@ -1472,15 +1472,15 @@ enum egprs_rlcmac_dl_spb gprs_rlcmac_dl_tbf::get_egprs_dl_spb(const int bsn) */ if (block_status_dl == EGPRS_RESEG_FIRST_SEG_SENT) { /* statistics */ - bts->do_rate_ctr_inc(CTR_SPB_DL_SECOND_SEGMENT); + bts_do_rate_ctr_inc(bts, CTR_SPB_DL_SECOND_SEGMENT); return EGPRS_RLCMAC_DL_SEC_SEG; } else if ((ht_cs_init == HEADER_EGPRS_DATA_TYPE_1) || (ht_cs_init == HEADER_EGPRS_DATA_TYPE_2)) { - bts->do_rate_ctr_inc(CTR_SPB_DL_FIRST_SEGMENT); + bts_do_rate_ctr_inc(bts, CTR_SPB_DL_FIRST_SEGMENT); return EGPRS_RLCMAC_DL_FIRST_SEG; } else if ((cs_init == MCS4) && (cs_current_trans == MCS1)) { - bts->do_rate_ctr_inc(CTR_SPB_DL_FIRST_SEGMENT); + bts_do_rate_ctr_inc(bts, CTR_SPB_DL_FIRST_SEGMENT); return EGPRS_RLCMAC_DL_FIRST_SEG; } } @@ -1490,7 +1490,7 @@ enum egprs_rlcmac_dl_spb gprs_rlcmac_dl_tbf::get_egprs_dl_spb(const int bsn) void gprs_rlcmac_dl_tbf::set_window_size() { - const struct gprs_rlcmac_bts *b = bts->bts_data(); + const struct gprs_rlcmac_bts *b = bts; uint16_t ws = egprs_window_size(b, dl_slots()); LOGPTBFDL(this, LOGL_INFO, "setting EGPRS DL window size to %u, base(%u) slots(%u) ws_pdch(%u)\n", @@ -1502,55 +1502,55 @@ void gprs_rlcmac_dl_tbf::update_coding_scheme_counter_dl(enum CodingScheme cs) { switch (cs) { case CS1: - bts->do_rate_ctr_inc(CTR_GPRS_DL_CS1); + bts_do_rate_ctr_inc(bts, CTR_GPRS_DL_CS1); rate_ctr_inc(&m_dl_gprs_ctrs->ctr[TBF_CTR_GPRS_DL_CS1]); break; case CS2: - bts->do_rate_ctr_inc(CTR_GPRS_DL_CS2); + bts_do_rate_ctr_inc(bts, CTR_GPRS_DL_CS2); rate_ctr_inc(&m_dl_gprs_ctrs->ctr[TBF_CTR_GPRS_DL_CS2]); break; case CS3: - bts->do_rate_ctr_inc(CTR_GPRS_DL_CS3); + bts_do_rate_ctr_inc(bts, CTR_GPRS_DL_CS3); rate_ctr_inc(&m_dl_gprs_ctrs->ctr[TBF_CTR_GPRS_DL_CS3]); break; case CS4: - bts->do_rate_ctr_inc(CTR_GPRS_DL_CS4); + bts_do_rate_ctr_inc(bts, CTR_GPRS_DL_CS4); rate_ctr_inc(&m_dl_gprs_ctrs->ctr[TBF_CTR_GPRS_DL_CS4]); break; case MCS1: - bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS1); + bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS1); rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS1]); break; case MCS2: - bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS2); + bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS2); rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS2]); break; case MCS3: - bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS3); + bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS3); rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS3]); break; case MCS4: - bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS4); + bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS4); rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS4]); break; case MCS5: - bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS5); + bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS5); rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS5]); break; case MCS6: - bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS6); + bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS6); rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS6]); break; case MCS7: - bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS7); + bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS7); rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS7]); break; case MCS8: - bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS8); + bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS8); rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS8]); break; case MCS9: - bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS9); + bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS9); rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS9]); break; default: diff --git a/src/tbf_dl.h b/src/tbf_dl.h index 3cd88c9e..e29bb3fe 100644 --- a/src/tbf_dl.h +++ b/src/tbf_dl.h @@ -39,7 +39,7 @@ enum tbf_dl_prio { #define LOGPTBFDL(tbf, level, fmt, args...) LOGP(DTBFDL, level, "%s " fmt, tbf_name(tbf), ## args) struct gprs_rlcmac_dl_tbf : public gprs_rlcmac_tbf { - gprs_rlcmac_dl_tbf(BTS *bts, GprsMs *ms); + gprs_rlcmac_dl_tbf(struct gprs_rlcmac_bts *bts, GprsMs *ms); gprs_rlc_window *window(); void cleanup(); /* dispatch Unitdata.DL messages */ diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp index 1f3cb015..0c59a50f 100644 --- a/src/tbf_ul.cpp +++ b/src/tbf_ul.cpp @@ -111,7 +111,7 @@ struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts, GprsMs if (!tbf) return NULL; talloc_set_destructor(tbf, ul_tbf_dtor); - new (tbf) gprs_rlcmac_ul_tbf(bts->bts, ms); + new (tbf) gprs_rlcmac_ul_tbf(bts, ms); rc = tbf->setup(use_trx, single_slot); @@ -134,8 +134,8 @@ struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts, GprsMs return NULL; } - llist_add(&tbf->list(), &bts->bts->ul_tbfs()); - tbf->bts->do_rate_ctr_inc(CTR_TBF_UL_ALLOCATED); + llist_add_tail(tbf_bts_list(tbf), &bts->ul_tbfs); + bts_do_rate_ctr_inc(tbf->bts, CTR_TBF_UL_ALLOCATED); return tbf; } @@ -171,7 +171,7 @@ struct gprs_rlcmac_ul_tbf *handle_tbf_reject(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_trx *trx = &bts->trx[trx_no]; if (!ms) - ms = bts->bts->ms_alloc(0, 0); + ms = bts_alloc_ms(bts, 0, 0); ms_set_tlli(ms, tlli); ul_tbf = talloc(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf); @@ -179,10 +179,10 @@ struct gprs_rlcmac_ul_tbf *handle_tbf_reject(struct gprs_rlcmac_bts *bts, return ul_tbf; talloc_set_destructor(ul_tbf, ul_tbf_dtor); - new (ul_tbf) gprs_rlcmac_ul_tbf(bts->bts, ms); + new (ul_tbf) gprs_rlcmac_ul_tbf(bts, ms); - llist_add(&ul_tbf->list(), &bts->bts->ul_tbfs()); - ul_tbf->bts->do_rate_ctr_inc(CTR_TBF_UL_ALLOCATED); + llist_add(tbf_bts_list((struct gprs_rlcmac_tbf *)ul_tbf), &bts->ul_tbfs); + bts_do_rate_ctr_inc(ul_tbf->bts, CTR_TBF_UL_ALLOCATED); TBF_SET_ASS_ON(ul_tbf, GPRS_RLCMAC_FLAG_PACCH, false); ms_attach_tbf(ms, ul_tbf); @@ -206,7 +206,7 @@ struct gprs_rlcmac_ul_tbf *handle_tbf_reject(struct gprs_rlcmac_bts *bts, return ul_tbf; } -gprs_rlcmac_ul_tbf::gprs_rlcmac_ul_tbf(BTS *bts_, GprsMs *ms) : +gprs_rlcmac_ul_tbf::gprs_rlcmac_ul_tbf(struct gprs_rlcmac_bts *bts_, GprsMs *ms) : gprs_rlcmac_tbf(bts_, ms, GPRS_RLCMAC_UL_TBF), m_rx_counter(0), m_contention_resolution_done(0), @@ -243,7 +243,7 @@ int gprs_rlcmac_ul_tbf::assemble_forward_llc(const gprs_rlc_data *_data) frame = frames + i; if (frame->length) { - bts->do_rate_ctr_add(CTR_RLC_UL_PAYLOAD_BYTES, frame->length); + bts_do_rate_ctr_add(bts, CTR_RLC_UL_PAYLOAD_BYTES, frame->length); LOGPTBFUL(this, LOGL_DEBUG, "Frame %d " "starts at offset %d, " @@ -259,7 +259,7 @@ int gprs_rlcmac_ul_tbf::assemble_forward_llc(const gprs_rlc_data *_data) /* send frame to SGSN */ LOGPTBFUL(this, LOGL_DEBUG, "complete UL frame len=%d\n", llc_frame_length(&m_llc)); snd_ul_ud(); - bts->do_rate_ctr_add(CTR_LLC_UL_BYTES, llc_frame_length(&m_llc)); + bts_do_rate_ctr_add(bts, CTR_LLC_UL_BYTES, llc_frame_length(&m_llc)); m_llc.reset(); } } @@ -440,7 +440,7 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged( rdbi, rlc->cs, rlc_data, NULL, 0, &new_tlli); if (num_chunks < 0) { - bts->do_rate_ctr_inc(CTR_DECODE_ERRORS); + bts_do_rate_ctr_inc(bts, CTR_DECODE_ERRORS); LOGPTBFUL(this, LOGL_NOTICE, "Failed to decode TLLI of %s UL DATA TFI=%d.\n", mcs_name(rlc->cs), rlc->tfi); @@ -589,7 +589,7 @@ egprs_rlc_ul_reseg_bsn_state gprs_rlcmac_ul_tbf::handle_egprs_ul_second_seg( union split_block_status *spb_status = &block->spb_status; uint8_t *rlc_data = &block->block[0]; - bts->do_rate_ctr_inc(CTR_SPB_UL_SECOND_SEGMENT); + bts_do_rate_ctr_inc(bts, CTR_SPB_UL_SECOND_SEGMENT); if (spb_status->block_status_ul & EGPRS_RESEG_FIRST_SEG_RXD) { @@ -622,7 +622,7 @@ egprs_rlc_ul_reseg_bsn_state gprs_rlcmac_ul_tbf::handle_egprs_ul_first_seg( uint8_t *rlc_data = &block->block[0]; union split_block_status *spb_status = &block->spb_status; - bts->do_rate_ctr_inc(CTR_SPB_UL_FIRST_SEGMENT); + bts_do_rate_ctr_inc(bts, CTR_SPB_UL_FIRST_SEGMENT); if (spb_status->block_status_ul & EGPRS_RESEG_SECOND_SEG_RXD) { LOGPTBFUL(this, LOGL_DEBUG, @@ -702,55 +702,55 @@ void gprs_rlcmac_ul_tbf::update_coding_scheme_counter_ul(enum CodingScheme cs) { switch (cs) { case CS1: - bts->do_rate_ctr_inc(CTR_GPRS_UL_CS1); + bts_do_rate_ctr_inc(bts, CTR_GPRS_UL_CS1); rate_ctr_inc(&m_ul_gprs_ctrs->ctr[TBF_CTR_GPRS_UL_CS1]); break; case CS2: - bts->do_rate_ctr_inc(CTR_GPRS_UL_CS2); + bts_do_rate_ctr_inc(bts, CTR_GPRS_UL_CS2); rate_ctr_inc(&m_ul_gprs_ctrs->ctr[TBF_CTR_GPRS_UL_CS2]); break; case CS3: - bts->do_rate_ctr_inc(CTR_GPRS_UL_CS3); + bts_do_rate_ctr_inc(bts, CTR_GPRS_UL_CS3); rate_ctr_inc(&m_ul_gprs_ctrs->ctr[TBF_CTR_GPRS_UL_CS3]); break; case CS4: - bts->do_rate_ctr_inc(CTR_GPRS_UL_CS4); + bts_do_rate_ctr_inc(bts, CTR_GPRS_UL_CS4); rate_ctr_inc(&m_ul_gprs_ctrs->ctr[TBF_CTR_GPRS_UL_CS4]); break; case MCS1: - bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS1); + bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS1); rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS1]); break; case MCS2: - bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS2); + bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS2); rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS2]); break; case MCS3: - bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS3); + bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS3); rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS3]); break; case MCS4: - bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS4); + bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS4); rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS4]); break; case MCS5: - bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS5); + bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS5); rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS5]); break; case MCS6: - bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS6); + bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS6); rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS6]); break; case MCS7: - bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS7); + bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS7); rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS7]); break; case MCS8: - bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS8); + bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS8); rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS8]); break; case MCS9: - bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS9); + bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS9); rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS9]); break; default: @@ -761,7 +761,7 @@ void gprs_rlcmac_ul_tbf::update_coding_scheme_counter_ul(enum CodingScheme cs) void gprs_rlcmac_ul_tbf::set_window_size() { - const struct gprs_rlcmac_bts *b = bts->bts_data(); + const struct gprs_rlcmac_bts *b = bts; uint16_t ws = egprs_window_size(b, ul_slots()); LOGPTBFUL(this, LOGL_INFO, "setting EGPRS UL window size to %u, base(%u) slots(%u) ws_pdch(%u)\n", ws, bts->pcu->vty.ws_base, pcu_bitcount(ul_slots()), bts->pcu->vty.ws_pdch); diff --git a/src/tbf_ul.h b/src/tbf_ul.h index 1d9cf50c..8713596e 100644 --- a/src/tbf_ul.h +++ b/src/tbf_ul.h @@ -50,7 +50,7 @@ enum tbf_egprs_ul_counters { #define LOGPTBFUL(tbf, level, fmt, args...) LOGP(DTBFUL, level, "%s " fmt, tbf_name(tbf), ## args) struct gprs_rlcmac_ul_tbf : public gprs_rlcmac_tbf { - gprs_rlcmac_ul_tbf(BTS *bts, GprsMs *ms); + gprs_rlcmac_ul_tbf(struct gprs_rlcmac_bts *bts, GprsMs *ms); gprs_rlc_window *window(); struct msgb *create_ul_ack(uint32_t fn, uint8_t ts); bool ctrl_ack_to_toggle(); |