diff --git a/src/tbf.cpp b/src/tbf.cpp index c68d5051..107c867d 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -93,10 +93,8 @@ static const struct value_string tbf_counters_names[] = { static const struct value_string tbf_timers_names[] = { OSMO_VALUE_STRING(T0), OSMO_VALUE_STRING(T3141), - OSMO_VALUE_STRING(T3169), OSMO_VALUE_STRING(T3191), OSMO_VALUE_STRING(T3193), - OSMO_VALUE_STRING(T3195), { 0, NULL } }; @@ -475,10 +473,8 @@ static inline void tbf_timeout_free(struct gprs_rlcmac_tbf *tbf, enum tbf_timers * allocated temporary block flow is released as specified in 3GPP TS 44.060 and * the packet access is forgotten.*/ T_CBACK(T3141, true) -T_CBACK(T3169, true) T_CBACK(T3191, true) T_CBACK(T3193, false) -T_CBACK(T3195, true) void gprs_rlcmac_tbf::t_start(enum tbf_timers t, int T, const char *reason, bool force, const char *file, unsigned line) @@ -527,18 +523,12 @@ void gprs_rlcmac_tbf::t_start(enum tbf_timers t, int T, const char *reason, bool case T3141: Tarr[t].cb = cb_T3141; break; - case T3169: - Tarr[t].cb = cb_T3169; - break; case T3191: Tarr[t].cb = cb_T3191; break; case T3193: Tarr[t].cb = cb_T3193; break; - case T3195: - Tarr[t].cb = cb_T3195; - break; default: LOGPSRC(DTBF, LOGL_ERROR, file, line, "%s attempting to set callback for unknown timer %s [%s], cur_fn=%d\n", tbf_name(this), get_value_string(tbf_timers_names, t), reason, current_fn); @@ -641,7 +631,6 @@ void gprs_rlcmac_tbf::poll_timeout(struct gprs_rlcmac_pdch *pdch, uint32_t poll_ if (ul_tbf->n_inc(N3103)) { bts_do_rate_ctr_inc(bts, CTR_PUAN_POLL_FAILED); osmo_fsm_inst_dispatch(this->state_fsm.fi, TBF_EV_MAX_N3103, NULL); - T_START(ul_tbf, T3169, 3169, "MAX N3103 reached", false); return; } /* reschedule UL ack */ @@ -660,7 +649,6 @@ void gprs_rlcmac_tbf::poll_timeout(struct gprs_rlcmac_pdch *pdch, uint32_t poll_ bts_do_rate_ctr_inc(bts, CTR_PUA_POLL_TIMEDOUT); if (n_inc(N3105)) { osmo_fsm_inst_dispatch(this->state_fsm.fi, TBF_EV_MAX_N3105, NULL); - T_START(this, T3195, 3195, "MAX N3105 reached", true); bts_do_rate_ctr_inc(bts, CTR_RLC_ASS_FAILED); bts_do_rate_ctr_inc(bts, CTR_PUA_POLL_FAILED); return; @@ -679,7 +667,6 @@ void gprs_rlcmac_tbf::poll_timeout(struct gprs_rlcmac_pdch *pdch, uint32_t poll_ bts_do_rate_ctr_inc(bts, CTR_PDA_POLL_TIMEDOUT); if (n_inc(N3105)) { osmo_fsm_inst_dispatch(this->state_fsm.fi, TBF_EV_MAX_N3105, NULL); - T_START(this, T3195, 3195, "MAX N3105 reached", true); bts_do_rate_ctr_inc(bts, CTR_RLC_ASS_FAILED); bts_do_rate_ctr_inc(bts, CTR_PDA_POLL_FAILED); return; @@ -710,7 +697,6 @@ void gprs_rlcmac_tbf::poll_timeout(struct gprs_rlcmac_pdch *pdch, uint32_t poll_ if (dl_tbf->n_inc(N3105)) { osmo_fsm_inst_dispatch(this->state_fsm.fi, TBF_EV_MAX_N3105, NULL); - T_START(dl_tbf, T3195, 3195, "MAX N3105 reached", true); bts_do_rate_ctr_inc(bts, CTR_PDAN_POLL_FAILED); bts_do_rate_ctr_inc(bts, CTR_RLC_ACK_FAILED); return; diff --git a/src/tbf.h b/src/tbf.h index ded3a3c3..6c33bc2a 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -121,9 +121,6 @@ enum tbf_timers { /* Wait contention resolution success on UL TBFs assigned over CCCH */ T3141, - /* Wait for reuse of USF and TFI(s) after the MS uplink assignment for this TBF is invalid. */ - T3169, - /* Wait for reuse of TFI(s) after sending of the last RLC Data Block on this TBF. Wait for reuse of TFI(s) after sending the PACKET TBF RELEASE for an MBMS radio bearer. */ T3191, @@ -132,9 +129,6 @@ enum tbf_timers { MS for this TBF. */ T3193, - /* Wait for reuse of TFI(s) when there is no response from the MS - (radio failure or cell change) for this TBF/MBMS radio bearer. */ - T3195, T_MAX }; diff --git a/src/tbf_fsm.c b/src/tbf_fsm.c index 1ba1d616..a57dd085 100644 --- a/src/tbf_fsm.c +++ b/src/tbf_fsm.c @@ -145,6 +145,7 @@ static void st_assign(struct osmo_fsm_inst *fi, uint32_t event, void *data) static void st_flow(struct osmo_fsm_inst *fi, uint32_t event, void *data) { + struct tbf_fsm_ctx *ctx = (struct tbf_fsm_ctx *)fi->priv; switch (event) { case TBF_EV_LAST_DL_DATA_SENT: case TBF_EV_LAST_UL_DATA_RECVD: @@ -158,7 +159,11 @@ static void st_flow(struct osmo_fsm_inst *fi, uint32_t event, void *data) tbf_fsm_state_chg(fi, TBF_ST_WAIT_RELEASE); break; case TBF_EV_MAX_N3101: + ctx->T_release = 3169; + tbf_fsm_state_chg(fi, TBF_ST_RELEASING); + break; case TBF_EV_MAX_N3105: + ctx->T_release = 3195; tbf_fsm_state_chg(fi, TBF_ST_RELEASING); break; default: @@ -168,7 +173,7 @@ static void st_flow(struct osmo_fsm_inst *fi, uint32_t event, void *data) static void st_finished(struct osmo_fsm_inst *fi, uint32_t event, void *data) { - //struct tbf_fsm_ctx *ctx = (struct tbf_fsm_ctx *)fi->priv; + struct tbf_fsm_ctx *ctx = (struct tbf_fsm_ctx *)fi->priv; switch (event) { case TBF_EV_FINAL_ACK_RECVD: /* We received Final Ack (DL ACK/NACK) from MS. move to @@ -177,9 +182,11 @@ static void st_finished(struct osmo_fsm_inst *fi, uint32_t event, void *data) tbf_fsm_state_chg(fi, TBF_ST_WAIT_RELEASE); break; case TBF_EV_MAX_N3103: + ctx->T_release = 3169; tbf_fsm_state_chg(fi, TBF_ST_RELEASING); break; case TBF_EV_MAX_N3105: + ctx->T_release = 3195; tbf_fsm_state_chg(fi, TBF_ST_RELEASING); break; default: @@ -189,12 +196,17 @@ static void st_finished(struct osmo_fsm_inst *fi, uint32_t event, void *data) static void st_wait_release(struct osmo_fsm_inst *fi, uint32_t event, void *data) { + struct tbf_fsm_ctx *ctx = (struct tbf_fsm_ctx *)fi->priv; switch (event) { case TBF_EV_FINAL_ACK_RECVD: /* ignore, duplicate ACK, we already know about since we are in WAIT_RELEASE */ break; case TBF_EV_MAX_N3101: + ctx->T_release = 3169; + tbf_fsm_state_chg(fi, TBF_ST_RELEASING); + break; case TBF_EV_MAX_N3105: + ctx->T_release = 3195; tbf_fsm_state_chg(fi, TBF_ST_RELEASING); break; default: @@ -202,6 +214,26 @@ static void st_wait_release(struct osmo_fsm_inst *fi, uint32_t event, void *data } } +static void st_releasing_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct tbf_fsm_ctx *ctx = (struct tbf_fsm_ctx *)fi->priv; + unsigned long val; + + if (!ctx->T_release) + return; + + /* In general we should end up here with an assigned timer in ctx->T_release. Possible values are: + * T3195: Wait for reuse of TFI(s) when there is no response from the MS + * (radio failure or cell change) for this TBF/MBMS radio bearer. + * T3169: Wait for reuse of USF and TFI(s) after the MS uplink assignment for this TBF is invalid. + */ + val = osmo_tdef_get(tbf_ms(ctx->tbf)->bts->T_defs_bts, ctx->T_release, OSMO_TDEF_S, -1); + fi->T = ctx->T_release; + LOGPTBF(ctx->tbf, LOGL_DEBUG, "starting timer T%u with %lu sec. %u microsec\n", + ctx->T_release, val, 0); + osmo_timer_schedule(&fi->timer, val, 0); +} + static void tbf_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause) { /* TODO: needed ? @@ -211,9 +243,14 @@ static void tbf_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause c static int tbf_fsm_timer_cb(struct osmo_fsm_inst *fi) { + struct tbf_fsm_ctx *ctx = (struct tbf_fsm_ctx *)fi->priv; switch (fi->T) { - default: - break; + case 3169: + case 3195: + tbf_free(ctx->tbf); + break; + default: + OSMO_ASSERT(0); } return 0; } @@ -284,6 +321,7 @@ static struct osmo_fsm_state tbf_fsm_states[] = { .out_state_mask = 0, .name = "RELEASING", + .onenter = st_releasing_on_enter, }, }; diff --git a/src/tbf_fsm.h b/src/tbf_fsm.h index ae0d6aef..1874bc34 100644 --- a/src/tbf_fsm.h +++ b/src/tbf_fsm.h @@ -53,6 +53,7 @@ struct tbf_fsm_ctx { struct osmo_fsm_inst *fi; struct gprs_rlcmac_tbf* tbf; /* back pointer */ uint32_t state_flags; + unsigned int T_release; /* Timer to be used to end release: T3169 or T3195 */ }; extern const struct osmo_tdef_state_timeout tbf_fsm_timeouts[32]; diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp index a7a7c3e4..d4575a36 100644 --- a/src/tbf_ul.cpp +++ b/src/tbf_ul.cpp @@ -816,11 +816,8 @@ gprs_rlc_window *gprs_rlcmac_ul_tbf::window() void gprs_rlcmac_ul_tbf::usf_timeout() { - if (n_inc(N3101)) { + if (n_inc(N3101)) osmo_fsm_inst_dispatch(this->state_fsm.fi, TBF_EV_MAX_N3101, NULL); - T_START(this, T3169, 3169, "MAX N3101 reached", false); - return; - } } struct gprs_rlcmac_ul_tbf *as_ul_tbf(struct gprs_rlcmac_tbf *tbf) diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 62a3a51e..91b84594 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -3085,7 +3085,7 @@ PDCH(bts=0,trx=0,ts=7) Timeout for registered USF (FN=2654318): TBF(TFI=0 TLLI=0 TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) N3101 exceeded MAX (10) TBF(UL-TFI_0){FLOW}: Received Event MAX_N3101 TBF(UL-TFI_0){FLOW}: state_chg to RELEASING -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=RELEASING) starting timer T3169 [MAX N3101 reached] with 5 sec. 0 microsec, cur_fn=2654379 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=RELEASING) starting timer T3169 with 5 sec. 0 microsec PDCH(bts=0,trx=0,ts=7) Expiring FN=2654379 but previous FN=2654322 is still reserved! PDCH(bts=0,trx=0,ts=7) Timeout for registered USF (FN=2654322): TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=RELEASING) TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=RELEASING) N3101 10 => 11 (< MAX 10)