diff options
-rw-r--r-- | src/bts.cpp | 62 | ||||
-rw-r--r-- | src/bts.h | 12 | ||||
-rw-r--r-- | src/encoding.cpp | 1 | ||||
-rw-r--r-- | src/gprs_rlcmac.cpp | 8 | ||||
-rw-r--r-- | src/gprs_rlcmac.h | 7 | ||||
-rw-r--r-- | src/gprs_rlcmac_data.cpp | 76 | ||||
-rw-r--r-- | src/gprs_rlcmac_sched.cpp | 9 | ||||
-rw-r--r-- | src/gprs_rlcmac_ts_alloc.cpp | 1 | ||||
-rw-r--r-- | src/pcu_l1_if.cpp | 4 | ||||
-rw-r--r-- | src/poll_controller.cpp | 5 | ||||
-rw-r--r-- | src/sysmo_sock.cpp | 1 | ||||
-rw-r--r-- | src/tbf.cpp | 79 | ||||
-rw-r--r-- | src/tbf.h | 10 | ||||
-rw-r--r-- | tests/alloc/AllocTest.cpp | 22 |
14 files changed, 153 insertions, 144 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.. */ @@ -30,11 +30,11 @@ extern "C" { #include "poll_controller.h" #include "sba.h" #include "ta.h" +#include "tbf.h" #endif #include <stdint.h> -struct gprs_rlcmac_tbf; struct BTS; /* @@ -104,6 +104,13 @@ struct gprs_rlcmac_bts { uint8_t force_two_phase; uint8_t alpha, gamma; + /* TBF handling, make private or move into TBFController */ + /* list of uplink TBFs */ + struct llist_head ul_tbfs; + /* list of downlink TBFs */ + struct llist_head dl_tbfs; + + /** * Point back to the C++ object. This is used during the transition * period. @@ -134,6 +141,9 @@ public: /** add paging to paging queue(s) */ int add_paging(uint8_t chan_needed, uint8_t *identity_lv); + gprs_rlcmac_tbf *tbf_by_tlli(uint32_t tlli, enum gprs_rlcmac_tbf_direction dir); + gprs_rlcmac_tbf *tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts); + private: int m_cur_fn; struct gprs_rlcmac_bts m_bts; diff --git a/src/encoding.cpp b/src/encoding.cpp index 26ac71ec..e28fff7f 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -21,6 +21,7 @@ #include <encoding.h> #include <gprs_rlcmac.h> +#include <bts.h> #include <tbf.h> #include <gprs_debug.h> diff --git a/src/gprs_rlcmac.cpp b/src/gprs_rlcmac.cpp index 87cb8460..a8fd5ec5 100644 --- a/src/gprs_rlcmac.cpp +++ b/src/gprs_rlcmac.cpp @@ -36,15 +36,13 @@ struct gprs_rlcmac_cs gprs_rlcmac_cs[] = { { 54, 53, 50 }, /* CS-4 */ }; -LLIST_HEAD(gprs_rlcmac_ul_tbfs); -LLIST_HEAD(gprs_rlcmac_dl_tbfs); extern void *tall_pcu_ctx; #ifdef DEBUG_DIAGRAM struct timeval diagram_time = {0,0}; struct timeval diagram_last_tv = {0,0}; -void debug_diagram(int diag, const char *format, ...) +void debug_diagram(BTS *bts, int diag, const char *format, ...) { va_list ap; char debug[128]; @@ -60,14 +58,14 @@ void debug_diagram(int diag, const char *format, ...) va_end(ap); memset(tbf_a, 0, sizeof(tbf_a)); - llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) { + llist_for_each_entry(tbf, &bts->bts_data()->ul_tbfs, list) { if (tbf->diag < 16) { if (tbf->diag > max_diag) max_diag = tbf->diag; tbf_a[tbf->diag] = tbf; } } - llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { + llist_for_each_entry(tbf, &bts->bts_data()->dl_tbfs, list) { if (tbf->diag < 16) { if (tbf->diag > max_diag) max_diag = tbf->diag; diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h index 3a2569c3..90c1b775 100644 --- a/src/gprs_rlcmac.h +++ b/src/gprs_rlcmac.h @@ -44,6 +44,7 @@ extern "C" { struct gprs_rlcmac_tbf; struct gprs_rlcmac_bts; +struct BTS; #ifdef __cplusplus /* @@ -67,9 +68,9 @@ struct gprs_rlcmac_cs { extern struct gprs_rlcmac_cs gprs_rlcmac_cs[]; #ifdef DEBUG_DIAGRAM -void debug_diagram(int diag, const char *format, ...); +void debug_diagram(BTS *bts, int diag, const char *format, ...); #else -#define debug_diagram(a, b, args...) ; +#define debug_diagram(a, b, c, args...) ; #endif int gprs_rlcmac_received_lost(struct gprs_rlcmac_tbf *tbf, uint16_t received, @@ -142,7 +143,7 @@ int gprs_rlcmac_rcv_rts_block(struct gprs_rlcmac_bts *bts, uint8_t trx, uint8_t ts, uint16_t arfcn, uint32_t fn, uint8_t block_nr); -int gprs_rlcmac_imm_ass_cnf(uint8_t *data, uint32_t fn); +int gprs_rlcmac_imm_ass_cnf(BTS *bts, uint8_t *data, uint32_t fn); extern "C" { #endif diff --git a/src/gprs_rlcmac_data.cpp b/src/gprs_rlcmac_data.cpp index 32585938..170ed9a1 100644 --- a/src/gprs_rlcmac_data.cpp +++ b/src/gprs_rlcmac_data.cpp @@ -100,13 +100,13 @@ int gprs_rlcmac_poll_timeout(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_UL_ACK); } tbf->ul_ack_state = GPRS_RLCMAC_UL_ACK_NONE; - debug_diagram(tbf->diag, "timeout UL-ACK"); + debug_diagram(bts->bts, tbf->diag, "timeout UL-ACK"); if (tbf->state_is(GPRS_RLCMAC_FINISHED)) { tbf->dir.ul.n3103++; if (tbf->dir.ul.n3103 == bts->n3103) { LOGP(DRLCMAC, LOGL_NOTICE, "- N3103 exceeded\n"); - debug_diagram(tbf->diag, "N3103 exceeded"); + debug_diagram(bts->bts, tbf->diag, "N3103 exceeded"); tbf_new_state(tbf, GPRS_RLCMAC_RELEASING); tbf_timer_start(tbf, 3169, bts->t3169, 0); return 0; @@ -124,11 +124,11 @@ int gprs_rlcmac_poll_timeout(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS); } tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE; - debug_diagram(tbf->diag, "timeout UL-ASS"); + debug_diagram(bts->bts, tbf->diag, "timeout UL-ASS"); tbf->n3105++; if (tbf->n3105 == bts->n3105) { LOGP(DRLCMAC, LOGL_NOTICE, "- N3105 exceeded\n"); - debug_diagram(tbf->diag, "N3105 exceeded"); + debug_diagram(bts->bts, tbf->diag, "N3105 exceeded"); tbf_new_state(tbf, GPRS_RLCMAC_RELEASING); tbf_timer_start(tbf, 3195, bts->t3195, 0); return 0; @@ -145,11 +145,11 @@ int gprs_rlcmac_poll_timeout(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS); } tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE; - debug_diagram(tbf->diag, "timeout DL-ASS"); + debug_diagram(bts->bts, tbf->diag, "timeout DL-ASS"); tbf->n3105++; if (tbf->n3105 == bts->n3105) { LOGP(DRLCMAC, LOGL_NOTICE, "- N3105 exceeded\n"); - debug_diagram(tbf->diag, "N3105 exceeded"); + debug_diagram(bts->bts, tbf->diag, "N3105 exceeded"); tbf_new_state(tbf, GPRS_RLCMAC_RELEASING); tbf_timer_start(tbf, 3195, bts->t3195, 0); return 0; @@ -164,11 +164,11 @@ int gprs_rlcmac_poll_timeout(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf gprs_rlcmac_diag(tbf); tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK); } - debug_diagram(tbf->diag, "timeout DL-ACK"); + debug_diagram(bts->bts, tbf->diag, "timeout DL-ACK"); tbf->n3105++; if (tbf->n3105 == bts->n3105) { LOGP(DRLCMAC, LOGL_NOTICE, "- N3105 exceeded\n"); - debug_diagram(tbf->diag, "N3105 exceeded"); + debug_diagram(bts->bts, tbf->diag, "N3105 exceeded"); tbf_new_state(tbf, GPRS_RLCMAC_RELEASING); tbf_timer_start(tbf, 3195, bts->t3195, 0); return 0; @@ -223,7 +223,7 @@ int gprs_rlcmac_rcv_control_block(struct gprs_rlcmac_bts *bts, switch (ul_control_block->u.MESSAGE_TYPE) { case MT_PACKET_CONTROL_ACK: tlli = ul_control_block->u.Packet_Control_Acknowledgement.TLLI; - tbf = tbf_by_poll_fn(fn, trx, ts); + tbf = bts->bts->tbf_by_poll_fn(fn, trx, ts); if (!tbf) { LOGP(DRLCMAC, LOGL_NOTICE, "PACKET CONTROL ACK with " "unknown FN=%u TLL=0x%08x (TRX %d TS %d)\n", @@ -243,7 +243,7 @@ int gprs_rlcmac_rcv_control_block(struct gprs_rlcmac_bts *bts, if (tbf->ul_ack_state == GPRS_RLCMAC_UL_ACK_WAIT_ACK) { LOGP(DRLCMAC, LOGL_DEBUG, "TBF: [UPLINK] END TFI: %u TLLI: 0x%08x \n", tbf->tfi, tbf->tlli); tbf->ul_ack_state = GPRS_RLCMAC_UL_ACK_NONE; - debug_diagram(tbf->diag, "got CTL-ACK (fin)"); + debug_diagram(bts->bts, tbf->diag, "got CTL-ACK (fin)"); if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_UL_ACK))) { tbf->state_flags &= @@ -259,9 +259,9 @@ int gprs_rlcmac_rcv_control_block(struct gprs_rlcmac_bts *bts, /* reset N3105 */ tbf->n3105 = 0; tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE; - debug_diagram(tbf->diag, "got CTL-ACK DL-ASS"); + debug_diagram(bts->bts, tbf->diag, "got CTL-ACK DL-ASS"); if (tbf->direction == GPRS_RLCMAC_UL_TBF) - tbf = tbf_by_tlli(tbf->tlli, + tbf = bts->bts->tbf_by_tlli(tbf->tlli, GPRS_RLCMAC_DL_TBF); if (!tbf) { LOGP(DRLCMAC, LOGL_ERROR, "Got ACK, but DL " @@ -286,9 +286,9 @@ int gprs_rlcmac_rcv_control_block(struct gprs_rlcmac_bts *bts, /* reset N3105 */ tbf->n3105 = 0; tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE; - debug_diagram(tbf->diag, "got CTL-AC UL-ASS"); + debug_diagram(bts->bts, tbf->diag, "got CTL-AC UL-ASS"); if (tbf->direction == GPRS_RLCMAC_DL_TBF) - tbf = tbf_by_tlli(tbf->tlli, + tbf = bts->bts->tbf_by_tlli(tbf->tlli, GPRS_RLCMAC_UL_TBF); if (!tbf) { LOGP(DRLCMAC, LOGL_ERROR, "Got ACK, but UL " @@ -311,7 +311,7 @@ int gprs_rlcmac_rcv_control_block(struct gprs_rlcmac_bts *bts, break; case MT_PACKET_DOWNLINK_ACK_NACK: tfi = ul_control_block->u.Packet_Downlink_Ack_Nack.DOWNLINK_TFI; - tbf = tbf_by_poll_fn(fn, trx, ts); + tbf = bts->bts->tbf_by_poll_fn(fn, trx, ts); if (!tbf) { LOGP(DRLCMAC, LOGL_NOTICE, "PACKET DOWNLINK ACK with " "unknown FN=%u TFI=%d (TRX %d TS %d)\n", @@ -336,7 +336,7 @@ int gprs_rlcmac_rcv_control_block(struct gprs_rlcmac_bts *bts, tlli = tbf->tlli; LOGP(DRLCMAC, LOGL_DEBUG, "RX: [PCU <- BTS] TFI: %u TLLI: 0x%08x Packet Downlink Ack/Nack\n", tbf->tfi, tbf->tlli); tbf->poll_state = GPRS_RLCMAC_POLL_NONE; - debug_diagram(tbf->diag, "got DL-ACK"); + debug_diagram(bts->bts, tbf->diag, "got DL-ACK"); rc = gprs_rlcmac_downlink_ack(bts, tbf, ul_control_block->u.Packet_Downlink_Ack_Nack.Ack_Nack_Description.FINAL_ACK_INDICATION, @@ -358,7 +358,7 @@ int gprs_rlcmac_rcv_control_block(struct gprs_rlcmac_bts *bts, case MT_PACKET_RESOURCE_REQUEST: if (ul_control_block->u.Packet_Resource_Request.ID.UnionType) { tlli = ul_control_block->u.Packet_Resource_Request.ID.u.TLLI; - tbf = tbf_by_tlli(tlli, GPRS_RLCMAC_UL_TBF); + tbf = bts->bts->tbf_by_tlli(tlli, GPRS_RLCMAC_UL_TBF); if (tbf) { LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from " "TLLI=0x%08x while UL TBF=%d still " @@ -372,7 +372,7 @@ int gprs_rlcmac_rcv_control_block(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *dl_tbf; uint8_t ta; - if ((dl_tbf = tbf_by_tlli(tlli, GPRS_RLCMAC_DL_TBF))) { + if ((dl_tbf = bts->bts->tbf_by_tlli(tlli, GPRS_RLCMAC_DL_TBF))) { LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from " "TLLI=0x%08x while DL TBF=%d still exists. " "Killing pending DL TBF\n", tlli, @@ -411,7 +411,7 @@ int gprs_rlcmac_rcv_control_block(struct gprs_rlcmac_bts *bts, tbf->control_ts = ts; /* schedule uplink assignment */ tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS; - debug_diagram(tbf->diag, "Res. REQ"); + debug_diagram(bts->bts, tbf->diag, "Res. REQ"); break; } tfi = tbf->tfi; @@ -720,7 +720,7 @@ struct msgb *gprs_rlcmac_send_uplink_ack(struct gprs_rlcmac_bts *bts, tbf->dir.ul.final_ack_sent = 1; } else tbf->ul_ack_state = GPRS_RLCMAC_UL_ACK_NONE; - debug_diagram(tbf->diag, "send UL-ACK"); + debug_diagram(bts->bts, tbf->diag, "send UL-ACK"); return msg; } @@ -792,7 +792,7 @@ int gprs_rlcmac_rcv_data_block_acknowledged(struct gprs_rlcmac_bts *bts, } LOGP(DRLCMACUL, LOGL_INFO, "Decoded premier TLLI=0x%08x of " "UL DATA TBF=%d.\n", tbf->tlli, rh->tfi); - if ((dl_tbf = tbf_by_tlli(tbf->tlli, GPRS_RLCMAC_DL_TBF))) { + if ((dl_tbf = bts->bts->tbf_by_tlli(tbf->tlli, GPRS_RLCMAC_DL_TBF))) { LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from " "TLLI=0x%08x while DL TBF=%d still exists. " "Killing pending DL TBF\n", tbf->tlli, @@ -801,7 +801,7 @@ int gprs_rlcmac_rcv_data_block_acknowledged(struct gprs_rlcmac_bts *bts, } /* tbf_by_tlli will not find your TLLI, because it is not * yet marked valid */ - if ((ul_tbf = tbf_by_tlli(tbf->tlli, GPRS_RLCMAC_UL_TBF))) { + if ((ul_tbf = bts->bts->tbf_by_tlli(tbf->tlli, GPRS_RLCMAC_UL_TBF))) { LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from " "TLLI=0x%08x while UL TBF=%d still exists. " "Killing pending UL TBF\n", tbf->tlli, @@ -926,13 +926,13 @@ int gprs_rlcmac_rcv_data_block_acknowledged(struct gprs_rlcmac_bts *bts, if (tbf->ul_ack_state == GPRS_RLCMAC_UL_ACK_NONE) { #ifdef DEBUG_DIAGRAM if (rh->si) - debug_diagram(tbf->diag, "sched UL-ACK stall"); + debug_diagram(bts->bts, tbf->diag, "sched UL-ACK stall"); if (rh->ti) - debug_diagram(tbf->diag, "sched UL-ACK TLLI"); + debug_diagram(bts->bts, tbf->diag, "sched UL-ACK TLLI"); if (tbf->state_is(GPRS_RLCMAC_FINISHED)) - debug_diagram(tbf->diag, "sched UL-ACK CV==0"); + debug_diagram(bts->bts, tbf->diag, "sched UL-ACK CV==0"); if ((tbf->dir.ul.rx_counter % SEND_ACK_AFTER_FRAMES) == 0) - debug_diagram(tbf->diag, "sched UL-ACK n=%d", + debug_diagram(bts->bts, tbf->diag, "sched UL-ACK n=%d", tbf->dir.ul.rx_counter); #endif /* trigger sending at next RTS */ @@ -970,7 +970,7 @@ struct msgb *gprs_rlcmac_send_packet_uplink_assignment( /* on down TBF we get the uplink TBF to be assigned. */ if (tbf->direction == GPRS_RLCMAC_DL_TBF) - new_tbf = tbf_by_tlli(tbf->tlli, GPRS_RLCMAC_UL_TBF); + new_tbf = bts->bts->tbf_by_tlli(tbf->tlli, GPRS_RLCMAC_UL_TBF); else new_tbf = tbf; @@ -1015,7 +1015,7 @@ struct msgb *gprs_rlcmac_send_packet_uplink_assignment( tbf_new_state(new_tbf, GPRS_RLCMAC_FLOW); tbf_assign_control_ts(new_tbf); #endif - debug_diagram(tbf->diag, "send UL-ASS"); + debug_diagram(bts->bts, tbf->diag, "send UL-ASS"); return msg; } @@ -1438,11 +1438,11 @@ tx_block: tbf->poll_fn = (fn + 13) % 2715648; #ifdef DEBUG_DIAGRAM - debug_diagram(tbf->diag, "poll DL-ACK"); + debug_diagram(bts->bts, tbf->diag, "poll DL-ACK"); if (first_fin_ack) - debug_diagram(tbf->diag, "(is first FINAL)"); + debug_diagram(bts->bts, tbf->diag, "(is first FINAL)"); if (rh->fbi) - debug_diagram(tbf->diag, "(FBI is set)"); + debug_diagram(bts->bts, tbf->diag, "(FBI is set)"); #endif /* set polling in header */ @@ -1566,7 +1566,7 @@ int gprs_rlcmac_downlink_ack(struct gprs_rlcmac_bts *bts, } LOGP(DRLCMACDL, LOGL_DEBUG, "- Final ACK received.\n"); - debug_diagram(tbf->diag, "got Final ACK"); + debug_diagram(bts->bts, tbf->diag, "got Final ACK"); /* range V(A)..V(S)-1 */ for (bsn = tbf->dir.dl.v_a; bsn != tbf->dir.dl.v_s; bsn = (bsn + 1) & mod_sns) { @@ -1584,7 +1584,7 @@ int gprs_rlcmac_downlink_ack(struct gprs_rlcmac_bts *bts, LOGP(DRLCMACDL, LOGL_DEBUG, "- No new message, so we " "release.\n"); /* start T3193 */ - debug_diagram(tbf->diag, "start T3193"); + debug_diagram(bts->bts, tbf->diag, "start T3193"); tbf_timer_start(tbf, 3193, bts->t3193_msec / 1000, (bts->t3193_msec % 1000) * 1000); tbf_new_state(tbf, GPRS_RLCMAC_WAIT_RELEASE); @@ -1650,7 +1650,7 @@ struct msgb *gprs_rlcmac_send_packet_downlink_assignment( "finished.\n"); return NULL; } - new_tbf = tbf_by_tlli(tbf->tlli, GPRS_RLCMAC_DL_TBF); + new_tbf = bts->bts->tbf_by_tlli(tbf->tlli, GPRS_RLCMAC_DL_TBF); } else new_tbf = tbf; if (!new_tbf) { @@ -1696,7 +1696,7 @@ struct msgb *gprs_rlcmac_send_packet_downlink_assignment( tbf_timer_stop(new_tbf); } - debug_diagram(tbf->diag, "send DL-ASS"); + debug_diagram(bts->bts, tbf->diag, "send DL-ASS"); return msg; } @@ -1707,7 +1707,7 @@ static void gprs_rlcmac_downlink_assignment(struct gprs_rlcmac_bts *bts, { int plen; - debug_diagram(tbf->diag, "IMM.ASS (PCH)"); + debug_diagram(bts->bts, tbf->diag, "IMM.ASS (PCH)"); LOGP(DRLCMAC, LOGL_INFO, "TX: START TFI: %u TLLI: 0x%08x Immediate Assignment Downlink (PCH)\n", tbf->tfi, tbf->tlli); bitvec *immediate_assignment = bitvec_alloc(22); /* without plen */ bitvec_unhex(immediate_assignment, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); @@ -1771,7 +1771,7 @@ void gprs_rlcmac_trigger_downlink_assignment(struct gprs_rlcmac_bts *bts, } } -int gprs_rlcmac_imm_ass_cnf(uint8_t *data, uint32_t fn) +int gprs_rlcmac_imm_ass_cnf(BTS *bts, uint8_t *data, uint32_t fn) { struct gprs_rlcmac_tbf *tbf; uint8_t plen; @@ -1795,7 +1795,7 @@ int gprs_rlcmac_imm_ass_cnf(uint8_t *data, uint32_t fn) tlli |= (*data++) << 4; tlli |= (*data++) >> 4; - tbf = tbf_by_tlli(tlli, GPRS_RLCMAC_DL_TBF); + tbf = bts->tbf_by_tlli(tlli, GPRS_RLCMAC_DL_TBF); if (!tbf) { LOGP(DRLCMAC, LOGL_ERROR, "Got IMM.ASS confirm, but TLLI=%08x " "does not exit\n", tlli); diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp index 42110931..069e90f6 100644 --- a/src/gprs_rlcmac_sched.cpp +++ b/src/gprs_rlcmac_sched.cpp @@ -23,7 +23,8 @@ #include <bts.h> #include <tbf.h> -static uint32_t sched_poll(uint8_t trx, uint8_t ts, uint32_t fn, uint8_t block_nr, +static uint32_t sched_poll(struct gprs_rlcmac_bts *bts, + uint8_t trx, uint8_t ts, uint32_t fn, uint8_t block_nr, struct gprs_rlcmac_tbf **poll_tbf, struct gprs_rlcmac_tbf **ul_ass_tbf, struct gprs_rlcmac_tbf **dl_ass_tbf, @@ -37,7 +38,7 @@ static uint32_t sched_poll(uint8_t trx, uint8_t ts, uint32_t fn, uint8_t block_n if ((block_nr % 3) == 2) poll_fn ++; poll_fn = poll_fn % 2715648; - llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) { + llist_for_each_entry(tbf, &bts->ul_tbfs, list) { /* this trx, this ts */ if (tbf->trx_no != trx || tbf->control_ts != ts) continue; @@ -53,7 +54,7 @@ static uint32_t sched_poll(uint8_t trx, uint8_t ts, uint32_t fn, uint8_t block_n *ul_ass_tbf = tbf; #warning "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_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { + llist_for_each_entry(tbf, &bts->dl_tbfs, list) { /* this trx, this ts */ if (tbf->trx_no != trx || tbf->control_ts != ts) continue; @@ -232,7 +233,7 @@ int gprs_rlcmac_rcv_rts_block(struct gprs_rlcmac_bts *bts, /* store last frame number of RTS */ pdch->last_rts_fn = fn; - poll_fn = sched_poll(trx, ts, fn, block_nr, &poll_tbf, &ul_ass_tbf, + poll_fn = sched_poll(bts, trx, ts, fn, block_nr, &poll_tbf, &ul_ass_tbf, &dl_ass_tbf, &ul_ack_tbf); /* check uplink ressource for polling */ if (poll_tbf) diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index bf69296d..5bfc18f2 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -21,6 +21,7 @@ #include <gprs_rlcmac.h> #include <gprs_debug.h> +#include <bts.h> #include <tbf.h> #include <errno.h> diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp index 89d3eb2f..ab9c134b 100644 --- a/src/pcu_l1_if.cpp +++ b/src/pcu_l1_if.cpp @@ -221,8 +221,8 @@ 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) - rc = gprs_rlcmac_imm_ass_cnf(data_cnf->data, - data_cnf->fn); + rc = gprs_rlcmac_imm_ass_cnf(BTS::main_bts(), + data_cnf->data, data_cnf->fn); break; default: LOGP(DL1IF, LOGL_ERROR, "Received PCU data confirm with " diff --git a/src/poll_controller.cpp b/src/poll_controller.cpp index 461b1a2b..115a68f2 100644 --- a/src/poll_controller.cpp +++ b/src/poll_controller.cpp @@ -21,6 +21,7 @@ */ #include <poll_controller.h> +#include <bts.h> #include <tbf.h> PollController::PollController(BTS& bts) @@ -35,7 +36,7 @@ void PollController::expireTimedout(int frame_number) uint32_t elapsed; /* check for poll timeout */ - llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) { + llist_for_each_entry(tbf, &bts->ul_tbfs, list) { if (tbf->poll_state == GPRS_RLCMAC_POLL_SCHED) { elapsed = (frame_number + 2715648 - tbf->poll_fn) % 2715648; @@ -43,7 +44,7 @@ void PollController::expireTimedout(int frame_number) gprs_rlcmac_poll_timeout(bts, tbf); } } - llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { + llist_for_each_entry(tbf, &bts->dl_tbfs, list) { if (tbf->poll_state == GPRS_RLCMAC_POLL_SCHED) { elapsed = (frame_number + 2715648 - tbf->poll_fn) % 2715648; diff --git a/src/sysmo_sock.cpp b/src/sysmo_sock.cpp index 6af2e9ab..2e2d9d39 100644 --- a/src/sysmo_sock.cpp +++ b/src/sysmo_sock.cpp @@ -36,6 +36,7 @@ extern "C" { #include <gprs_debug.h> #include <gprs_bssgp_pcu.h> #include <pcuif_proto.h> +#include <bts.h> #include <tbf.h> extern void *tall_pcu_ctx; diff --git a/src/tbf.cpp b/src/tbf.cpp index 3a1ac456..2fcb51c2 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -47,10 +47,11 @@ static inline void tbf_assign_imsi(struct gprs_rlcmac_tbf *tbf, strncpy(tbf->meas.imsi, imsi, sizeof(tbf->meas.imsi) - 1); } -static struct gprs_rlcmac_tbf *tbf_lookup_dl(const uint32_t tlli, const char *imsi) +static struct gprs_rlcmac_tbf *tbf_lookup_dl(BTS *bts, + const uint32_t tlli, const char *imsi) { /* TODO: look up by IMSI first, then tlli, then old_tlli */ - return tbf_by_tlli(tlli, GPRS_RLCMAC_DL_TBF); + return bts->tbf_by_tlli(tlli, GPRS_RLCMAC_DL_TBF); } static int tbf_append_data(struct gprs_rlcmac_tbf *tbf, @@ -121,7 +122,7 @@ static int tbf_new_dl_assignment(struct gprs_rlcmac_bts *bts, /* check for uplink data, so we copy our informations */ #warning "Do the same look up for IMSI, TLLI and OLD_TLLI" #warning "Refactor the below lines... into a new method" - tbf = tbf_by_tlli(tlli, GPRS_RLCMAC_UL_TBF); + tbf = bts->bts->tbf_by_tlli(tlli, GPRS_RLCMAC_UL_TBF); if (tbf && tbf->dir.ul.contention_resolution_done && !tbf->dir.ul.final_ack_sent) { use_trx = tbf->trx_no; @@ -196,7 +197,7 @@ int tbf_handle(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *tbf; /* check for existing TBF */ - tbf = tbf_lookup_dl(tlli, imsi); + tbf = tbf_lookup_dl(bts->bts, tlli, imsi); if (tbf) { int rc = tbf_append_data(tbf, bts, ms_class, delay_csec, data, len); @@ -274,9 +275,9 @@ void tbf_free(struct gprs_rlcmac_tbf *tbf) gprs_rlcmac_rssi_rep(tbf); gprs_rlcmac_lost_rep(tbf); - debug_diagram(tbf->diag, "+---------------+"); - debug_diagram(tbf->diag, "| THE END |"); - debug_diagram(tbf->diag, "+---------------+"); + debug_diagram(tbf->bts, tbf->diag, "+---------------+"); + debug_diagram(tbf->bts, tbf->diag, "| THE END |"); + debug_diagram(tbf->bts, tbf->diag, "+---------------+"); LOGP(DRLCMAC, LOGL_INFO, "Free %s TBF=%d with TLLI=0x%08x.\n", (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi, tbf->tlli); @@ -315,7 +316,7 @@ int tbf_update(struct gprs_rlcmac_tbf *tbf) return -EINVAL; } - ul_tbf = tbf_by_tlli(tbf->tlli, GPRS_RLCMAC_UL_TBF); + ul_tbf = bts->bts->tbf_by_tlli(tbf->tlli, GPRS_RLCMAC_UL_TBF); tbf_unlink_pdch(tbf); rc = bts->alloc_algorithm(bts, ul_tbf, tbf, bts->alloc_algorithm_curst, 0); @@ -353,7 +354,7 @@ static const char *tbf_state_name[] = { void tbf_new_state(struct gprs_rlcmac_tbf *tbf, enum gprs_rlcmac_tbf_state state) { - debug_diagram(tbf->diag, "->%s", tbf_state_name[state]); + debug_diagram(tbf->bts, tbf->diag, "->%s", tbf_state_name[state]); LOGP(DRLCMAC, LOGL_DEBUG, "%s TBF=%d changes state from %s to %s\n", (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi, tbf_state_name[tbf->state], tbf_state_name[state]); @@ -415,50 +416,6 @@ struct gprs_rlcmac_tbf *tbf_by_tfi(struct gprs_rlcmac_bts *bts, return NULL; } -/* search for active downlink or uplink tbf */ -struct gprs_rlcmac_tbf *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, &gprs_rlcmac_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, &gprs_rlcmac_dl_tbfs, list) { - if (tbf->state_is_not(GPRS_RLCMAC_RELEASING) - && tbf->tlli == tlli) - return tbf; - } - } - return NULL; -} - -struct gprs_rlcmac_tbf *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, &gprs_rlcmac_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, &gprs_rlcmac_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; -} - struct gprs_rlcmac_tbf *tbf_alloc(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *old_tbf, enum gprs_rlcmac_tbf_direction dir, uint8_t tfi, uint8_t trx, @@ -471,11 +428,11 @@ struct gprs_rlcmac_tbf *tbf_alloc(struct gprs_rlcmac_bts *bts, /* hunt for first free number in diagram */ int diagram_num; for (diagram_num = 0; ; diagram_num++) { - llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) { + llist_for_each_entry(tbf, &bts->ul_tbfs, list) { if (tbf->diag == diagram_num) goto next_diagram; } - llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { + llist_for_each_entry(tbf, &bts->dl_tbfs, list) { if (tbf->diag == diagram_num) goto next_diagram; } @@ -533,14 +490,14 @@ next_diagram: INIT_LLIST_HEAD(&tbf->llc_queue); if (dir == GPRS_RLCMAC_UL_TBF) - llist_add(&tbf->list, &gprs_rlcmac_ul_tbfs); + llist_add(&tbf->list, &bts->ul_tbfs); else - llist_add(&tbf->list, &gprs_rlcmac_dl_tbfs); + llist_add(&tbf->list, &bts->dl_tbfs); - debug_diagram(tbf->diag, "+-----------------+"); - debug_diagram(tbf->diag, "|NEW %s TBF TFI=%2d|", + debug_diagram(bts->bts, tbf->diag, "+-----------------+"); + debug_diagram(bts->bts, tbf->diag, "|NEW %s TBF TFI=%2d|", (dir == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tfi); - debug_diagram(tbf->diag, "+-----------------+"); + debug_diagram(bts->bts, tbf->diag, "+-----------------+"); return tbf; } @@ -591,7 +548,7 @@ void tbf_timer_cb(void *_tbf) /* fall through */ case 3193: if (tbf->T == 3193) - debug_diagram(tbf->diag, "T3193 timeout"); + debug_diagram(tbf->bts, tbf->diag, "T3193 timeout"); LOGP(DRLCMAC, LOGL_DEBUG, "TBF will be freed due to timeout\n"); /* free TBF */ tbf_free(tbf); @@ -19,7 +19,6 @@ #pragma once #include "gprs_rlcmac.h" -#include "bts.h" #include <stdint.h> @@ -82,10 +81,6 @@ enum gprs_rlcmac_tbf_direction { #define GPRS_RLCMAC_FLAG_TO_DL_ASS 7 #define GPRS_RLCMAC_FLAG_TO_MASK 0xf0 /* timeout bits */ -extern struct llist_head gprs_rlcmac_ul_tbfs; /* list of uplink TBFs */ -extern struct llist_head gprs_rlcmac_dl_tbfs; /* list of downlink TBFs */ - - struct gprs_rlcmac_tbf { static void free_all(struct gprs_rlcmac_trx *trx); @@ -222,11 +217,6 @@ struct gprs_rlcmac_tbf *tbf_by_tfi(struct gprs_rlcmac_bts *bts, uint8_t tfi, uint8_t trx, enum gprs_rlcmac_tbf_direction dir); -struct gprs_rlcmac_tbf *tbf_by_tlli(uint32_t tlli, - enum gprs_rlcmac_tbf_direction dir); - -struct gprs_rlcmac_tbf *tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts); - void tbf_free(struct gprs_rlcmac_tbf *tbf); int tbf_update(struct gprs_rlcmac_tbf *tbf); diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp index 2117b11a..281ac652 100644 --- a/tests/alloc/AllocTest.cpp +++ b/tests/alloc/AllocTest.cpp @@ -20,6 +20,7 @@ #include "gprs_rlcmac.h" #include "gprs_debug.h" #include "tbf.h" +#include "bts.h" #include <string.h> #include <stdio.h> @@ -39,15 +40,16 @@ static void test_alloc_a(gprs_rlcmac_tbf_direction dir, const int count) { int tfi; uint8_t used_trx; - struct gprs_rlcmac_bts bts; + BTS the_bts; + struct gprs_rlcmac_bts *bts; struct gprs_rlcmac_tbf *tbfs[33] = { 0, }; printf("Testing alloc_a direction(%d)\n", dir); - memset(&bts, 0, sizeof(bts)); - bts.alloc_algorithm = alloc_algorithm_a; + bts = the_bts.bts_data(); + bts->alloc_algorithm = alloc_algorithm_a; - struct gprs_rlcmac_trx *trx = &bts.trx[0]; + struct gprs_rlcmac_trx *trx = &bts->trx[0]; trx->pdch[2].enable(); trx->pdch[3].enable(); @@ -60,13 +62,13 @@ static void test_alloc_a(gprs_rlcmac_tbf_direction dir, const int count) for (int i = 0; i < count; ++i) { struct gprs_rlcmac_tbf *tbf; - tfi = tfi_find_free(&bts, dir, &used_trx, 0); + tfi = tfi_find_free(bts, dir, &used_trx, 0); OSMO_ASSERT(tfi >= 0); - tbfs[i] = tbf_alloc(&bts, NULL, dir, tfi, used_trx, 0, 0); + tbfs[i] = tbf_alloc(bts, NULL, dir, tfi, used_trx, 0, 0); } /* Now check that there are still some TFIs */ - tfi = tfi_find_free(&bts, dir, &used_trx, 0); + tfi = tfi_find_free(bts, dir, &used_trx, 0); switch (dir) { case GPRS_RLCMAC_UL_TBF: OSMO_ASSERT(tfi >= 0); @@ -75,16 +77,16 @@ static void test_alloc_a(gprs_rlcmac_tbf_direction dir, const int count) OSMO_ASSERT(tfi < 0); break; } - OSMO_ASSERT(!tbf_alloc(&bts, NULL, dir, tfi, used_trx, 0, 0)); + OSMO_ASSERT(!tbf_alloc(bts, NULL, dir, tfi, used_trx, 0, 0)); for (int i = 0; i < ARRAY_SIZE(tbfs); ++i) if (tbfs[i]) tbf_free(tbfs[i]); - tfi = tfi_find_free(&bts, dir, &used_trx, 0); + tfi = tfi_find_free(bts, dir, &used_trx, 0); OSMO_ASSERT(tfi >= 0); - tbfs[tfi] = tbf_alloc(&bts, NULL, dir, tfi, used_trx, 0, 0); + tbfs[tfi] = tbf_alloc(bts, NULL, dir, tfi, used_trx, 0, 0); OSMO_ASSERT(tbfs[tfi]); tbf_free(tbfs[tfi]); } |