diff options
author | Pau Espin Pedrol <pespin@sysmocom.de> | 2023-06-23 14:47:26 +0200 |
---|---|---|
committer | Pau Espin Pedrol <pespin@sysmocom.de> | 2023-06-29 14:42:33 +0200 |
commit | 5f3177eb414632e140675ea8eac9bf5af38cc1b2 (patch) | |
tree | 73e837950547db76f137ee9fc5af9ae6623be083 /src | |
parent | 061fbca2a9e6e374ff25a22799e500298d841934 (diff) |
tbf_ul_fsm: Delay moving ul_tbf to FLOW
Otherwise the scheduler selects the UL TBF for USF during that time, and
of course no one has that USF assigned yet, so no answer and that ends
up triggering MAX_N3101 on the UL TBF.
This is specially important when PCU is connected to the BSC, since the
amount of time for the ImmAss to be scheduled on the BTS and reach the
MS can be bigger.
Change-Id: I48babd70ca44f11110240cbcfbab43d0e3a0fb59
Diffstat (limited to 'src')
-rw-r--r-- | src/tbf_ul_fsm.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/src/tbf_ul_fsm.c b/src/tbf_ul_fsm.c index a26d1618..49849ba3 100644 --- a/src/tbf_ul_fsm.c +++ b/src/tbf_ul_fsm.c @@ -89,7 +89,7 @@ static void st_new(struct osmo_fsm_inst *fi, uint32_t event, void *data) switch (event) { case TBF_EV_ASSIGN_ADD_CCCH: mod_ass_type(ctx, GPRS_RLCMAC_FLAG_CCCH, true); - tbf_ul_fsm_state_chg(fi, TBF_ST_FLOW); + tbf_ul_fsm_state_chg(fi, TBF_ST_ASSIGN); ul_tbf_contention_resolution_start(ctx->ul_tbf); break; case TBF_EV_ASSIGN_ADD_PACCH: @@ -126,6 +126,22 @@ static void st_assign_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) "Starting timer T3168 [UL TBF Ass (PACCH)] with %u sec. %u microsec\n", sec, micro); osmo_timer_schedule(&fi->timer, sec, micro); + } else if (ctx->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH)) { + /* Wait a bit for the AGCH ImmAss[PktUlAss] sent BSC->BTS to + * arrive at the MS, and for the MS to jump and starting + * listening on USFs in the assigned PDCH. + * Ideally we would first wait for TBF_EV_ASSIGN_PCUIF_CNF to + * account for queueing time, but that's only sent for data on PCH + * so far, while ImmAss for UL TBF is sent on AGCH. + */ + fi->T = -2002; + val = osmo_tdef_get(the_pcu->T_defs, fi->T, OSMO_TDEF_MS, -1); + sec = val / 1000; + micro = (val % 1000) * 1000; + LOGPTBFUL(ctx->ul_tbf, LOGL_DEBUG, + "Starting timer X2002 [assignment (AGCH)] with %u sec. %u microsec\n", + sec, micro); + osmo_timer_schedule(&fi->timer, sec, micro); } } @@ -152,6 +168,10 @@ static void st_assign(struct osmo_fsm_inst *fi, uint32_t event, void *data) } tbf_ul_fsm_state_chg(fi, TBF_ST_FLOW); break; + case TBF_EV_ASSIGN_READY_CCCH: + /* change state to FLOW, so scheduler will start requesting USF */ + tbf_ul_fsm_state_chg(fi, TBF_ST_FLOW); + break; default: OSMO_ASSERT(0); } @@ -259,6 +279,9 @@ static int tbf_ul_fsm_timer_cb(struct osmo_fsm_inst *fi) { struct tbf_ul_fsm_ctx *ctx = (struct tbf_ul_fsm_ctx *)fi->priv; switch (fi->T) { + case -2002: + osmo_fsm_inst_dispatch(fi, TBF_EV_ASSIGN_READY_CCCH, NULL); + break; case 3168: LOGPTBFUL(ctx->ul_tbf, LOGL_NOTICE, "Releasing due to UL TBF PACCH assignment timeout\n"); /* fall-through */ @@ -286,7 +309,8 @@ static struct osmo_fsm_state tbf_ul_fsm_states[] = { .in_event_mask = X(TBF_EV_ASSIGN_ADD_CCCH) | X(TBF_EV_ASSIGN_ADD_PACCH) | - X(TBF_EV_ASSIGN_ACK_PACCH), + X(TBF_EV_ASSIGN_ACK_PACCH) | + X(TBF_EV_ASSIGN_READY_CCCH), .out_state_mask = X(TBF_ST_FLOW) | X(TBF_ST_FINISHED), |