Move resource allocation outside of tbf allocation
This patch finally decouples TBF allocation from resource allocation.
This will allow in the future reserving resources without having to
require a TBF object to exist.
Change-Id: I2856c946cb62d6e5372a1099b60e5f3456eb8fd4
diff --git a/src/gprs_ms.c b/src/gprs_ms.c
index 0018252..739bbcd 100644
--- a/src/gprs_ms.c
+++ b/src/gprs_ms.c
@@ -24,6 +24,7 @@
#include "pcu_utils.h"
#include "nacc_fsm.h"
#include "tbf_ul_ack_fsm.h"
+#include "alloc_algo.h"
#include <time.h>
@@ -1119,15 +1120,46 @@
*/
struct gprs_rlcmac_ul_tbf *ms_new_ul_tbf_assigned_pacch(struct GprsMs *ms, int8_t use_trx)
{
- const bool single_slot = false;
struct gprs_rlcmac_ul_tbf *ul_tbf;
+ const struct alloc_resources_req req = {
+ .bts = ms->bts,
+ .ms = ms,
+ .direction = GPRS_RLCMAC_UL_TBF,
+ .single = false,
+ .use_trx = use_trx,
+ };
+ struct alloc_resources_res res = {};
+ int rc;
- ul_tbf = ul_tbf_alloc(ms->bts, ms, use_trx, single_slot);
+ rc = the_pcu->alloc_algorithm(&req, &res);
+ if (rc < 0) {
+ LOGPMS(ms, DTBF, LOGL_NOTICE,
+ "Timeslot Allocation failed: trx = %d, single_slot = %d\n",
+ req.use_trx, req.single);
+ bts_do_rate_ctr_inc(ms->bts, CTR_TBF_ALLOC_FAIL);
+ return NULL;
+ }
+
+ ul_tbf = ul_tbf_alloc(ms->bts, ms);
if (!ul_tbf) {
- LOGPMS(ms, DTBF, LOGL_NOTICE, "No PDCH resource\n");
+ LOGPMS(ms, DTBF, LOGL_NOTICE, "ul_tbf_alloc() failed\n");
/* Caller will most probably send a Imm Ass Reject after return */
return NULL;
}
+
+ /* Update MS, really allocate the resources */
+ if (res.reserved_ul_slots != ms_reserved_ul_slots(ms) ||
+ res.reserved_dl_slots != ms_reserved_dl_slots(ms)) {
+ /* The reserved slots have changed, update the MS */
+ ms_set_reserved_slots(ms, res.trx, res.reserved_ul_slots, res.reserved_dl_slots);
+ }
+ ms_set_first_common_ts(ms, res.first_common_ts);
+
+ /* Apply allocated resources to TBF: */
+ ul_tbf_apply_allocated_resources(ul_tbf, &res);
+
+ ms_attach_tbf(ms, ul_tbf_as_tbf(ul_tbf));
+
osmo_fsm_inst_dispatch(tbf_state_fi(ul_tbf_as_tbf(ul_tbf)), TBF_EV_ASSIGN_ADD_PACCH, NULL);
/* Contention resolution is considered to be done since TLLI is known in MS */
return ul_tbf;
@@ -1137,30 +1169,79 @@
* packet access", where MS requested only 1 PDCH TS (TS 44.018 Table 9.1.8.1). */
struct gprs_rlcmac_ul_tbf *ms_new_ul_tbf_assigned_agch(struct GprsMs *ms)
{
- const int8_t trx_no = -1;
- const bool single_slot = true;
struct gprs_rlcmac_ul_tbf *ul_tbf;
+ const struct alloc_resources_req req = {
+ .bts = ms->bts,
+ .ms = ms,
+ .direction = GPRS_RLCMAC_UL_TBF,
+ .single = true,
+ .use_trx = -1,
+ };
+ struct alloc_resources_res res = {};
+ int rc;
- ul_tbf = ul_tbf_alloc(ms->bts, ms, trx_no, single_slot);
+ rc = the_pcu->alloc_algorithm(&req, &res);
+ if (rc < 0) {
+ LOGPMS(ms, DTBF, LOGL_NOTICE,
+ "Timeslot Allocation failed: trx = %d, single_slot = %d\n",
+ req.use_trx, req.single);
+ bts_do_rate_ctr_inc(ms->bts, CTR_TBF_ALLOC_FAIL);
+ return NULL;
+ }
+
+ ul_tbf = ul_tbf_alloc(ms->bts, ms);
if (!ul_tbf) {
- LOGP(DTBF, LOGL_NOTICE, "No PDCH resource for Uplink TBF\n");
+ LOGPMS(ms, DTBF, LOGL_NOTICE, "ul_tbf_alloc() failed\n");
/* Caller will most probably send a Imm Ass Reject after return */
return NULL;
}
+
+ /* Update MS, really allocate the resources */
+ if (res.reserved_ul_slots != ms_reserved_ul_slots(ms) ||
+ res.reserved_dl_slots != ms_reserved_dl_slots(ms)) {
+ /* The reserved slots have changed, update the MS */
+ ms_set_reserved_slots(ms, res.trx, res.reserved_ul_slots, res.reserved_dl_slots);
+ }
+ ms_set_first_common_ts(ms, res.first_common_ts);
+
+ /* Apply allocated resources to TBF: */
+ ul_tbf_apply_allocated_resources(ul_tbf, &res);
+
+ ms_attach_tbf(ms, ul_tbf_as_tbf(ul_tbf));
+
osmo_fsm_inst_dispatch(tbf_state_fi(ul_tbf_as_tbf(ul_tbf)), TBF_EV_ASSIGN_ADD_CCCH, NULL);
return ul_tbf;
}
/* Create a temporary dummy TBF to Tx a ImmAssReject if allocating a new one during
* packet resource Request failed. This is similar as ul_tbf_alloc() but without
- * calling tbf->setup() (in charge of TFI/USF allocation), and reusing resources
+ * calling alloc_algo (in charge of TFI/USF allocation), and reusing resources
* from Packet Resource Request we received. See TS 44.060 sec 7.1.3.2.1 */
struct gprs_rlcmac_ul_tbf *ms_new_ul_tbf_rejected_pacch(struct GprsMs *ms, struct gprs_rlcmac_pdch *pdch)
{
struct gprs_rlcmac_ul_tbf *ul_tbf;
- ul_tbf = ul_tbf_alloc_rejected(ms->bts, ms, pdch);
+ struct alloc_resources_res fake_res = {
+ .trx = pdch->trx,
+ .first_common_ts = pdch,
+ .reserved_ul_slots = 0,
+ .reserved_dl_slots = 0,
+ .ass_slots_mask = 0,
+ .upgrade_to_multislot = false,
+ .tfi = TBF_TFI_UNSET,
+ .usf = {0},
+ };
+ ul_tbf = ul_tbf_alloc(ms->bts, ms);
if (!ul_tbf)
return NULL;
+
+ /* The only one TS is the common, control TS */
+ ms_set_first_common_ts(ms, pdch);
+
+ /* Apply fake resources to TBF, to attach it to the proper TRX/PDCH: */
+ ul_tbf_apply_allocated_resources(ul_tbf, &fake_res);
+
+ ms_attach_tbf(ms, ul_tbf_as_tbf(ul_tbf));
+
osmo_fsm_inst_dispatch(tbf_state_fi(ul_tbf_as_tbf(ul_tbf)), TBF_EV_ASSIGN_ADD_PACCH, NULL);
osmo_fsm_inst_dispatch(tbf_ul_ass_fi(ul_tbf_as_tbf(ul_tbf)), TBF_UL_ASS_EV_SCHED_ASS_REJ, NULL);
@@ -1174,16 +1255,45 @@
int ms_new_dl_tbf_assigned_on_pacch(struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf)
{
OSMO_ASSERT(tbf);
- const int8_t trx_no = tbf_get_trx(tbf)->trx_no;
- const bool single_slot = false;
struct gprs_rlcmac_dl_tbf *dl_tbf;
+ const struct alloc_resources_req req = {
+ .bts = ms->bts,
+ .ms = ms,
+ .direction = GPRS_RLCMAC_DL_TBF,
+ .single = false,
+ .use_trx = tbf_get_trx(tbf)->trx_no,
+ };
+ struct alloc_resources_res res = {};
+ int rc;
- dl_tbf = dl_tbf_alloc(ms->bts, ms, trx_no, single_slot);
- if (!dl_tbf) {
- LOGPMS(ms, DTBF, LOGL_NOTICE, "No PDCH resource\n");
+ rc = the_pcu->alloc_algorithm(&req, &res);
+ if (rc < 0) {
+ LOGPMS(ms, DTBF, LOGL_NOTICE,
+ "Timeslot Allocation failed: trx = %d, single_slot = %d\n",
+ req.use_trx, req.single);
+ bts_do_rate_ctr_inc(ms->bts, CTR_TBF_ALLOC_FAIL);
return -EBUSY;
}
+ dl_tbf = dl_tbf_alloc(ms->bts, ms);
+ if (!dl_tbf) {
+ LOGPMS(ms, DTBF, LOGL_NOTICE, "dl_tbf_alloc() failed\n");
+ return -1;
+ }
+
+ /* Update MS, really allocate the resources */
+ if (res.reserved_ul_slots != ms_reserved_ul_slots(ms) ||
+ res.reserved_dl_slots != ms_reserved_dl_slots(ms)) {
+ /* The reserved slots have changed, update the MS */
+ ms_set_reserved_slots(ms, res.trx, res.reserved_ul_slots, res.reserved_dl_slots);
+ }
+ ms_set_first_common_ts(ms, res.first_common_ts);
+
+ /* Apply allocated resources to TBF: */
+ dl_tbf_apply_allocated_resources(dl_tbf, &res);
+
+ ms_attach_tbf(ms, dl_tbf_as_tbf(dl_tbf));
+
LOGPTBFDL(dl_tbf, LOGL_DEBUG, "[DOWNLINK] START (PACCH)\n");
dl_tbf_trigger_ass_on_pacch(dl_tbf, tbf);
return 0;
@@ -1194,16 +1304,45 @@
*/
int ms_new_dl_tbf_assigned_on_pch(struct GprsMs *ms)
{
- const int8_t trx_no = -1;
- const bool single_slot = true;
struct gprs_rlcmac_dl_tbf *dl_tbf;
+ const struct alloc_resources_req req = {
+ .bts = ms->bts,
+ .ms = ms,
+ .direction = GPRS_RLCMAC_DL_TBF,
+ .single = true,
+ .use_trx = -1,
+ };
+ struct alloc_resources_res res = {};
+ int rc;
- dl_tbf = dl_tbf_alloc(ms->bts, ms, trx_no, single_slot);
- if (!dl_tbf) {
- LOGPMS(ms, DTBF, LOGL_NOTICE, "No PDCH resource\n");
+ rc = the_pcu->alloc_algorithm(&req, &res);
+ if (rc < 0) {
+ LOGPMS(ms, DTBF, LOGL_NOTICE,
+ "Timeslot Allocation failed: trx = %d, single_slot = %d\n",
+ req.use_trx, req.single);
+ bts_do_rate_ctr_inc(ms->bts, CTR_TBF_ALLOC_FAIL);
return -EBUSY;
}
+ dl_tbf = dl_tbf_alloc(ms->bts, ms);
+ if (!dl_tbf) {
+ LOGPMS(ms, DTBF, LOGL_NOTICE, "dl_tbf_alloc() failed\n");
+ return -1;
+ }
+
+ /* Update MS, really allocate the resources */
+ if (res.reserved_ul_slots != ms_reserved_ul_slots(ms) ||
+ res.reserved_dl_slots != ms_reserved_dl_slots(ms)) {
+ /* The reserved slots have changed, update the MS */
+ ms_set_reserved_slots(ms, res.trx, res.reserved_ul_slots, res.reserved_dl_slots);
+ }
+ ms_set_first_common_ts(ms, res.first_common_ts);
+
+ /* Apply allocated resources to TBF: */
+ dl_tbf_apply_allocated_resources(dl_tbf, &res);
+
+ ms_attach_tbf(ms, dl_tbf_as_tbf(dl_tbf));
+
LOGPTBFDL(dl_tbf, LOGL_DEBUG, "[DOWNLINK] START (PCH)\n");
dl_tbf_trigger_ass_on_pch(dl_tbf);
return 0;
diff --git a/src/tbf.cpp b/src/tbf.cpp
index 921611d..7f549c7 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -222,8 +222,10 @@
* confirmation from the MS and goes through the FLOW state. Hence, we
* may have ULC pollings ongoing and we need to make sure we drop all
* reserved nodes there: */
- if (tbf->control_ts)
+ if (tbf->control_ts) {
pdch_ulc_release_tbf(tbf->control_ts->ulc, tbf);
+ tbf->control_ts = NULL;
+ }
/* Now simply detach from all attached PDCHs */
for (ts = 0; ts < 8; ts++) {
@@ -233,6 +235,12 @@
tbf->pdch[ts]->detach_tbf(tbf);
tbf->pdch[ts] = NULL;
}
+
+ /* Detach from TRX: */
+ if (tbf->trx) {
+ llist_del(tbf_trx_list(tbf));
+ tbf->trx = NULL;
+ }
}
void tbf_free(struct gprs_rlcmac_tbf *tbf)
@@ -264,7 +272,6 @@
tbf->stop_timers("freeing TBF");
/* TODO: Could/Should generate bssgp_tx_llc_discarded */
tbf_unlink_pdch(tbf);
- llist_del(tbf_trx_list(tbf));
if (tbf->ms())
tbf->set_ms(NULL);
@@ -572,68 +579,6 @@
}
}
-int gprs_rlcmac_tbf::alloc_algorithm(const struct alloc_resources_req *req)
-{
- int rc;
-
- /* select algorithm */
- struct alloc_resources_res res = {};
- rc = the_pcu->alloc_algorithm(req, &res);
- if (rc < 0)
- return rc;
-
- /* The allocation will be successful, so the system state and tbf/ms
- * may be modified from now on. */
-
- /* Update MS, really allocate the resources */
- if (res.reserved_ul_slots != ms_reserved_ul_slots(req->ms) ||
- res.reserved_dl_slots != ms_reserved_dl_slots(req->ms)) {
- /* The reserved slots have changed, update the MS */
- ms_set_reserved_slots(ms(), res.trx, res.reserved_ul_slots, res.reserved_dl_slots);
- }
- ms_set_first_common_ts(ms(), res.first_common_ts);
-
- /* Assign TRX,TS,TFI,USF to TBF: */
- this->apply_allocated_resources(&res);
-
- return 0;
-}
-
-int gprs_rlcmac_tbf::setup(int8_t use_trx, bool single_slot)
-{
- int rc;
- const struct alloc_resources_req req = {
- .bts = bts,
- .ms = this->ms(),
- .direction = this->direction,
- .single = single_slot,
- .use_trx = use_trx,
- };
-
- /* select algorithm */
- rc = this->alloc_algorithm(&req);
- /* if no resource */
- if (rc < 0) {
- LOGPTBF(this, LOGL_NOTICE,
- "Timeslot Allocation failed: trx = %d, single_slot = %d\n",
- use_trx, single_slot);
- bts_do_rate_ctr_inc(bts, CTR_TBF_ALLOC_FAIL);
- return -1;
- }
- /* assign initial control ts */
- tbf_assign_control_ts(this);
-
- LOGPTBF(this, LOGL_INFO,
- "Allocated: trx = %d, ul_slots = %02x, dl_slots = %02x\n",
- this->trx->trx_no, ul_slots(), dl_slots());
-
- tbf_update_state_fsm_name(this);
-
- ms_attach_tbf(m_ms, this);
-
- return 0;
-}
-
const char *tbf_name(const gprs_rlcmac_tbf *tbf)
{
return tbf ? tbf->name() : "(no TBF)";
diff --git a/src/tbf.h b/src/tbf.h
index ba2a755..878c77b 100644
--- a/src/tbf.h
+++ b/src/tbf.h
@@ -165,7 +165,6 @@
virtual gprs_rlc_window *window() = 0;
virtual void apply_allocated_resources(const struct alloc_resources_res *res) = 0;
- int setup(int8_t use_trx, bool single_slot);
bool state_is(enum tbf_fsm_states rhs) const;
bool state_is_not(enum tbf_fsm_states rhs) const;
bool dl_ass_state_is(enum tbf_dl_ass_fsm_states rhs) const;
@@ -214,8 +213,6 @@
/* attempt to make things a bit more fair */
void rotate_in_list();
- int alloc_algorithm(const struct alloc_resources_req *req);
-
enum gprs_rlcmac_tbf_direction direction;
struct gprs_rlcmac_trx *trx;
struct gprs_rlcmac_pdch *control_ts; /* timeslot control messages and polling */
diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp
index 4af9ae6..3ffafbf 100644
--- a/src/tbf_dl.cpp
+++ b/src/tbf_dl.cpp
@@ -106,10 +106,9 @@
return 0;
}
-struct gprs_rlcmac_dl_tbf *dl_tbf_alloc(struct gprs_rlcmac_bts *bts, struct GprsMs *ms, int8_t use_trx, bool single_slot)
+struct gprs_rlcmac_dl_tbf *dl_tbf_alloc(struct gprs_rlcmac_bts *bts, struct GprsMs *ms)
{
struct gprs_rlcmac_dl_tbf *tbf;
- int rc;
OSMO_ASSERT(ms != NULL);
@@ -124,15 +123,7 @@
talloc_set_destructor(tbf, dl_tbf_dtor);
new (tbf) gprs_rlcmac_dl_tbf(bts, ms);
- rc = tbf->setup(use_trx, single_slot);
- /* if no resource */
- if (rc < 0) {
- talloc_free(tbf);
- return NULL;
- }
-
if (tbf->is_egprs_enabled()) {
- tbf->set_window_size();
tbf->m_dl_egprs_ctrs = rate_ctr_group_alloc(tbf,
&tbf_dl_egprs_ctrg_desc,
tbf->m_ctrs->idx);
@@ -151,8 +142,6 @@
return NULL;
}
}
-
- llist_add(tbf_trx_list((struct gprs_rlcmac_tbf *)tbf), &tbf->trx->dl_tbfs);
bts_do_rate_ctr_inc(tbf->bts, CTR_TBF_DL_ALLOCATED);
return tbf;
@@ -422,6 +411,11 @@
{
uint8_t ts;
+ if (this->trx)
+ llist_del(&this->m_trx_list.list);
+
+ llist_add(&this->m_trx_list.list, &res->trx->dl_tbfs);
+
this->trx = res->trx;
this->upgrade_to_multislot = res->upgrade_to_multislot;
@@ -438,6 +432,23 @@
this->pdch[pdch->ts_no] = pdch;
pdch->attach_tbf(this);
}
+
+ /* assign initial control ts */
+ tbf_assign_control_ts(this);
+
+ LOGPTBF(this, LOGL_INFO,
+ "Allocated: trx = %d, ul_slots = %02x, dl_slots = %02x\n",
+ this->trx->trx_no, ul_slots(), dl_slots());
+
+ if (tbf_is_egprs_enabled(this))
+ this->set_window_size();
+
+ tbf_update_state_fsm_name(this);
+}
+
+void dl_tbf_apply_allocated_resources(struct gprs_rlcmac_dl_tbf *dl_tbf, const struct alloc_resources_res *res)
+{
+ dl_tbf->apply_allocated_resources(res);
}
/* old_tbf (UL TBF or DL TBF) will send a Pkt Dl Ass on PACCH to assign tbf.
@@ -483,6 +494,7 @@
struct gprs_rlcmac_tbf *tbf = dl_tbf_as_tbf(dl_tbf);
struct gprs_rlcmac_trx *trx = tbf_get_trx(dl_tbf);
struct gprs_rlcmac_bts *bts = trx->bts;
+ struct GprsMs *ms = tbf->ms();
LOGPTBFDL(dl_tbf, LOGL_DEBUG, "Upgrade to multislot\n");
@@ -490,12 +502,14 @@
const struct alloc_resources_req req = {
.bts = bts,
- .ms = tbf->ms(),
+ .ms = ms,
.direction = tbf_direction(tbf),
.single = false,
.use_trx = -1,
};
- rc = dl_tbf->alloc_algorithm(&req);
+ struct alloc_resources_res res = {};
+
+ rc = the_pcu->alloc_algorithm(&req, &res);
/* if no resource */
if (rc < 0) {
LOGPTBFDL(dl_tbf, LOGL_ERROR, "No resources allocated during upgrade to multislot!\n");
@@ -503,9 +517,18 @@
return rc;
}
- if (tbf_is_egprs_enabled(tbf))
- dl_tbf->set_window_size();
- tbf_update_state_fsm_name(tbf);
+ /* Update MS, really allocate the resources */
+ if (res.reserved_ul_slots != ms_reserved_ul_slots(ms) ||
+ res.reserved_dl_slots != ms_reserved_dl_slots(ms)) {
+ /* The reserved slots have changed, update the MS */
+ ms_set_reserved_slots(ms, res.trx, res.reserved_ul_slots, res.reserved_dl_slots);
+ }
+ ms_set_first_common_ts(ms, res.first_common_ts);
+
+ /* Apply allocated resources to TBF: */
+ dl_tbf_apply_allocated_resources(dl_tbf, &res);
+
+ /* Note: No need to call ms_attach_tbf(), tbf is already attached to the MS */
/* Now trigger the assignment using the pre-existing TBF: */
dl_tbf_trigger_ass_on_pacch(dl_tbf, tbf);
diff --git a/src/tbf_dl.h b/src/tbf_dl.h
index 90dfb12..6718c13 100644
--- a/src/tbf_dl.h
+++ b/src/tbf_dl.h
@@ -138,8 +138,7 @@
#endif
struct gprs_rlcmac_bts;
-struct gprs_rlcmac_dl_tbf *dl_tbf_alloc(struct gprs_rlcmac_bts *bts, struct GprsMs *ms,
- int8_t use_trx, bool single_slot);
+struct gprs_rlcmac_dl_tbf *dl_tbf_alloc(struct gprs_rlcmac_bts *bts, struct GprsMs *ms);
struct gprs_rlcmac_dl_tbf *tbf_as_dl_tbf(struct gprs_rlcmac_tbf *tbf);
const struct gprs_rlcmac_dl_tbf *tbf_as_dl_tbf_const(const struct gprs_rlcmac_tbf *tbf);
@@ -150,6 +149,7 @@
const uint8_t egprs_ms_class, const uint16_t delay_csec,
const uint8_t *data, const uint16_t len);
+void dl_tbf_apply_allocated_resources(struct gprs_rlcmac_dl_tbf *dl_tbf, const struct alloc_resources_res *res);
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);
diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp
index 47347f9..9a139ba 100644
--- a/src/tbf_ul.cpp
+++ b/src/tbf_ul.cpp
@@ -105,10 +105,9 @@
}
/* Generic function to alloc a UL TBF, later configured to be assigned either over CCCH or PACCH */
-struct gprs_rlcmac_ul_tbf *ul_tbf_alloc(struct gprs_rlcmac_bts *bts, struct GprsMs *ms, int8_t use_trx, bool single_slot)
+struct gprs_rlcmac_ul_tbf *ul_tbf_alloc(struct gprs_rlcmac_bts *bts, struct GprsMs *ms)
{
struct gprs_rlcmac_ul_tbf *tbf;
- int rc;
OSMO_ASSERT(ms != NULL);
@@ -121,53 +120,11 @@
talloc_set_destructor(tbf, ul_tbf_dtor);
new (tbf) gprs_rlcmac_ul_tbf(bts, ms);
- rc = tbf->setup(use_trx, single_slot);
-
- /* if no resource */
- if (rc < 0) {
- talloc_free(tbf);
- return NULL;
- }
-
- if (tbf->is_egprs_enabled())
- tbf->set_window_size();
-
- llist_add_tail(tbf_trx_list(tbf), &tbf->trx->ul_tbfs);
bts_do_rate_ctr_inc(tbf->bts, CTR_TBF_UL_ALLOCATED);
return tbf;
}
-/* Create a temporary dummy TBF to Tx a ImmAssReject if allocating a new one during
- * packet resource Request failed. This is similar as tbf_alloc_ul() but without
- * calling tbf->setup() (in charge of TFI/USF allocation), and reusing resources
- * from Packet Resource Request we received. See TS 44.060 sec 7.1.3.2.1 */
-struct gprs_rlcmac_ul_tbf *ul_tbf_alloc_rejected(struct gprs_rlcmac_bts *bts, struct GprsMs *ms,
- struct gprs_rlcmac_pdch *pdch)
-{
- struct gprs_rlcmac_ul_tbf *ul_tbf = NULL;
- struct gprs_rlcmac_trx *trx = pdch->trx;
- OSMO_ASSERT(ms);
-
- ul_tbf = talloc(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);
- if (!ul_tbf)
- return ul_tbf;
- talloc_set_destructor(ul_tbf, ul_tbf_dtor);
- new (ul_tbf) gprs_rlcmac_ul_tbf(bts, ms);
-
- ul_tbf->trx = trx;
- /* The only one TS is the common, control TS */
- ms_set_first_common_ts(ms, pdch);
- tbf_assign_control_ts(ul_tbf);
- tbf_update_state_fsm_name(ul_tbf);
-
- ms_attach_tbf(ms, ul_tbf);
- llist_add(tbf_trx_list(ul_tbf), &trx->ul_tbfs);
- bts_do_rate_ctr_inc(ul_tbf->bts, CTR_TBF_UL_ALLOCATED);
-
- return ul_tbf;
-}
-
gprs_rlcmac_ul_tbf::gprs_rlcmac_ul_tbf(struct gprs_rlcmac_bts *bts_, GprsMs *ms) :
gprs_rlcmac_tbf(bts_, ms, GPRS_RLCMAC_UL_TBF),
m_rx_counter(0),
@@ -709,6 +666,11 @@
{
uint8_t ts;
+ if (this->trx)
+ llist_del(&this->m_trx_list.list);
+
+ llist_add(&this->m_trx_list.list, &res->trx->ul_tbfs);
+
this->trx = res->trx;
this->upgrade_to_multislot = res->upgrade_to_multislot;
@@ -727,6 +689,27 @@
this->pdch[pdch->ts_no] = pdch;
pdch->attach_tbf(this);
}
+
+ /* assign initial control ts */
+ tbf_assign_control_ts(this);
+
+ /* res.ass_slots_mask == 0 -> special case for Rejected UL TBFs,
+ * see ms_new_ul_tbf_rejected_pacch() */
+ if (res->ass_slots_mask != 0) {
+ LOGPTBF(this, LOGL_INFO,
+ "Allocated: trx = %d, ul_slots = %02x, dl_slots = %02x\n",
+ this->trx->trx_no, ul_slots(), dl_slots());
+
+ if (tbf_is_egprs_enabled(this))
+ this->set_window_size();
+ }
+
+ tbf_update_state_fsm_name(this);
+}
+
+void ul_tbf_apply_allocated_resources(struct gprs_rlcmac_ul_tbf *ul_tbf, const struct alloc_resources_res *res)
+{
+ ul_tbf->apply_allocated_resources(res);
}
void gprs_rlcmac_ul_tbf::usf_timeout()
diff --git a/src/tbf_ul.h b/src/tbf_ul.h
index 5ef8465..14884ab 100644
--- a/src/tbf_ul.h
+++ b/src/tbf_ul.h
@@ -133,14 +133,13 @@
#ifdef __cplusplus
extern "C" {
#endif
-struct gprs_rlcmac_ul_tbf *ul_tbf_alloc(struct gprs_rlcmac_bts *bts, struct GprsMs *ms, int8_t use_trx, bool single_slot);
-struct gprs_rlcmac_ul_tbf *ul_tbf_alloc_rejected(struct gprs_rlcmac_bts *bts, struct GprsMs *ms,
- struct gprs_rlcmac_pdch *pdch);
+struct gprs_rlcmac_ul_tbf *ul_tbf_alloc(struct gprs_rlcmac_bts *bts, struct GprsMs *ms);
void update_tbf_ta(struct gprs_rlcmac_ul_tbf *tbf, int8_t ta_delta);
void set_tbf_ta(struct gprs_rlcmac_ul_tbf *tbf, uint8_t ta);
struct gprs_rlcmac_ul_tbf *tbf_as_ul_tbf(struct gprs_rlcmac_tbf *tbf);
const struct gprs_rlcmac_ul_tbf *tbf_as_ul_tbf_const(const struct gprs_rlcmac_tbf *tbf);
void tbf_usf_timeout(struct gprs_rlcmac_ul_tbf *tbf);
+void ul_tbf_apply_allocated_resources(struct gprs_rlcmac_ul_tbf *ul_tbf, const struct alloc_resources_res *res);
void ul_tbf_contention_resolution_start(struct gprs_rlcmac_ul_tbf *tbf);
void ul_tbf_contention_resolution_success(struct gprs_rlcmac_ul_tbf *tbf);
bool ul_tbf_contention_resolution_done(const struct gprs_rlcmac_ul_tbf *tbf);