aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2012-08-07 15:48:21 +0200
committerAndreas Eversberg <jolly@eversberg.eu>2012-08-07 15:48:21 +0200
commitcbcd124588abf91be129aee3f37505ca60706de9 (patch)
treed3a40c1cbc4aa8eb46c8ca944191cf3401996ccc
parent309ce743767d321565d8c63f0d78563154db3cd9 (diff)
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.
-rw-r--r--src/gprs_rlcmac.h3
-rw-r--r--src/gprs_rlcmac_data.cpp32
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);