ms: Integrate the MS storage

Use the MS storage to find a MS object for a given TLLI instead of
searching the TBF lists. The TBFs are then taken from the MS object,
if one has been found. If all TBF might be temporarily detached from
the MS object, a GprsMs::Guard is added to prevent the deletion of
the object, in case another TBF gets attached later on in the scope.

Ticket: #1674
Sponsored-by: On-Waves ehf
This commit is contained in:
Jacob Erlbeck 2015-05-13 13:33:12 +02:00
parent 5367086175
commit e43460b50f
5 changed files with 67 additions and 16 deletions

View File

@ -884,13 +884,21 @@ void gprs_rlcmac_pdch::rcv_resource_request(Packet_Resource_Request_t *request,
int rc;
if (request->ID.UnionType) {
struct gprs_rlcmac_ul_tbf *ul_tbf;
struct gprs_rlcmac_dl_tbf *dl_tbf;
struct gprs_rlcmac_ul_tbf *ul_tbf = NULL;
struct gprs_rlcmac_dl_tbf *dl_tbf = NULL;
uint32_t tlli = request->ID.u.TLLI;
uint8_t ms_class = 0;
uint8_t ta;
ul_tbf = bts()->ul_tbf_by_tlli(tlli);
GprsMs *ms = bts()->ms_by_tlli(tlli);
/* Keep the ms, even if it gets idle temporarily */
GprsMs::Guard guard(ms);
if (ms) {
ul_tbf = ms->ul_tbf();
dl_tbf = ms->dl_tbf();
}
if (ul_tbf) {
LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from "
"TLLI=0x%08x while %s still "
@ -900,7 +908,7 @@ void gprs_rlcmac_pdch::rcv_resource_request(Packet_Resource_Request_t *request,
ul_tbf = NULL;
}
if ((dl_tbf = bts()->dl_tbf_by_tlli(tlli))) {
if (dl_tbf) {
LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from "
"TLLI=0x%08x while %s still exists. "
"Killing pending DL TBF\n", tlli,

View File

@ -32,6 +32,7 @@ extern "C" {
#include "sba.h"
#include "ta.h"
#include "tbf.h"
#include "gprs_ms_storage.h"
#endif
#include <stdint.h>
@ -220,6 +221,9 @@ public:
void trigger_dl_ass(gprs_rlcmac_dl_tbf *tbf, gprs_rlcmac_tbf *old_tbf, const char *imsi);
void snd_dl_ass(gprs_rlcmac_tbf *tbf, uint8_t poll, const char *imsi);
GprsMsStorage &ms_store();
GprsMs *ms_by_tlli(uint32_t tlli, uint32_t old_tlli = 0);
/*
* Statistics
*/
@ -257,6 +261,8 @@ private:
gprs_rlcmac_tbf *tbf_by_tlli(uint32_t tlli, enum gprs_rlcmac_tbf_direction dir);
gprs_rlcmac_tbf *tbf_by_tfi(uint8_t tfi, uint8_t trx, enum gprs_rlcmac_tbf_direction dir);
GprsMsStorage m_ms_store;
private:
/* disable copying to avoid slicing */
BTS(const BTS&);
@ -278,6 +284,16 @@ inline SBAController *BTS::sba()
return &m_sba;
}
inline GprsMsStorage &BTS::ms_store()
{
return m_ms_store;
}
inline GprsMs *BTS::ms_by_tlli(uint32_t tlli, uint32_t old_tlli)
{
return ms_store().get_ms(tlli, old_tlli);
}
inline BTS *gprs_rlcmac_pdch::bts() const
{
return trx->bts;

View File

@ -94,8 +94,7 @@ void gprs_rlcmac_tbf::set_ms(GprsMs *ms)
void gprs_rlcmac_tbf::update_ms(uint32_t tlli)
{
if (!ms())
/* TODO: access the container instead when that is implemented */
set_ms(new GprsMs(tlli));
set_ms(bts->ms_store().get_or_create_ms(tlli));
else
ms()->set_tlli(tlli);
}
@ -236,7 +235,14 @@ int gprs_rlcmac_tbf::update()
if (direction != GPRS_RLCMAC_DL_TBF)
return -EINVAL;
ul_tbf = bts->ul_tbf_by_tlli(m_tlli);
if (ms()) {
ul_tbf = ms()->ul_tbf();
} else if (is_tlli_valid()) {
LOGP(DRLCMAC, LOGL_NOTICE,
"Using ul_tbf_by_tlli() since there is no MS object for "
"TLLI 0x%08x\n", m_tlli);
ul_tbf = bts->ul_tbf_by_tlli(m_tlli);
}
tbf_unlink_pdch(this);
rc = bts_data->alloc_algorithm(bts_data, ul_tbf, this, bts_data->alloc_algorithm_curst, 0);
@ -840,10 +846,12 @@ void gprs_rlcmac_tbf::update_tlli(uint32_t tlli)
int gprs_rlcmac_tbf::extract_tlli(const uint8_t *data, const size_t len)
{
struct gprs_rlcmac_tbf *dl_tbf, *ul_tbf;
struct gprs_rlcmac_tbf *dl_tbf = NULL;
struct gprs_rlcmac_tbf *ul_tbf = NULL;
struct rlc_ul_header *rh = (struct rlc_ul_header *)data;
uint32_t new_tlli;
int rc;
GprsMs *old_ms;
/* no TLLI yet */
if (!rh->ti) {
@ -858,11 +866,21 @@ int gprs_rlcmac_tbf::extract_tlli(const uint8_t *data, const size_t len)
"of UL DATA TFI=%d.\n", rh->tfi);
return 0;
}
old_ms = bts->ms_by_tlli(new_tlli);
if (old_ms) {
/* Get them before calling set_ms() */
dl_tbf = old_ms->dl_tbf();
ul_tbf = old_ms->ul_tbf();
set_ms(old_ms);
}
update_tlli(new_tlli);
update_ms(new_tlli);
LOGP(DRLCMACUL, LOGL_INFO, "Decoded premier TLLI=0x%08x of "
"UL DATA TFI=%d.\n", tlli(), rh->tfi);
if ((dl_tbf = bts->dl_tbf_by_tlli(tlli()))) {
if (dl_tbf) {
LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from "
"TLLI=0x%08x while %s still exists. "
"Killing pending DL TBF\n", tlli(),
@ -870,9 +888,7 @@ int gprs_rlcmac_tbf::extract_tlli(const uint8_t *data, const size_t len)
tbf_free(dl_tbf);
dl_tbf = NULL;
}
/* ul_tbf_by_tlli will not find your TLLI, because it is not
* yet marked valid */
if ((ul_tbf = bts->ul_tbf_by_tlli(tlli()))) {
if (ul_tbf) {
LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from "
"TLLI=0x%08x while %s still exists. "
"Killing pending UL TBF\n", tlli(),

View File

@ -137,8 +137,11 @@ int gprs_rlcmac_dl_tbf::append_data(const uint8_t ms_class,
static struct gprs_rlcmac_dl_tbf *tbf_lookup_dl(BTS *bts,
const uint32_t tlli, const char *imsi)
{
/* TODO: look up by IMSI first, then tlli, then old_tlli */
return bts->dl_tbf_by_tlli(tlli);
GprsMs *ms = bts->ms_store().get_ms(tlli, 0, imsi);
if (!ms)
return NULL;
return ms->dl_tbf();
}
static int tbf_new_dl_assignment(struct gprs_rlcmac_bts *bts,
@ -148,15 +151,19 @@ static int tbf_new_dl_assignment(struct gprs_rlcmac_bts *bts,
{
uint8_t trx, ta, ss;
int8_t use_trx;
struct gprs_rlcmac_ul_tbf *ul_tbf, *old_ul_tbf;
struct gprs_rlcmac_ul_tbf *ul_tbf = NULL, *old_ul_tbf;
struct gprs_rlcmac_dl_tbf *dl_tbf = NULL;
int8_t tfi; /* must be signed */
int rc;
GprsMs *ms;
/* check for uplink data, so we copy our informations */
#warning "Do the same look up for IMSI, TLLI and OLD_TLLI"
#warning "Refactor the below lines... into a new method"
ul_tbf = bts->bts->ul_tbf_by_tlli(tlli);
ms = bts->bts->ms_store().get_ms(tlli, 0, imsi);
if (ms)
ul_tbf = ms->ul_tbf();
if (ul_tbf && ul_tbf->m_contention_resolution_done
&& !ul_tbf->m_final_ack_sent) {
use_trx = ul_tbf->trx->trx_no;

View File

@ -190,6 +190,7 @@ static void test_alloc_b(int ms_class)
dl_tbf = tbf_alloc_dl_tbf(bts, NULL, tfi, trx_no, ms_class, 1);
dl_tbf->m_tlli = 0x23;
dl_tbf->m_tlli_valid = true;
dl_tbf->update_ms(dl_tbf->m_tlli);
OSMO_ASSERT(dl_tbf);
dump_assignment(dl_tbf, "DL");
@ -198,6 +199,7 @@ static void test_alloc_b(int ms_class)
ul_tbf = tbf_alloc_ul_tbf(bts, dl_tbf, tfi, trx_no, ms_class, 0);
ul_tbf->m_tlli = 0x23;
ul_tbf->m_tlli_valid = true;
ul_tbf->update_ms(ul_tbf->m_tlli);
ul_tbf->m_contention_resolution_done = 1;
OSMO_ASSERT(ul_tbf);
dump_assignment(ul_tbf, "UL");
@ -348,6 +350,7 @@ static void test_alloc_b(bool ts0, bool ts1, bool ts2, bool ts3, bool ts4, bool
OSMO_ASSERT(dl_tbf);
dl_tbf->m_tlli = 0x23;
dl_tbf->m_tlli_valid = true;
dl_tbf->update_ms(dl_tbf->m_tlli);
tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
OSMO_ASSERT(tfi >= 0);
@ -355,6 +358,7 @@ static void test_alloc_b(bool ts0, bool ts1, bool ts2, bool ts3, bool ts4, bool
OSMO_ASSERT(ul_tbf);
ul_tbf->m_tlli = 0x23;
ul_tbf->m_tlli_valid = true;
ul_tbf->update_ms(ul_tbf->m_tlli);
ul_tbf->m_contention_resolution_done = 1;
OSMO_ASSERT(dl_tbf->first_common_ts == ul_tbf->first_common_ts);