diff options
Diffstat (limited to 'src/bts.cpp')
-rw-r--r-- | src/bts.cpp | 62 |
1 files changed, 54 insertions, 8 deletions
diff --git a/src/bts.cpp b/src/bts.cpp index 353451c6..d6ed8f3f 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -38,12 +38,6 @@ extern "C" { extern void *tall_pcu_ctx; -static llist_head *gprs_rlcmac_tbfs_lists[] = { - &gprs_rlcmac_ul_tbfs, - &gprs_rlcmac_dl_tbfs, - NULL -}; - static BTS s_bts; BTS* BTS::main_bts() @@ -67,6 +61,8 @@ BTS::BTS() , m_sba(*this) { memset(&m_bts, 0, sizeof(m_bts)); + INIT_LLIST_HEAD(&m_bts.ul_tbfs); + INIT_LLIST_HEAD(&m_bts.dl_tbfs); m_bts.bts = this; } @@ -84,6 +80,13 @@ int BTS::add_paging(uint8_t chan_needed, uint8_t *identity_lv) uint8_t slot_mask[8]; int8_t first_ts; /* must be signed */ + llist_head *tbfs_lists[] = { + &m_bts.ul_tbfs, + &m_bts.dl_tbfs, + NULL + }; + + LOGP(DRLCMAC, LOGL_INFO, "Add RR paging: chan-needed=%d MI=%s\n", chan_needed, osmo_hexdump(identity_lv + 1, identity_lv[0])); @@ -92,8 +95,8 @@ int BTS::add_paging(uint8_t chan_needed, uint8_t *identity_lv) * Mark only the first slot found. * Don't mark, if TBF uses a different slot that is already marked. */ memset(slot_mask, 0, sizeof(slot_mask)); - for (l = 0; gprs_rlcmac_tbfs_lists[l]; l++) { - llist_for_each_entry(tbf, gprs_rlcmac_tbfs_lists[l], list) { + for (l = 0; tbfs_lists[l]; l++) { + llist_for_each_entry(tbf, tbfs_lists[l], list) { first_ts = -1; for (ts = 0; ts < 8; ts++) { if (tbf->pdch[ts]) { @@ -153,6 +156,49 @@ int BTS::add_paging(uint8_t chan_needed, uint8_t *identity_lv) return 0; } +/* search for active downlink or uplink tbf */ +gprs_rlcmac_tbf *BTS::tbf_by_tlli(uint32_t tlli, enum gprs_rlcmac_tbf_direction dir) +{ + struct gprs_rlcmac_tbf *tbf; + if (dir == GPRS_RLCMAC_UL_TBF) { + llist_for_each_entry(tbf, &m_bts.ul_tbfs, list) { + if (tbf->state_is_not(GPRS_RLCMAC_RELEASING) + && tbf->tlli == tlli && tbf->tlli_valid) + return tbf; + } + } else { + llist_for_each_entry(tbf, &m_bts.dl_tbfs, list) { + if (tbf->state_is_not(GPRS_RLCMAC_RELEASING) + && tbf->tlli == tlli) + return tbf; + } + } + return NULL; +} + +gprs_rlcmac_tbf *BTS::tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts) +{ + 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_entry(tbf, &m_bts.ul_tbfs, list) { + if (tbf->state_is_not(GPRS_RLCMAC_RELEASING) + && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED + && tbf->poll_fn == fn && tbf->trx_no == trx + && tbf->control_ts == ts) + return tbf; + } + llist_for_each_entry(tbf, &m_bts.dl_tbfs, list) { + if (tbf->state_is_not(GPRS_RLCMAC_RELEASING) + && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED + && tbf->poll_fn == fn && tbf->trx_no == trx + && tbf->control_ts == ts) + return tbf; + } + return NULL; +} + void gprs_rlcmac_pdch::enable() { /* TODO: Check if there are still allocated resources.. */ |