diff options
author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2015-06-19 09:08:23 +0200 |
---|---|---|
committer | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2015-06-29 10:53:32 +0200 |
commit | 6d86628e5b6d81afae4ca1f24201ee90bfab1c2a (patch) | |
tree | b6b531eca25ee3c165e3f933604b78a36fe33af7 /src | |
parent | e2e004e7a91a3cd680c11364d9cb8cd21c714a8b (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')
-rw-r--r-- | src/bts.cpp | 2 | ||||
-rw-r--r-- | src/gprs_ms.cpp | 2 | ||||
-rw-r--r-- | src/tbf.cpp | 59 |
3 files changed, 32 insertions, 31 deletions
diff --git a/src/bts.cpp b/src/bts.cpp index 8e565435..0ff0ffac 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -962,7 +962,7 @@ void gprs_rlcmac_pdch::rcv_resource_request(Packet_Resource_Request_t *request, ms_class = Decoding::get_ms_class_by_capability(&request->MS_Radio_Access_capability); if (!ms_class) LOGP(DRLCMAC, LOGL_NOTICE, "MS does not give us a class.\n"); - ul_tbf = tbf_alloc_ul(bts_data(), trx_no(), ms_class, tlli, ta, NULL); + ul_tbf = tbf_alloc_ul(bts_data(), trx_no(), ms_class, tlli, ta, ms); if (!ul_tbf) return; diff --git a/src/gprs_ms.cpp b/src/gprs_ms.cpp index 2cfedc3b..0c1ae650 100644 --- a/src/gprs_ms.cpp +++ b/src/gprs_ms.cpp @@ -240,7 +240,7 @@ void GprsMs::detach_tbf(gprs_rlcmac_tbf *tbf) if (tbf->ms() == this) tbf->set_ms(NULL); - if (!m_dl_tbf && !m_ul_tbf) + if (!m_dl_tbf && !m_ul_tbf && tlli() != 0) start_timer(); update_status(); 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(), |