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;