From cbcd124588abf91be129aee3f37505ca60706de9 Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Tue, 7 Aug 2012 15:48:21 +0200 Subject: [PATCH] Fix: Add timer for downlink TBF in assignment state This is required, since the UL TBF which is used to assign downlink TBF may be freed due to timeouts. --- src/gprs_rlcmac.h | 3 ++- src/gprs_rlcmac_data.cpp | 32 +++++++++++++++++++++++++------- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h index 6bdef6be..e1c8343f 100644 --- a/src/gprs_rlcmac.h +++ b/src/gprs_rlcmac.h @@ -93,7 +93,8 @@ extern struct gprs_rlcmac_bts *gprs_rlcmac_bts; #define RLC_MAX_WS 64 /* max window size */ #define RLC_MAX_LEN 54 /* CS-4 including spare bits */ -#define Tassign_agch 0,800000/* FIXME: we need a confirm from BTS */ +#define Tassign_agch 0,800000 /* FIXME: we need a confirm from BTS */ +#define Tassign_pacch 2,0 /* timeout for pacch assigment */ enum gprs_rlcmac_tbf_state { GPRS_RLCMAC_NULL = 0, /* new created TBF */ diff --git a/src/gprs_rlcmac_data.cpp b/src/gprs_rlcmac_data.cpp index d59153f7..a1bed3c6 100644 --- a/src/gprs_rlcmac_data.cpp +++ b/src/gprs_rlcmac_data.cpp @@ -247,6 +247,8 @@ int gprs_rlcmac_rcv_control_block(bitvec *rlc_block, uint8_t trx, uint8_t ts, break; } tbf_new_state(tbf, GPRS_RLCMAC_FLOW); + /* stop pending assignment timer */ + tbf_timer_stop(tbf); if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS))) { tbf->state_flags &= @@ -405,13 +407,24 @@ void tbf_timer_cb(void *_tbf) break; #endif case 0: /* assignment */ - /* change state to FLOW, so scheduler will start transmission */ - if (tbf->state == GPRS_RLCMAC_ASSIGN) { - tbf_new_state(tbf, GPRS_RLCMAC_FLOW); - tbf_assign_control_ts(tbf); - } else - LOGP(DRLCMAC, LOGL_ERROR, "Error: TBF is not in assign " - "state\n"); + 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 */ + if (tbf->state == GPRS_RLCMAC_ASSIGN) { + tbf_new_state(tbf, GPRS_RLCMAC_FLOW); + tbf_assign_control_ts(tbf); + } else + LOGP(DRLCMAC, LOGL_ERROR, "Error: TBF is not " + "in assign state\n"); + } break; case 3169: case 3191: @@ -1575,6 +1588,9 @@ struct msgb *gprs_rlcmac_send_packet_downlink_assignment( tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE; tbf_new_state(new_tbf, GPRS_RLCMAC_FLOW); tbf_assign_control_ts(new_tbf); + /* stop pending assignment timer */ + tbf_timer_stop(new_tbf); + } return msg; @@ -1623,6 +1639,8 @@ void gprs_rlcmac_trigger_downlink_assignment(struct gprs_rlcmac_tbf *tbf, /* change state */ tbf_new_state(tbf, GPRS_RLCMAC_ASSIGN); tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_PACCH); + /* start timer */ + tbf_timer_start(tbf, 0, Tassign_pacch); #endif } else { LOGP(DRLCMAC, LOGL_DEBUG, "Send dowlink assignment for TBF=%d on PCH, no TBF exist (IMSI=%s)\n", tbf->tfi, imsi);