diff options
author | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2013-10-16 18:09:19 +0200 |
---|---|---|
committer | Ivan Kluchnikov <kluchnikovi@gmail.com> | 2013-10-28 12:53:49 +0400 |
commit | 7380babdba39faa090e5dff442e2afbeec202c16 (patch) | |
tree | 823f3d948455e1b31136c61936d4467461f4b71f /src | |
parent | 0946f99b08f0f8dd08f42be4e9b2ed0b70e8500b (diff) |
tbf: Move the tbf_timer_cb into the tbf class
Introduce the first instance method for printing out diagonistic
about itself and create a jump function for it.
Diffstat (limited to 'src')
-rw-r--r-- | src/gprs_rlcmac.cpp | 150 | ||||
-rw-r--r-- | src/gprs_rlcmac.h | 2 | ||||
-rw-r--r-- | src/gprs_rlcmac_data.cpp | 72 | ||||
-rw-r--r-- | src/tbf.cpp | 227 | ||||
-rw-r--r-- | src/tbf.h | 3 |
5 files changed, 231 insertions, 223 deletions
diff --git a/src/gprs_rlcmac.cpp b/src/gprs_rlcmac.cpp index 8841445d..9b4e6436 100644 --- a/src/gprs_rlcmac.cpp +++ b/src/gprs_rlcmac.cpp @@ -253,156 +253,6 @@ static inline int8_t find_free_usf(struct gprs_rlcmac_pdch *pdch, uint8_t ts) return -1; } -/* lookup TBF Entity (by TFI) */ -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; - - if (tfi >= 32 || trx >= 8) - return NULL; - - if (dir == GPRS_RLCMAC_UL_TBF) - tbf = bts->trx[trx].ul_tbf[tfi]; - else - tbf = bts->trx[trx].dl_tbf[tfi]; - if (!tbf) - return NULL; - - if (tbf->state != GPRS_RLCMAC_RELEASING) - return tbf; - - 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 != 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 != 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 != GPRS_RLCMAC_RELEASING - && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED - && tbf->poll_fn == fn && tbf->trx == trx - && tbf->control_ts == ts) - return tbf; - } - llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { - if (tbf->state != GPRS_RLCMAC_RELEASING - && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED - && tbf->poll_fn == fn && tbf->trx == 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, - uint8_t ms_class, uint8_t single_slot) -{ - struct gprs_rlcmac_tbf *tbf; - int rc; - -#ifdef DEBUG_DIAGRAM - /* 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) { - if (tbf->diag == diagram_num) - goto next_diagram; - } - llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { - if (tbf->diag == diagram_num) - goto next_diagram; - } - break; -next_diagram: - continue; - } -#endif - - LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF starts here **********\n"); - LOGP(DRLCMAC, LOGL_INFO, "Allocating %s TBF: TFI=%d TRX=%d " - "MS_CLASS=%d\n", (dir == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", - tfi, trx, ms_class); - - if (trx >= 8 || tfi >= 32) - return NULL; - - tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_tbf); - if (!tbf) - return NULL; - -#ifdef DEBUG_DIAGRAM - tbf->diag = diagram_num; -#endif - tbf->direction = dir; - tbf->tfi = tfi; - tbf->trx = trx; - tbf->arfcn = bts->trx[trx].arfcn; - tbf->ms_class = ms_class; - tbf->ws = 64; - tbf->sns = 128; - /* select algorithm */ - rc = bts->alloc_algorithm(bts, old_tbf, tbf, bts->alloc_algorithm_curst, - single_slot); - /* if no ressource */ - if (rc < 0) { - talloc_free(tbf); - return NULL; - } - /* assign control ts */ - tbf->control_ts = 0xff; - rc = tbf_assign_control_ts(tbf); - /* if no ressource */ - if (rc < 0) { - talloc_free(tbf); - return NULL; - } - - /* set timestamp */ - gettimeofday(&tbf->meas.dl_bw_tv, NULL); - gettimeofday(&tbf->meas.rssi_tv, NULL); - gettimeofday(&tbf->meas.dl_loss_tv, NULL); - - INIT_LLIST_HEAD(&tbf->llc_queue); - if (dir == GPRS_RLCMAC_UL_TBF) - llist_add(&tbf->list, &gprs_rlcmac_ul_tbfs); - else - llist_add(&tbf->list, &gprs_rlcmac_dl_tbfs); - - debug_diagram(tbf->diag, "+-----------------+"); - debug_diagram(tbf->diag, "|NEW %s TBF TFI=%2d|", - (dir == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tfi); - debug_diagram(tbf->diag, "+-----------------+"); - - return tbf; -} - /* Slot Allocation: Algorithm A * * Assign single slot for uplink and downlink diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h index a40ebd6a..8863af47 100644 --- a/src/gprs_rlcmac.h +++ b/src/gprs_rlcmac.h @@ -183,8 +183,6 @@ void write_packet_uplink_ack(RlcMacDownlink_t * block, struct gprs_rlcmac_tbf *t int gprs_rlcmac_tx_ul_ud(gprs_rlcmac_tbf *tbf); -void tbf_timer_cb(void *_tbf); - int gprs_rlcmac_poll_timeout(struct gprs_rlcmac_tbf *tbf); int gprs_rlcmac_sba_timeout(struct gprs_rlcmac_sba *sba); diff --git a/src/gprs_rlcmac_data.cpp b/src/gprs_rlcmac_data.cpp index bc55c574..b5ea7c9b 100644 --- a/src/gprs_rlcmac_data.cpp +++ b/src/gprs_rlcmac_data.cpp @@ -79,20 +79,7 @@ static void gprs_rlcmac_downlink_assignment(gprs_rlcmac_tbf *tbf, uint8_t poll, static int gprs_rlcmac_diag(struct gprs_rlcmac_tbf *tbf) { - if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) - LOGP(DRLCMAC, LOGL_NOTICE, "- Assignment was on CCCH\n"); - if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH))) - LOGP(DRLCMAC, LOGL_NOTICE, "- Assignment was on PACCH\n"); - if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_UL_DATA))) - LOGP(DRLCMAC, LOGL_NOTICE, "- Uplink data was received\n"); - else if (tbf->direction == GPRS_RLCMAC_UL_TBF) - LOGP(DRLCMAC, LOGL_NOTICE, "- No uplink data received yet\n"); - if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_DL_ACK))) - LOGP(DRLCMAC, LOGL_NOTICE, "- Downlink ACK was received\n"); - else if (tbf->direction == GPRS_RLCMAC_DL_TBF) - LOGP(DRLCMAC, LOGL_NOTICE, "- No downlink ACK received yet\n"); - - return 0; + return tbf->rlcmac_diag(); } int gprs_rlcmac_poll_timeout(struct gprs_rlcmac_tbf *tbf) @@ -487,63 +474,6 @@ int gprs_rlcmac_rcv_control_block(bitvec *rlc_block, uint8_t trx, uint8_t ts, char debug_imsi[16]; #endif -void tbf_timer_cb(void *_tbf) -{ - struct gprs_rlcmac_tbf *tbf = (struct gprs_rlcmac_tbf *)_tbf; - - LOGP(DRLCMAC, LOGL_DEBUG, "%s TBF=%d timer %u expired.\n", - (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi, - tbf->T); - - tbf->num_T_exp++; - - switch (tbf->T) { -#ifdef DEBUG_DL_ASS_IDLE - case 1234: - gprs_rlcmac_trigger_downlink_assignment(tbf, NULL, debug_imsi); - break; -#endif - case 0: /* assignment */ - if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH))) { - if (tbf->state == GPRS_RLCMAC_ASSIGN) { - LOGP(DRLCMAC, LOGL_NOTICE, "Releasing due to " - "PACCH assignment timeout.\n"); - tbf_free(tbf); - } else - LOGP(DRLCMAC, LOGL_ERROR, "Error: TBF is not " - "in assign state\n"); - } - if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) { - /* change state to FLOW, so scheduler will start transmission */ - tbf->dir.dl.wait_confirm = 0; - if (tbf->state == GPRS_RLCMAC_ASSIGN) { - tbf_new_state(tbf, GPRS_RLCMAC_FLOW); - tbf_assign_control_ts(tbf); - } else - LOGP(DRLCMAC, LOGL_NOTICE, "Continue flow after " - "IMM.ASS confirm\n"); - } - break; - case 3169: - case 3191: - case 3195: - LOGP(DRLCMAC, LOGL_NOTICE, "TBF T%d timeout during " - "transsmission\n", tbf->T); - gprs_rlcmac_diag(tbf); - /* fall through */ - case 3193: - if (tbf->T == 3193) - debug_diagram(tbf->diag, "T3193 timeout"); - LOGP(DRLCMAC, LOGL_DEBUG, "TBF will be freed due to timeout\n"); - /* free TBF */ - tbf_free(tbf); - break; - default: - LOGP(DRLCMAC, LOGL_ERROR, "Timer expired in unknown mode: %u\n", - tbf->T); - } -} - /* * UL data block flow */ diff --git a/src/tbf.cpp b/src/tbf.cpp index b93d0f1e..918520c7 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -31,6 +31,8 @@ extern "C" { #include <errno.h> #include <string.h> +extern void *tall_pcu_ctx; + static inline void tbf_update_ms_class(struct gprs_rlcmac_tbf *tbf, const uint8_t ms_class) { @@ -391,6 +393,231 @@ void tbf_timer_stop(struct gprs_rlcmac_tbf *tbf) } } +/* lookup TBF Entity (by TFI) */ +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; + + if (tfi >= 32 || trx >= 8) + return NULL; + + if (dir == GPRS_RLCMAC_UL_TBF) + tbf = bts->trx[trx].ul_tbf[tfi]; + else + tbf = bts->trx[trx].dl_tbf[tfi]; + if (!tbf) + return NULL; + + if (tbf->state != GPRS_RLCMAC_RELEASING) + return tbf; + + 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 != 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 != 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 != GPRS_RLCMAC_RELEASING + && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED + && tbf->poll_fn == fn && tbf->trx == trx + && tbf->control_ts == ts) + return tbf; + } + llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { + if (tbf->state != GPRS_RLCMAC_RELEASING + && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED + && tbf->poll_fn == fn && tbf->trx == 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, + uint8_t ms_class, uint8_t single_slot) +{ + struct gprs_rlcmac_tbf *tbf; + int rc; + +#ifdef DEBUG_DIAGRAM + /* 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) { + if (tbf->diag == diagram_num) + goto next_diagram; + } + llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { + if (tbf->diag == diagram_num) + goto next_diagram; + } + break; +next_diagram: + continue; + } +#endif + + LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF starts here **********\n"); + LOGP(DRLCMAC, LOGL_INFO, "Allocating %s TBF: TFI=%d TRX=%d " + "MS_CLASS=%d\n", (dir == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", + tfi, trx, ms_class); + + if (trx >= 8 || tfi >= 32) + return NULL; + + tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_tbf); + if (!tbf) + return NULL; + +#ifdef DEBUG_DIAGRAM + tbf->diag = diagram_num; +#endif + tbf->direction = dir; + tbf->tfi = tfi; + tbf->trx = trx; + tbf->arfcn = bts->trx[trx].arfcn; + tbf->ms_class = ms_class; + tbf->ws = 64; + tbf->sns = 128; + /* select algorithm */ + rc = bts->alloc_algorithm(bts, old_tbf, tbf, bts->alloc_algorithm_curst, + single_slot); + /* if no ressource */ + if (rc < 0) { + talloc_free(tbf); + return NULL; + } + /* assign control ts */ + tbf->control_ts = 0xff; + rc = tbf_assign_control_ts(tbf); + /* if no ressource */ + if (rc < 0) { + talloc_free(tbf); + return NULL; + } + + /* set timestamp */ + gettimeofday(&tbf->meas.dl_bw_tv, NULL); + gettimeofday(&tbf->meas.rssi_tv, NULL); + gettimeofday(&tbf->meas.dl_loss_tv, NULL); + + INIT_LLIST_HEAD(&tbf->llc_queue); + if (dir == GPRS_RLCMAC_UL_TBF) + llist_add(&tbf->list, &gprs_rlcmac_ul_tbfs); + else + llist_add(&tbf->list, &gprs_rlcmac_dl_tbfs); + + debug_diagram(tbf->diag, "+-----------------+"); + debug_diagram(tbf->diag, "|NEW %s TBF TFI=%2d|", + (dir == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tfi); + debug_diagram(tbf->diag, "+-----------------+"); + + return tbf; +} + +void tbf_timer_cb(void *_tbf) +{ + struct gprs_rlcmac_tbf *tbf = (struct gprs_rlcmac_tbf *)_tbf; + + LOGP(DRLCMAC, LOGL_DEBUG, "%s TBF=%d timer %u expired.\n", + (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi, + tbf->T); + + tbf->num_T_exp++; + + switch (tbf->T) { +#ifdef DEBUG_DL_ASS_IDLE + case 1234: + gprs_rlcmac_trigger_downlink_assignment(tbf, NULL, debug_imsi); + break; +#endif + case 0: /* assignment */ + if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH))) { + if (tbf->state == GPRS_RLCMAC_ASSIGN) { + LOGP(DRLCMAC, LOGL_NOTICE, "Releasing due to " + "PACCH assignment timeout.\n"); + tbf_free(tbf); + } else + LOGP(DRLCMAC, LOGL_ERROR, "Error: TBF is not " + "in assign state\n"); + } + if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) { + /* change state to FLOW, so scheduler will start transmission */ + tbf->dir.dl.wait_confirm = 0; + if (tbf->state == GPRS_RLCMAC_ASSIGN) { + tbf_new_state(tbf, GPRS_RLCMAC_FLOW); + tbf_assign_control_ts(tbf); + } else + LOGP(DRLCMAC, LOGL_NOTICE, "Continue flow after " + "IMM.ASS confirm\n"); + } + break; + case 3169: + case 3191: + case 3195: + LOGP(DRLCMAC, LOGL_NOTICE, "TBF T%d timeout during " + "transsmission\n", tbf->T); + tbf->rlcmac_diag(); + /* fall through */ + case 3193: + if (tbf->T == 3193) + debug_diagram(tbf->diag, "T3193 timeout"); + LOGP(DRLCMAC, LOGL_DEBUG, "TBF will be freed due to timeout\n"); + /* free TBF */ + tbf_free(tbf); + break; + default: + LOGP(DRLCMAC, LOGL_ERROR, "Timer expired in unknown mode: %u\n", + tbf->T); + } +} + +int gprs_rlcmac_tbf::rlcmac_diag() +{ + if ((state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) + LOGP(DRLCMAC, LOGL_NOTICE, "- Assignment was on CCCH\n"); + if ((state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH))) + LOGP(DRLCMAC, LOGL_NOTICE, "- Assignment was on PACCH\n"); + if ((state_flags & (1 << GPRS_RLCMAC_FLAG_UL_DATA))) + LOGP(DRLCMAC, LOGL_NOTICE, "- Uplink data was received\n"); + else if (direction == GPRS_RLCMAC_UL_TBF) + LOGP(DRLCMAC, LOGL_NOTICE, "- No uplink data received yet\n"); + if ((state_flags & (1 << GPRS_RLCMAC_FLAG_DL_ACK))) + LOGP(DRLCMAC, LOGL_NOTICE, "- Downlink ACK was received\n"); + else if (direction == GPRS_RLCMAC_DL_TBF) + LOGP(DRLCMAC, LOGL_NOTICE, "- No downlink ACK received yet\n"); + + return 0; +} + void gprs_rlcmac_tbf::free_all(struct gprs_rlcmac_trx *trx) { for (uint8_t tfi = 0; tfi < 32; tfi++) { @@ -91,6 +91,7 @@ struct gprs_rlcmac_tbf { static void free_all(struct gprs_rlcmac_trx *trx); static void free_all(struct gprs_rlcmac_pdch *pdch); + int rlcmac_diag(); struct llist_head list; enum gprs_rlcmac_tbf_state state; @@ -229,3 +230,5 @@ void tbf_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int T, void tbf_timer_stop(struct gprs_rlcmac_tbf *tbf); +void tbf_timer_cb(void *_tbf); + |