aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2023-06-23 14:47:26 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2023-06-29 14:42:33 +0200
commit5f3177eb414632e140675ea8eac9bf5af38cc1b2 (patch)
tree73e837950547db76f137ee9fc5af9ae6623be083 /src
parent061fbca2a9e6e374ff25a22799e500298d841934 (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.c28
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),