aboutsummaryrefslogtreecommitdiffstats
path: root/src/tbf.cpp
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2015-06-19 09:08:23 +0200
committerJacob Erlbeck <jerlbeck@sysmocom.de>2015-06-19 13:38:32 +0200
commit196ddc58a414bb0209e672896d1119d7297c2872 (patch)
tree26207fa9cf5489443d5f512ceb81944ba8a56be7 /src/tbf.cpp
parent77a23a7de4435b1076bdfd1ac1f0e47d0fac1af6 (diff)
tbf: Always create an MS object on TBF allocation
Currently the MS object are created when the TLLI gets known. Therefore some information (TA, MS class) must be stored in the TBF itself and is copied to the MS object later on. This would get even more complex, if the allocation algorithms were extended based on this scheme. This commit ensures, that an MS object will always be created on TBF allocation, even if the TLLI is not yet known. These 'anonymous' objects are still managed by the MS storage. To avoid dangling entries without a TLLI there (which cannnot be retrieved anyway), the timer in the MS objects is not started after all TBF have been detached, so that they get deleted immediately in that case. Note that an MS object can still be removed (e.g. by replacement) from an existing TBF, so tbf->ms() can be NULL. Ticket: #1794 Sponsored-by: On-Waves ehf
Diffstat (limited to 'src/tbf.cpp')
-rw-r--r--src/tbf.cpp59
1 files changed, 30 insertions, 29 deletions
diff --git a/src/tbf.cpp b/src/tbf.cpp
index 5eda01eb..faddb79b 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -158,23 +158,11 @@ void gprs_rlcmac_tbf::set_ms(GprsMs *ms)
void gprs_rlcmac_tbf::update_ms(uint32_t tlli, enum gprs_rlcmac_tbf_direction dir)
{
- if (!ms()) {
- GprsMs *new_ms = bts->ms_store().get_ms(tlli);
- if (!new_ms) {
- new_ms = bts->ms_store().create_ms(tlli, dir);
- new_ms->set_timeout(bts->bts_data()->ms_idle_sec);
- }
-
- if (dir == GPRS_RLCMAC_UL_TBF) {
- new_ms->set_ta(m_ta);
- }
-
- if (m_ms_class)
- new_ms->set_ms_class(m_ms_class);
+ if (!ms())
+ return;
- set_ms(new_ms);
+ if (!tlli)
return;
- }
if (dir == GPRS_RLCMAC_UL_TBF)
ms()->set_tlli(tlli);
@@ -484,6 +472,8 @@ static int setup_tbf(struct gprs_rlcmac_tbf *tbf, struct gprs_rlcmac_bts *bts,
gettimeofday(&tbf->meas.rssi_tv, NULL);
tbf->m_llc.init();
+ tbf->set_ms(ms);
+
return 0;
}
@@ -508,6 +498,13 @@ struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts,
return NULL;
tbf->direction = GPRS_RLCMAC_UL_TBF;
+
+ if (!ms) {
+ ms = bts->bts->ms_store().create_ms(0, tbf->direction);
+ ms->set_timeout(bts->ms_idle_sec);
+ ms->set_ms_class(ms_class);
+ }
+
rc = setup_tbf(tbf, bts, ms, tfi, trx, ms_class, single_slot);
/* if no resource */
if (rc < 0) {
@@ -518,12 +515,6 @@ struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts,
llist_add(&tbf->list.list, &bts->ul_tbfs);
tbf->bts->tbf_ul_created();
- if (ms)
- tbf->set_ms(ms);
-
- if (tbf->ms())
- tbf->ms()->attach_ul_tbf(tbf);
-
return tbf;
}
@@ -547,6 +538,13 @@ struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts,
return NULL;
tbf->direction = GPRS_RLCMAC_DL_TBF;
+
+ if (!ms) {
+ ms = bts->bts->ms_store().create_ms(0, tbf->direction);
+ ms->set_timeout(bts->ms_idle_sec);
+ ms->set_ms_class(ms_class);
+ }
+
rc = setup_tbf(tbf, bts, ms, tfi, trx, ms_class, single_slot);
/* if no resource */
if (rc < 0) {
@@ -563,11 +561,6 @@ struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts,
gettimeofday(&tbf->m_bw.dl_bw_tv, NULL);
gettimeofday(&tbf->m_bw.dl_loss_tv, NULL);
- tbf->set_ms(ms);
-
- if (tbf->ms())
- tbf->ms()->attach_dl_tbf(tbf);
-
return tbf;
}
@@ -851,6 +844,8 @@ int gprs_rlcmac_tbf::extract_tlli(const uint8_t *data, const size_t len)
int rc;
GprsMs *old_ms;
+ OSMO_ASSERT(direction == GPRS_RLCMAC_UL_TBF);
+
/* no TLLI yet */
if (!rh->ti) {
LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA TFI=%d without "
@@ -871,14 +866,20 @@ int gprs_rlcmac_tbf::extract_tlli(const uint8_t *data, const size_t len)
dl_tbf = old_ms->dl_tbf();
ul_tbf = old_ms->ul_tbf();
- set_ms(old_ms);
+ if (!ms())
+ set_ms(old_ms);
+
+ /* there might be an active and valid downlink TBF */
+ if (!ms()->dl_tbf() && dl_tbf)
+ /* Move it to the current MS */
+ dl_tbf->set_ms(ms());
}
/* The TLLI has been taken from an UL message */
update_ms(new_tlli, GPRS_RLCMAC_UL_TBF);
LOGP(DRLCMACUL, LOGL_INFO, "Decoded premier TLLI=0x%08x of "
"UL DATA TFI=%d.\n", tlli(), rh->tfi);
- if (dl_tbf) {
+ if (dl_tbf && dl_tbf->ms() != ms()) {
LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from "
"TLLI=0x%08x while %s still exists. "
"Killing pending DL TBF\n", tlli(),
@@ -886,7 +887,7 @@ int gprs_rlcmac_tbf::extract_tlli(const uint8_t *data, const size_t len)
tbf_free(dl_tbf);
dl_tbf = NULL;
}
- if (ul_tbf) {
+ if (ul_tbf && ul_tbf->ms() != ms()) {
LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from "
"TLLI=0x%08x while %s still exists. "
"Killing pending UL TBF\n", tlli(),