Get rid of tbf->first_ts
There's no big benefit in keeping it stored since it can be quickly
found. This makes the tbf data structure simplier and easier to
maintain, and discharges the alloc_algorithm functions from an extra
step.
Change-Id: I5d2f665f648f8637466bfdd3bf7b924cb61ede33
diff --git a/src/bts.cpp b/src/bts.cpp
index c6253f4..5ae0714 100644
--- a/src/bts.cpp
+++ b/src/bts.cpp
@@ -988,7 +988,8 @@
goto send_imm_ass_rej;
}
tbf->set_ta(ta);
- pdch = &tbf->trx->pdch[tbf->first_ts];
+ /* Only single TS can be allocated through AGCH, hence first TS is the only one: */
+ pdch = tbf_get_first_ts(tbf);
usf = tbf->m_usf[pdch->ts_no];
bts_do_rate_ctr_inc(bts, CTR_IMMEDIATE_ASSIGN_UL_TBF_ONE_PHASE);
}
@@ -1076,12 +1077,15 @@
void bts_snd_dl_ass(struct gprs_rlcmac_bts *bts, const struct gprs_rlcmac_dl_tbf *tbf)
{
- uint8_t trx_no = tbf->trx->trx_no;
- uint8_t ts_no = tbf->first_ts;
uint16_t pgroup = ms_paging_group(tbf_ms(tbf));
int plen;
+ const struct gprs_rlcmac_pdch *pdch;
LOGPTBF(tbf, LOGL_INFO, "TX: START Immediate Assignment Downlink (PCH)\n");
+
+ /* Only one TS can be assigned through PCH, hence the first one is the only one: */
+ pdch = tbf_get_first_ts_const(tbf);
+
bitvec *immediate_assignment = bitvec_alloc(22, tall_pcu_ctx); /* without plen */
bitvec_unhex(immediate_assignment, DUMMY_VEC); /* standard '2B'O padding */
/* 3GPP TS 44.018, section 9.1.18.0d states that the network shall code the
@@ -1090,10 +1094,10 @@
* message sent by a mobile station. Use last_rts_fn + 21216 (16 TDMA
* super-frame periods, or ~21.3 seconds) to achieve a decent distance. */
LOGP(DRLCMAC, LOGL_DEBUG, " - TRX=%d (%d) TS=%d TA=%d\n",
- trx_no, tbf->trx->arfcn, ts_no, tbf->ta());
- plen = Encoding::write_immediate_assignment(&bts->trx[trx_no].pdch[ts_no],
+ tbf->trx->trx_no, tbf->trx->arfcn, pdch->ts_no, tbf->ta());
+ plen = Encoding::write_immediate_assignment(pdch,
tbf, immediate_assignment, true, 125,
- GSM_TDMA_FN_SUM(tbf->pdch[ts_no]->last_rts_fn, 21216),
+ GSM_TDMA_FN_SUM(pdch->last_rts_fn, 21216),
tbf->ta(), 7, false, 0,
bts_get_ms_pwr_alpha(bts), bts->pcu->vty.gamma, -1,
GSM_L1_BURST_TYPE_ACCESS_0);
diff --git a/src/encoding.cpp b/src/encoding.cpp
index c5f4dd4..370dbe2 100644
--- a/src/encoding.cpp
+++ b/src/encoding.cpp
@@ -553,7 +553,7 @@
Direct_encoding_1_t fh_params;
/* Check one PDCH, if it's hopping then all other should too */
- pdch = tbf->pdch[tbf->first_ts];
+ pdch = tbf_get_first_ts_const(tbf);
OSMO_ASSERT(pdch != NULL);
/* Training Sequence Code */
@@ -562,7 +562,7 @@
/* If frequency hopping is not in use, encode a single ARFCN */
if (!pdch->fh.enabled) {
freq_params->UnionType = 0x00;
- freq_params->u.ARFCN = tbf->trx->arfcn;
+ freq_params->u.ARFCN = pdch->trx->arfcn;
return;
}
diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp
index 026ad6e..96098a9 100644
--- a/src/gprs_rlcmac_ts_alloc.cpp
+++ b/src/gprs_rlcmac_ts_alloc.cpp
@@ -411,7 +411,6 @@
tbf->trx = trx;
/* the only one TS is the common TS */
- tbf->first_ts = ts;
ms_set_reserved_slots(ms, trx, 1 << ts, 1 << ts);
ms_set_first_common_ts(ms, ts);
@@ -865,7 +864,7 @@
int8_t first_common_ts;
uint8_t slotcount = 0;
uint8_t reserve_count = 0, trx_no;
- int first_ts = -1;
+ int first_ts;
int usf[8] = {-1, -1, -1, -1, -1, -1, -1, -1};
int rc;
int tfi;
@@ -920,15 +919,14 @@
}
first_ts = ffs(rc) - 1;
- first_common_ts = ffs(dl_slots & ul_slots) - 1;
-
- if (first_common_ts < 0) {
- LOGPAL(tbf, "B", single, use_trx, LOGL_NOTICE, "first common slot unavailable\n");
+ if (first_ts < 0) {
+ LOGPAL(tbf, "B", single, use_trx, LOGL_NOTICE, "first slot unavailable\n");
return -EINVAL;
}
- if (first_ts < 0) {
- LOGPAL(tbf, "B", single, use_trx, LOGL_NOTICE, "first slot unavailable\n");
+ first_common_ts = ffs(dl_slots & ul_slots) - 1;
+ if (first_common_ts < 0) {
+ LOGPAL(tbf, "B", single, use_trx, LOGL_NOTICE, "first common slot unavailable\n");
return -EINVAL;
}
@@ -948,7 +946,6 @@
update_ms_reserved_slots(trx, ms, reserved_ul_slots, reserved_dl_slots, ul_slots, dl_slots);
ms_set_first_common_ts(ms, first_common_ts);
tbf->trx = trx;
- tbf->first_ts = first_ts;
if (tbf->direction == GPRS_RLCMAC_DL_TBF)
assign_dl_tbf_slots(tbf_as_dl_tbf(tbf), trx, dl_slots, tfi);
diff --git a/src/pcu_vty_functions.cpp b/src/pcu_vty_functions.cpp
index e35e817..17aa203 100644
--- a/src/pcu_vty_functions.cpp
+++ b/src/pcu_vty_functions.cpp
@@ -61,12 +61,11 @@
tbf->ta(),
tbf->direction == GPRS_RLCMAC_UL_TBF ? "UL" : "DL",
tbf->imsi(), VTY_NEWLINE);
- vty_out(vty, " created=%lu state=%s flags=%08x [CCCH:%u, PACCH:%u] 1st_TS=%d 1st_cTS=%" PRId8 " ctrl_TS=%d MS_CLASS=%d/%d%s",
+ vty_out(vty, " created=%lu state=%s flags=%08x [CCCH:%u, PACCH:%u] 1st_cTS=%" PRId8 " ctrl_TS=%d MS_CLASS=%d/%d%s",
tbf->created_ts(), tbf->state_name(),
state_flags,
state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH),
state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH),
- tbf->first_ts,
ms_first_common_ts(ms), tbf->control_ts,
tbf->ms_class(),
ms_egprs_ms_class(ms),
diff --git a/src/tbf.cpp b/src/tbf.cpp
index 7483d49..8358b8f 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -90,7 +90,6 @@
gprs_rlcmac_tbf::gprs_rlcmac_tbf(struct gprs_rlcmac_bts *bts_, GprsMs *ms, gprs_rlcmac_tbf_direction dir) :
direction(dir),
trx(NULL),
- first_ts(TBF_TS_UNSET),
control_ts(TBF_TS_UNSET),
fT(0),
num_fT_exp(0),
@@ -892,6 +891,32 @@
return tbf->update();
}
+/* first TS used by TBF */
+struct gprs_rlcmac_pdch *tbf_get_first_ts(struct gprs_rlcmac_tbf *tbf)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(tbf->pdch); i++) {
+ struct gprs_rlcmac_pdch *pdch;
+ pdch = tbf->pdch[i];
+ if (pdch)
+ return pdch;
+ }
+ return NULL;
+}
+const struct gprs_rlcmac_pdch *tbf_get_first_ts_const(const struct gprs_rlcmac_tbf *tbf)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(tbf->pdch); i++) {
+ const struct gprs_rlcmac_pdch *pdch;
+ pdch = tbf->pdch[i];
+ if (pdch)
+ return pdch;
+ }
+ return NULL;
+}
+
const char* tbf_rlcmac_diag(const struct gprs_rlcmac_tbf *tbf)
{
static char buf[256];
diff --git a/src/tbf.h b/src/tbf.h
index d4d52f9..4a08da9 100644
--- a/src/tbf.h
+++ b/src/tbf.h
@@ -148,6 +148,8 @@
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_stop_timers(struct gprs_rlcmac_tbf *tbf, const char *reason);
#ifdef __cplusplus
@@ -218,7 +220,6 @@
enum gprs_rlcmac_tbf_direction direction;
struct gprs_rlcmac_trx *trx;
- uint8_t first_ts; /* first TS used by TBF */
uint8_t control_ts; /* timeslot control messages and polling */
struct gprs_rlcmac_pdch *pdch[8]; /* list of PDCHs allocated to TBF */
diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp
index e4e4f79..8333a2f 100644
--- a/src/tbf_ul.cpp
+++ b/src/tbf_ul.cpp
@@ -166,7 +166,6 @@
ul_tbf->trx = trx;
/* The only one TS is the common, control TS */
- ul_tbf->first_ts = ts;
ms_set_first_common_ts(ms, ts);
tbf_assign_control_ts(ul_tbf);
ul_tbf->m_ctrs = rate_ctr_group_alloc(ul_tbf, &tbf_ctrg_desc, next_tbf_ctr_group_id++);