Refactor code related to DL-TBF upgrade to multislot
* Make clear the code relates to DL-TBF and not UL-TBF.
* Change wording to "upgrade" to match the existing field and API
"tbf_can_upgrade_to_multislot()".
* Free the TBF if we cannot allocate new resources.
Change-Id: I0e4f8d7e46235a471b2124b280c81ff07b6967a4
diff --git a/src/tbf.cpp b/src/tbf.cpp
index 8358b8f..2cc6053 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -206,7 +206,7 @@
ms_attach_tbf(m_ms, this);
}
-static void tbf_unlink_pdch(struct gprs_rlcmac_tbf *tbf)
+void tbf_unlink_pdch(struct gprs_rlcmac_tbf *tbf)
{
int ts;
@@ -277,33 +277,6 @@
OSMO_MAX(64, (the_pcu->vty.ws_base + num_pdch * the_pcu->vty.ws_pdch) / 32 * 32));
}
-int gprs_rlcmac_tbf::update()
-{
- int rc;
-
- LOGP(DTBF, LOGL_DEBUG, "********** DL-TBF update **********\n");
- OSMO_ASSERT(direction == GPRS_RLCMAC_DL_TBF);
-
- tbf_unlink_pdch(this);
- rc = the_pcu->alloc_algorithm(bts, this, false, -1);
- /* if no resource */
- if (rc < 0) {
- LOGPTBF(this, LOGL_ERROR, "No resource after update???\n");
- bts_do_rate_ctr_inc(bts, CTR_TBF_ALLOC_FAIL);
- return rc;
- }
-
- if (is_egprs_enabled()) {
- gprs_rlcmac_dl_tbf *dl_tbf = tbf_as_dl_tbf(this);
- if (dl_tbf)
- dl_tbf->set_window_size();
- }
-
- tbf_update_state_fsm_name(this);
-
- return 0;
-}
-
void tbf_assign_control_ts(struct gprs_rlcmac_tbf *tbf)
{
int8_t first_common_ts = ms_first_common_ts(tbf_ms(tbf));
@@ -885,12 +858,6 @@
{
return tbf->upgrade_to_multislot;
}
-
-int tbf_update(struct gprs_rlcmac_tbf *tbf)
-{
- return tbf->update();
-}
-
/* first TS used by TBF */
struct gprs_rlcmac_pdch *tbf_get_first_ts(struct gprs_rlcmac_tbf *tbf)
{
diff --git a/src/tbf.h b/src/tbf.h
index 4a08da9..29f0d6f 100644
--- a/src/tbf.h
+++ b/src/tbf.h
@@ -147,10 +147,10 @@
const char* tbf_rlcmac_diag(const struct gprs_rlcmac_tbf *tbf);
bool tbf_is_control_ts(const struct gprs_rlcmac_tbf *tbf, const struct gprs_rlcmac_pdch *pdch);
bool tbf_can_upgrade_to_multislot(const struct gprs_rlcmac_tbf *tbf);
-int tbf_update(struct gprs_rlcmac_tbf *tbf);
struct gprs_rlcmac_pdch *tbf_get_first_ts(struct gprs_rlcmac_tbf *tbf);
const struct gprs_rlcmac_pdch *tbf_get_first_ts_const(const struct gprs_rlcmac_tbf *tbf);
struct gprs_rlcmac_trx *tbf_get_trx(struct gprs_rlcmac_tbf *tbf);
+void tbf_unlink_pdch(struct gprs_rlcmac_tbf *tbf);
void tbf_stop_timers(struct gprs_rlcmac_tbf *tbf, const char *reason);
#ifdef __cplusplus
}
@@ -183,7 +183,6 @@
bool n_inc(enum tbf_counters n);
void n_reset(enum tbf_counters n);
- int update();
void handle_timeout();
void stop_timers(const char *reason);
bool timers_pending(enum tbf_timers t);
diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp
index f5637f9..c5ce666 100644
--- a/src/tbf_dl.cpp
+++ b/src/tbf_dl.cpp
@@ -446,6 +446,30 @@
bts_snd_dl_ass(ms->bts, tbf);
}
+int dl_tbf_upgrade_to_multislot(struct gprs_rlcmac_dl_tbf *tbf)
+{
+ int rc;
+ struct gprs_rlcmac_trx *trx = tbf_get_trx(tbf);
+ struct gprs_rlcmac_bts *bts = trx->bts;
+
+ LOGPTBFDL(tbf, LOGL_DEBUG, "Upgrade to multislot\n");
+
+ tbf_unlink_pdch(tbf);
+ rc = the_pcu->alloc_algorithm(bts, dl_tbf_as_tbf(tbf), false, -1);
+ /* if no resource */
+ if (rc < 0) {
+ LOGPTBFDL(tbf, LOGL_ERROR, "No resources allocated during upgrade to multislot!\n");
+ bts_do_rate_ctr_inc(bts, CTR_TBF_ALLOC_FAIL);
+ return rc;
+ }
+
+ if (tbf_is_egprs_enabled(dl_tbf_as_tbf(tbf)))
+ tbf->set_window_size();
+ tbf_update_state_fsm_name(tbf);
+
+ return 0;
+}
+
void gprs_rlcmac_dl_tbf::schedule_next_frame()
{
struct msgb *msg;
diff --git a/src/tbf_dl.h b/src/tbf_dl.h
index 8d4d716..2fc4f5f 100644
--- a/src/tbf_dl.h
+++ b/src/tbf_dl.h
@@ -151,6 +151,7 @@
void dl_tbf_trigger_ass_on_pacch(struct gprs_rlcmac_dl_tbf *tbf, struct gprs_rlcmac_tbf *old_tbf);
void dl_tbf_trigger_ass_on_pch(struct gprs_rlcmac_dl_tbf *tbf);
void dl_tbf_request_dl_ack(struct gprs_rlcmac_dl_tbf *tbf);
+int dl_tbf_upgrade_to_multislot(struct gprs_rlcmac_dl_tbf *tbf);
static inline struct gprs_rlcmac_tbf *dl_tbf_as_tbf(struct gprs_rlcmac_dl_tbf *dl_tbf)
{
diff --git a/src/tbf_dl_fsm.c b/src/tbf_dl_fsm.c
index f306510..0ab740d 100644
--- a/src/tbf_dl_fsm.c
+++ b/src/tbf_dl_fsm.c
@@ -321,29 +321,35 @@
static void handle_timeout_X2002(struct osmo_fsm_inst *fi)
{
struct tbf_dl_fsm_ctx *ctx = (struct tbf_dl_fsm_ctx *)fi->priv;
+ int rc;
- if (fi->state == TBF_ST_ASSIGN) {
- tbf_assign_control_ts(ctx->tbf);
-
- if (!tbf_can_upgrade_to_multislot(ctx->tbf)) {
- /* change state to FLOW, so scheduler
- * will start transmission */
- osmo_fsm_inst_dispatch(fi, TBF_EV_ASSIGN_READY_CCCH, NULL);
- return;
- }
-
- /* This tbf can be upgraded to use multiple DL
- * timeslots and now that there is already one
- * slot assigned send another DL assignment via
- * PDCH. */
-
- /* keep to flags */
- ctx->state_flags &= GPRS_RLCMAC_FLAG_TO_MASK;
-
- tbf_update(ctx->tbf);
- dl_tbf_trigger_ass_on_pacch(ctx->dl_tbf, ctx->tbf);
- } else
+ if (fi->state != TBF_ST_ASSIGN) {
LOGPTBFDL(ctx->dl_tbf, LOGL_NOTICE, "Continue flow after IMM.ASS confirm\n");
+ return;
+ }
+
+ /* state TBF_ST_ASSIGN: */
+ tbf_assign_control_ts(ctx->tbf);
+
+ if (!tbf_can_upgrade_to_multislot(ctx->tbf)) {
+ /* change state to FLOW, so scheduler will start transmission */
+ osmo_fsm_inst_dispatch(fi, TBF_EV_ASSIGN_READY_CCCH, NULL);
+ return;
+ }
+
+ /* This tbf can be upgraded to use multiple DL timeslots and now that there is already
+ * one slot assigned send another DL assignment via PDCH.
+ */
+
+ /* keep TO flags */
+ ctx->state_flags &= GPRS_RLCMAC_FLAG_TO_MASK;
+
+ rc = dl_tbf_upgrade_to_multislot(ctx->dl_tbf);
+ if (rc < 0) {
+ tbf_free(ctx->tbf);
+ return;
+ }
+ dl_tbf_trigger_ass_on_pacch(ctx->dl_tbf, ctx->tbf);
}
static int tbf_dl_fsm_timer_cb(struct osmo_fsm_inst *fi)